[rhq] Branch 'bundle' - modules/core modules/enterprise
by Jay Shaughnessy
modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleDeployDefinition.java | 9
modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleDeployment.java | 4
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java | 34 ++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java | 14
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java | 159 ++++++++--
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/test/ResourceManagerBeanTest.java | 2
6 files changed, 191 insertions(+), 31 deletions(-)
New commits:
commit b6c0527369e344c9479287e00c070d3cd4cc0f28
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Thu Mar 4 15:30:52 2010 -0500
added:
deployBundle
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleDeployDefinition.java b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleDeployDefinition.java
index 7c88e96..5c11287 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleDeployDefinition.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleDeployDefinition.java
@@ -203,6 +203,15 @@ public class BundleDeployDefinition implements Serializable {
return deployments;
}
+ public void addDeployment(BundleDeployment bundleDeployment) {
+ this.deployments.add(bundleDeployment);
+ bundleDeployment.setBundleDeployDefinition(this);
+ }
+
+ public void setDeployments(List<BundleDeployment> deployments) {
+ this.deployments = deployments;
+ }
+
@Override
public String toString() {
return "BundleDeployDefinition[id=" + id + ", name=" + name + "]";
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleDeployment.java b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleDeployment.java
index 8132fa6..588bda6 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleDeployment.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleDeployment.java
@@ -119,6 +119,10 @@ public class BundleDeployment implements Serializable {
this.ctime = System.currentTimeMillis();
}
+ public void setBundleDeployDefinition(BundleDeployDefinition bundleDeployDefinition) {
+ this.bundleDeployDefinition = bundleDeployDefinition;
+ }
+
public List<BundleDeploymentHistory> getBundleDeploymentHistories() {
return histories;
}
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 c9a3261..b04efa0 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
@@ -20,6 +20,7 @@ package org.rhq.enterprise.server.bundle;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
@@ -55,6 +56,7 @@ import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleDeployDefinitionCriteria;
import org.rhq.core.domain.criteria.BundleDeploymentCriteria;
import org.rhq.core.domain.criteria.BundleVersionCriteria;
+import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.domain.util.PersistenceUtility;
@@ -327,6 +329,38 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
@RequiredPermission(Permission.MANAGE_INVENTORY)
+ public List<BundleDeployment> deployBundle(Subject subject, int bundleDeployDefinitionId, int[] resourceIds)
+ throws Exception {
+
+ if (null == resourceIds || 0 == resourceIds.length) {
+ throw new IllegalArgumentException("Invalid resourceIds: " + resourceIds);
+ }
+
+ BundleDeployDefinition deployDef = entityManager.find(BundleDeployDefinition.class, bundleDeployDefinitionId);
+ if (null == deployDef) {
+ throw new IllegalArgumentException("Invalid bundleDeployDefinitionId: " + bundleDeployDefinitionId);
+ }
+ Resource[] resources = new Resource[resourceIds.length];
+ for (int i = 0; (i < resourceIds.length); ++i) {
+ resources[i] = (Resource) entityManager.find(Resource.class, resourceIds[i]);
+ if (null == resources[i]) {
+ throw new IllegalArgumentException("Invalid resourceId (Resource does not exist): " + resources[i]);
+ }
+ }
+
+ List<BundleDeployment> result = new ArrayList<BundleDeployment>(resourceIds.length);
+ // create a BundleDeploy record for each deployment
+ for (Resource resource : resources) {
+ BundleDeployment deployment = new BundleDeployment(deployDef, resource);
+ deployDef.addDeployment(deployment);
+ result.add(deployment);
+ entityManager.persist(deployment);
+ }
+
+ return result;
+ }
+
+ @RequiredPermission(Permission.MANAGE_INVENTORY)
public Set<String> getBundleVersionFilenames(Subject subject, int bundleVersionId, boolean withoutBundleFileOnly)
throws Exception {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
index 22880be..11ca2bd 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
@@ -148,6 +148,20 @@ public interface BundleManagerLocal {
Set<String> getBundleVersionFilenames(Subject subject, int bundleVersionId, boolean withoutBundleFileOnly)
throws Exception;
+ /**
+ * Immediately deploy the bundle as described in the provided deploy definition to the specified resources.
+ * Deployment is asynchronous so return of this method does not indicate deployments are complete. The
+ * returned BundleDeployments can be used to track the history of the deployment.
+ *
+ * @param subject must be InventoryManager
+ * @param bundleDeployDefinitionId the BundleDeployDefinition being used to guide the deployments
+ * @param resourceIds the target resources (must exist), typically platforms, for the deployments
+ * @return a List of BundleDeployments, one for each requested resource.
+ * @throws Exception
+ */
+ List<BundleDeployment> deployBundle(Subject subject, int bundleDeployDefinitionId, int[] resourceIds)
+ throws Exception;
+
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
// The remaining methods are shared with the Remote Interface.
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
index 45e946f..a860e42 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
@@ -35,6 +35,7 @@ import org.testng.annotations.Test;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
+import org.rhq.core.domain.bundle.BundleDeployment;
import org.rhq.core.domain.bundle.BundleFile;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
@@ -46,10 +47,13 @@ import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.content.Repo;
import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleVersionCriteria;
+import org.rhq.core.domain.resource.InventoryStatus;
+import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainer;
+import org.rhq.enterprise.server.resource.ResourceManagerLocal;
import org.rhq.enterprise.server.test.AbstractEJB3Test;
import org.rhq.enterprise.server.util.LookupUtil;
@@ -65,26 +69,28 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
private static final String TEST_PREFIX = "bundletest";
private BundleManagerLocal bundleManager;
-
+ private ResourceManagerLocal resourceManager;
private TestBundleServerPluginService ps;
private MasterServerPluginContainer pc;
+ private Subject overlord;
@BeforeMethod
- public void beforeMethod() {
- // try and clean up any junk that may be lying around from a failed run
- cleanupDatabase();
+ public void beforeMethod() throws Exception {
this.ps = new TestBundleServerPluginService();
prepareCustomServerPluginService(this.ps);
bundleManager = LookupUtil.getBundleManager();
+ resourceManager = LookupUtil.getResourceManager();
+ overlord = LookupUtil.getSubjectManager().getOverlord();
this.ps.startMasterPluginContainer();
+
+ // try and clean up any junk that may be lying around from a failed run
+ cleanupDatabase();
}
@AfterMethod(alwaysRun = true)
public void afterMethod() throws Exception {
-
cleanupDatabase();
-
unprepareServerPluginService();
this.ps = null;
}
@@ -102,17 +108,26 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
// clean up any tests that don't already clean up after themselves
// remove bundleversions which cascade remove bundlefiles and bundledeploydefs
+ // removal of bundledeploydefs cascade remove bundledeployments
q = em.createQuery("SELECT bv FROM BundleVersion bv WHERE bv.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
for (Object removeMe : doomed) {
em.remove(em.getReference(BundleVersion.class, ((BundleVersion) removeMe).getId()));
}
+ em.flush();
// remove any orphaned bfs
q = em.createQuery("SELECT bf FROM BundleFile bf WHERE bf.generalPackage.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
for (Object removeMe : doomed) {
em.remove(em.getReference(BundleFile.class, ((BundleFile) removeMe).getId()));
}
+ // remove any orphaned bds
+ q = em.createQuery("SELECT bd FROM BundleDeployment bd WHERE bd.bundleDeployDefinition.name LIKE '"
+ + TEST_PREFIX + "%'");
+ doomed = q.getResultList();
+ for (Object removeMe : doomed) {
+ em.remove(em.getReference(BundleDeployment.class, ((BundleDeployment) removeMe).getId()));
+ }
// remove any orphaned bdds
q = em.createQuery("SELECT bdd FROM BundleDeployDefinition bdd WHERE bdd.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
@@ -125,6 +140,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
for (Object removeMe : doomed) {
em.remove(em.getReference(Package.class, ((Package) removeMe).getId()));
}
+ em.flush();
// remove any orphaned pvs
q = em.createQuery("SELECT pv FROM PackageVersion pv WHERE pv.generalPackage.name LIKE '" + TEST_PREFIX
+ "%'");
@@ -138,6 +154,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
for (Object removeMe : doomed) {
em.remove(em.getReference(Bundle.class, ((Bundle) removeMe).getId()));
}
+ em.flush();
// remove any orphaned repos
q = em.createQuery("SELECT r FROM Repo r WHERE r.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
@@ -150,6 +167,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
for (Object removeMe : doomed) {
em.remove(em.getReference(ResourceType.class, ((ResourceType) removeMe).getId()));
}
+ em.flush();
// remove any orphaned BundleTypes
q = em.createQuery("SELECT bt FROM BundleType bt WHERE bt.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
@@ -183,7 +201,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
public void testGetBundleTypes() throws Exception {
BundleType bt1 = createBundleType("one");
BundleType bt2 = createBundleType("two");
- List<BundleType> bts = bundleManager.getAllBundleTypes(LookupUtil.getSubjectManager().getOverlord());
+ List<BundleType> bts = bundleManager.getAllBundleTypes(overlord);
assert bts.size() >= 2 : "should have at least 2 bundle types";
List<String> btNames = new ArrayList<String>();
@@ -219,10 +237,10 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
assertNotNull(b1);
BundleVersion bv1 = createBundleVersion(b1.getName(), "1.0", b1);
assertNotNull(bv1);
- BundleFile bf1 = bundleManager.addBundleFileViaByteArray(getOverlord(), bv1.getId(), TEST_PREFIX
- + "-bundlefile-1", "1.0", null, "Test Bundle File # 1".getBytes(), false);
- BundleFile bf2 = bundleManager.addBundleFileViaByteArray(getOverlord(), bv1.getId(), TEST_PREFIX
- + "-bundlefile-2", "1.0", null, "Test Bundle File # 2".getBytes(), false);
+ BundleFile bf1 = bundleManager.addBundleFileViaByteArray(overlord, bv1.getId(), TEST_PREFIX + "-bundlefile-1",
+ "1.0", null, "Test Bundle File # 1".getBytes(), false);
+ BundleFile bf2 = bundleManager.addBundleFileViaByteArray(overlord, bv1.getId(), TEST_PREFIX + "-bundlefile-2",
+ "1.0", null, "Test Bundle File # 2".getBytes(), false);
}
@Test(enabled = TESTS_ENABLED)
@@ -237,7 +255,6 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
bdd1 = createDeployDefinition("one", bv1, config);
fail("Bad config was accepted");
} catch (Exception e) {
- System.out.println("EXPECTED EXCEPTION: " + e);
// expected due to bad config
}
config.put(new PropertySimple("bundletest.property", "bundletest.property value"));
@@ -246,22 +263,41 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
}
@Test(enabled = TESTS_ENABLED)
+ public void testDeployBundle() throws Exception {
+ Bundle b1 = createBundle("one");
+ assertNotNull(b1);
+ BundleVersion bv1 = createBundleVersion(b1.getName() + "-1", null, b1);
+ assertNotNull(bv1);
+ Configuration config = new Configuration();
+ config.put(new PropertySimple("bundletest.property", "bundletest.property value"));
+ BundleDeployDefinition bdd1 = createDeployDefinition("one", bv1, config);
+ assertNotNull(bdd1);
+ Resource platformResource = createTestResource();
+ List<BundleDeployment> bds = bundleManager.deployBundle(overlord, bdd1.getId(), new int[] { platformResource
+ .getId() });
+ assertNotNull(bds);
+ assertEquals(1, bds.size());
+ assertEquals(bdd1.getId(), bds.get(0).getBundleDeployDefinition().getId());
+ assertEquals(platformResource.getId(), bds.get(0).getResource().getId());
+ }
+
+ @Test(enabled = TESTS_ENABLED)
public void testGetBundleFilenames() throws Exception {
Bundle b1 = createBundle("one");
assertNotNull(b1);
BundleVersion bv1 = createBundleVersion(b1.getName(), "1.0", b1);
assertNotNull(bv1);
- Set<String> filenames = bundleManager.getBundleVersionFilenames(getOverlord(), bv1.getId(), true);
+ Set<String> filenames = bundleManager.getBundleVersionFilenames(overlord, bv1.getId(), true);
assertNotNull(filenames);
assertEquals(2, filenames.size());
- BundleFile bf1 = bundleManager.addBundleFileViaByteArray(getOverlord(), bv1.getId(), TEST_PREFIX
- + "-bundlefile-1", "1.0", null, "Test Bundle File # 1".getBytes(), false);
- filenames = bundleManager.getBundleVersionFilenames(getOverlord(), bv1.getId(), true);
+ BundleFile bf1 = bundleManager.addBundleFileViaByteArray(overlord, bv1.getId(), TEST_PREFIX + "-bundlefile-1",
+ "1.0", null, "Test Bundle File # 1".getBytes(), false);
+ filenames = bundleManager.getBundleVersionFilenames(overlord, bv1.getId(), true);
assertNotNull(filenames);
assertEquals(1, filenames.size());
- BundleFile bf2 = bundleManager.addBundleFileViaByteArray(getOverlord(), bv1.getId(), TEST_PREFIX
- + "-bundlefile-2", "1.0", null, "Test Bundle File # 2".getBytes(), false);
- filenames = bundleManager.getBundleVersionFilenames(getOverlord(), bv1.getId(), true);
+ BundleFile bf2 = bundleManager.addBundleFileViaByteArray(overlord, bv1.getId(), TEST_PREFIX + "-bundlefile-2",
+ "1.0", null, "Test Bundle File # 2".getBytes(), false);
+ filenames = bundleManager.getBundleVersionFilenames(overlord, bv1.getId(), true);
assertNotNull(filenames);
assertEquals(0, filenames.size());
}
@@ -278,7 +314,8 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
String name = null;
// return all with no optional data
- bundles = bundleManager.findBundlesByCriteria(getOverlord(), c);
+ c.addFilterName(TEST_PREFIX);
+ bundles = bundleManager.findBundlesByCriteria(overlord, c);
assertNotNull(bundles);
assertEquals(2, bundles.size());
b = bundles.get(0);
@@ -287,7 +324,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
assertTrue(b.getBundleType().getName(), b.getName().contains(name));
assertTrue(b.getBundleType().getName(), b.getBundleType().getName().contains(name));
try {
- assertTrue(b.getBundleVersions().isEmpty());
+ b.getBundleVersions().isEmpty();
fail("Should have thrown LazyInitializationException");
} catch (LazyInitializationException e) {
// expected
@@ -307,7 +344,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
c.addFilterBundleTypeName(b.getName());
c.fetchBundleVersions(true);
c.fetchRepo(true);
- bundles = bundleManager.findBundlesByCriteria(getOverlord(), c);
+ bundles = bundleManager.findBundlesByCriteria(overlord, c);
assertNotNull(bundles);
assertEquals(1, bundles.size());
b = bundles.get(0);
@@ -334,7 +371,8 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
BundleVersion bv = null;
// return all with no optional data
- bvs = bundleManager.findBundleVersionsByCriteria(getOverlord(), c);
+ c.addFilterName(TEST_PREFIX);
+ bvs = bundleManager.findBundleVersionsByCriteria(overlord, c);
bv = bvs.get(1);
assertNotNull(bvs);
assertEquals(3, bvs.size());
@@ -348,7 +386,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
c.fetchBundle(true);
c.fetchDistribution(true);
c.fetchBundleDeployDefinitions(true);
- bvs = bundleManager.findBundleVersionsByCriteria(getOverlord(), c);
+ bvs = bundleManager.findBundleVersionsByCriteria(overlord, c);
assertNotNull(bvs);
assertEquals(1, bvs.size());
bv = bvs.get(0);
@@ -363,7 +401,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
final String fullName = TEST_PREFIX + "-type-" + name;
ResourceType rt = createResourceType(name);
PackageType pt = createPackageType(name, rt);
- BundleType bt = bundleManager.createBundleType(getOverlord(), fullName, rt.getId());
+ BundleType bt = bundleManager.createBundleType(overlord, fullName, rt.getId());
assert bt.getId() > 0;
assert bt.getName().endsWith(fullName);
@@ -377,7 +415,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
private Bundle createBundle(String name, BundleType bt) throws Exception {
final String fullName = TEST_PREFIX + "-bundle-" + name;
- Bundle b = bundleManager.createBundle(getOverlord(), fullName, bt.getId());
+ Bundle b = bundleManager.createBundle(overlord, fullName, bt.getId());
assert b.getId() > 0;
assert b.getName().endsWith(fullName);
@@ -387,7 +425,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
private BundleVersion createBundleVersion(String name, String version, Bundle bundle) throws Exception {
final String fullName = TEST_PREFIX + "-bundleversion-" + version + "-" + name;
final String recipe = "deploy -f " + TEST_PREFIX + ".zip -d <% test.path %>";
- BundleVersion bv = bundleManager.createBundleVersion(getOverlord(), bundle.getId(), fullName, version, recipe);
+ BundleVersion bv = bundleManager.createBundleVersion(overlord, bundle.getId(), fullName, version, recipe);
assert bv.getId() > 0;
assert bv.getName().endsWith(fullName);
@@ -397,7 +435,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
private BundleDeployDefinition createDeployDefinition(String name, BundleVersion bv, Configuration config)
throws Exception {
final String fullName = TEST_PREFIX + "-bundledeploydef-" + name;
- BundleDeployDefinition bdd = bundleManager.createBundleDeployDefinition(getOverlord(), bv.getId(), fullName,
+ BundleDeployDefinition bdd = bundleManager.createBundleDeployDefinition(overlord, bv.getId(), fullName,
fullName, config, false, -1, false);
assert bdd.getId() > 0;
@@ -432,7 +470,68 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
return pt;
}
- private Subject getOverlord() {
- return LookupUtil.getSubjectManager().getOverlord();
+ // lifted from ResourceManagerBeanTest
+ private Resource createTestResource() throws Exception {
+ getTransactionManager().begin();
+ EntityManager em = getEntityManager();
+
+ Resource resource = null;
+
+ try {
+ // Naming this with TEST_PREFIX allows cleanupDatabase to blow away these test resources along
+ // with the bundle resource type
+ ResourceType resourceType = new ResourceType(TEST_PREFIX + "-platform-" + System.currentTimeMillis(),
+ "test", ResourceCategory.PLATFORM, null);
+
+ em.persist(resourceType);
+ em.flush();
+
+ resource = new Resource("reskey" + System.currentTimeMillis(), TEST_PREFIX + "-resname", resourceType);
+ resource.setInventoryStatus(InventoryStatus.COMMITTED);
+ em.persist(resource);
+
+ getTransactionManager().commit();
+ } catch (Exception e) {
+ try {
+ System.out.println("CANNOT PREPARE TEST: Cause: " + e);
+ getTransactionManager().rollback();
+ } catch (Exception ignore) {
+ //
+ }
+ } finally {
+ em.close();
+ }
+
+ return resource;
+ }
+
+ // lifted from ResourceManagerBeanTest
+ private void deleteTestResource(Resource resource) throws Exception {
+ if (resource != null) {
+ getTransactionManager().begin();
+ EntityManager em = getEntityManager();
+ try {
+ ResourceType type = em.find(ResourceType.class, resource.getResourceType().getId());
+ Resource res = em.find(Resource.class, resource.getId());
+
+ List<Integer> deletedIds = resourceManager.deleteResource(overlord, res.getId());
+ for (Integer deletedResourceId : deletedIds) {
+ resourceManager.deleteSingleResourceInNewTransaction(overlord, deletedResourceId);
+ }
+ em.remove(type);
+
+ getTransactionManager().commit();
+ } catch (Exception e) {
+ try {
+ System.out.println("CANNOT CLEAN UP TEST: Cause: " + e);
+ getTransactionManager().rollback();
+ } catch (Exception ignore) {
+ //
+ }
+ } finally {
+ em.close();
+ }
+ }
}
+
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/test/ResourceManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/test/ResourceManagerBeanTest.java
index bafdd5c..f4a49d0 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/test/ResourceManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/resource/test/ResourceManagerBeanTest.java
@@ -162,7 +162,7 @@ public class ResourceManagerBeanTest extends UpdateSubsytemTestBase {
try {
ResourceType type = em.find(ResourceType.class, resource.getResourceType().getId());
Resource res = em.find(Resource.class, resource.getId());
- Agent agent = em.find(Agent.class, resource.getAgent().getId());
+ Agent agent = em.find(Agent.class, res.getAgent().getId());
List<Integer> deletedIds = resourceManager.deleteResource(superuser, res.getId());
for (Integer deletedResourceId : deletedIds) {
14 years, 3 months
[rhq] Branch 'raw-config' - modules/enterprise
by John Sanda
modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/layout/main.xhtml | 3 +++
1 file changed, 3 insertions(+)
New commits:
commit 55aab5147bb010e08a8e6912b958a4910e0975bb
Author: John Sanda <john(a)localhost.localdomain>
Date: Thu Mar 4 12:23:37 2010 -0500
Wrapping the global <h:messages> in an <a4j:outputPanel> so messages are rendered on ajax requests
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/layout/main.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/layout/main.xhtml
index cc86bc9..e67b0f9 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/layout/main.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/layout/main.xhtml
@@ -87,11 +87,14 @@ REQUEST PARAMETERS:
</onc:tabBar>
+ <!-- Wrapping the global messages in an a4j outputPanel so that messages are rendered on ajax requests -->
+ <a4j:outputPanel ajaxRendered="true">
<!-- Shows the results of the last action executed. -->
<h:messages showSummary="true" showDetail="true"
infoClass="InfoBlock" warnClass="WarnBlock"
errorClass="ErrorBlock" fatalClass="FatalBlock"
globalOnly="true" layout="table" width="100%" />
+ </a4j:outputPanel>
</ui:define>
14 years, 3 months
[rhq] Branch 'raw-config' - modules/plugins
by John Sanda
modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawServer.groovy | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
New commits:
commit 2ad0d9eb12d46c347349ac356be921a87a0542a6
Author: John Sanda <john(a)localhost.localdomain>
Date: Thu Mar 4 11:58:32 2010 -0500
Making error messages more consistent
diff --git a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawServer.groovy b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawServer.groovy
index 97f3622..1005e9c 100644
--- a/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawServer.groovy
+++ b/modules/plugins/raw-config-test/src/main/groovy/org/rhq/plugins/test/rawconfig/StructuredAndRawServer.groovy
@@ -160,7 +160,7 @@ class StructuredAndRawServer extends ConfigurationServer implements ResourceComp
def match = fileNames.find { rawConfig.path.endsWith(it) }
if (match) {
- throw new RuntimeException("Validation failed for ${rawConfig.path}");
+ throw new RuntimeException("Raw validation failed for ${rawConfig.path}");
}
}
}
@@ -168,14 +168,14 @@ class StructuredAndRawServer extends ConfigurationServer implements ResourceComp
void validateStructuredConfiguration(Configuration config) {
def failValidation = resourceContext.pluginConfiguration.getSimple("failStructuredValidation")
if (failValidation != null && failValidation.booleanValue) {
- throw new RuntimeException("Structured validation failed for Structured and Raw Server");
+ throw new RuntimeException("Structured validation failed");
}
}
void persistStructuredConfiguration(Configuration config) {
def failValidation = resourceContext.pluginConfiguration.getSimple("failStructuredUpdate")
if (failValidation != null && failValidation.booleanValue) {
- throw new RuntimeException("Structured pdate failed for Structured and Raw Server");
+ throw new RuntimeException("Structured update failed");
}
pauseForStructuredUpdateIfDelaySet()
@@ -188,7 +188,7 @@ class StructuredAndRawServer extends ConfigurationServer implements ResourceComp
def match = fileNames.find { rawConfiguration.path.endsWith(it) }
if (match) {
- throw new RuntimeException("Update failed for ${rawConfiguration.path}");
+ throw new RuntimeException("Raw update failed for ${rawConfiguration.path}");
}
}
14 years, 3 months
[rhq] modules/core
by John Sanda
modules/core/plugin-container/pom.xml | 7
modules/core/plugin-container/src/test/java/org/rhq/core/pc/plugin/PluginManagerTest.java | 217 ++--------
modules/core/plugin-container/src/test/resources/org/rhq/core/pc/plugin/plugin-A.jar |binary
modules/core/plugin-container/src/test/resources/org/rhq/core/pc/plugin/plugin-B-depends-on-A.jar |binary
modules/core/plugin-container/src/test/resources/org/rhq/core/pc/plugin/plugin-C-depends-on-B.jar |binary
5 files changed, 71 insertions(+), 153 deletions(-)
New commits:
commit 3b99cb5400e78a387a750491f05c24f13ceac7ca
Author: John Sanda <john(a)localhost.localdomain>
Date: Thu Mar 4 11:34:16 2010 -0500
Fixing brittle tests in PluginManagerTest so that it no longer relies on plugin jars in the local maven repo
diff --git a/modules/core/plugin-container/pom.xml b/modules/core/plugin-container/pom.xml
index f950282..32abd55 100644
--- a/modules/core/plugin-container/pom.xml
+++ b/modules/core/plugin-container/pom.xml
@@ -101,6 +101,13 @@
<version>${version}</version>
<scope>test</scope>
</dependency>
+
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>1.4</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/plugin/PluginManagerTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/plugin/PluginManagerTest.java
index a315276..4a72afb 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/plugin/PluginManagerTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/plugin/PluginManagerTest.java
@@ -23,76 +23,65 @@
package org.rhq.core.pc.plugin;
-import static org.testng.Assert.*;
-
-import org.testng.annotations.Test;
-import org.testng.annotations.BeforeClass;
-import org.rhq.core.pc.PluginContainerConfiguration;
-import org.rhq.core.clientapi.descriptor.plugin.PluginDescriptor;
-import org.rhq.core.clientapi.descriptor.AgentPluginDescriptorUtil;
+import org.apache.commons.io.FileUtils;
import org.rhq.core.clientapi.agent.PluginContainerException;
-import org.rhq.core.pluginapi.plugin.PluginLifecycleListener;
+import org.rhq.core.clientapi.descriptor.AgentPluginDescriptorUtil;
+import org.rhq.core.clientapi.descriptor.plugin.PluginDescriptor;
+import org.rhq.core.pc.PluginContainerConfiguration;
import org.rhq.core.pluginapi.plugin.PluginContext;
-import org.rhq.core.domain.plugin.Plugin;
+import org.rhq.core.pluginapi.plugin.PluginLifecycleListener;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import java.io.File;
import java.net.URL;
-import java.net.MalformedURLException;
-import java.util.Collection;
-import java.util.List;
import java.util.ArrayList;
-import java.util.Map;
+import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
-import java.io.File;
-
-public class PluginManagerTest {
-
- static final String VERSION = System.getProperty("rhq.version");
- static final String PLATFORM_PLUGIN = "org/rhq/rhq-platform-plugin/" + VERSION + "/rhq-platform-plugin-" + VERSION + ".jar";
+import java.util.List;
+import java.util.Map;
- static final String HOSTS_PLUGIN = "org/rhq/rhq-hosts-plugin/" + VERSION + "/rhq-hosts-plugin-" + VERSION + ".jar";
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
- static final String AUGEAS_PLUGIN = "org/rhq/rhq-augeas-plugin/" + VERSION + "/rhq-augeas-plugin-" + VERSION + ".jar";
+public class PluginManagerTest {
- static final String JMX_PLUGIN = "org/rhq/rhq-jmx-plugin/" + VERSION + "/rhq-jmx-plugin-" + VERSION + ".jar";
+ static final String PLUGIN_A = "plugin-A.jar";
- String m2RepoDir;
+ static final String PLUGIN_B = "plugin-B-depends-on-A.jar";
- PluginDescriptor platformDescriptor;
+ static final String PLUGIN_C = "plugin-C-depends-on-B.jar";
- PluginDescriptor hostsDescriptor;
+ PluginDescriptor descriptorA;
- PluginDescriptor augeasDescriptor;
+ PluginDescriptor descriptorB;
- PluginDescriptor jmxDescriptor;
+ PluginDescriptor descriptorC;
@BeforeClass
public void initClass() throws Exception {
- setM2RepoDir();
verifyPluginsExist();
initPluginDescriptors();
}
- void setM2RepoDir() {
- String userHomeDir = System.getProperty("user.home");
- m2RepoDir = System.getProperty("m2.repo", userHomeDir + "/.m2/repository");
- }
-
void verifyPluginsExist() {
- assertPluginJarFileExists(PLATFORM_PLUGIN);
- assertPluginJarFileExists(HOSTS_PLUGIN);
- assertPluginJarFileExists(AUGEAS_PLUGIN);
+ assertPluginJarFileExists(PLUGIN_A);
+ assertPluginJarFileExists(PLUGIN_B);
+ assertPluginJarFileExists(PLUGIN_C);
}
void initPluginDescriptors() throws Exception {
- platformDescriptor = loadPluginDescriptor(getPlatformPluginURL());
- augeasDescriptor = loadPluginDescriptor(getAugeasPluginURL());
- hostsDescriptor = loadPluginDescriptor(getHostsPluginURL());
- jmxDescriptor = loadPluginDescriptor(getJMXPluginURL());
+ descriptorA = loadPluginDescriptor(getClass().getResource(PLUGIN_A));
+ descriptorB = loadPluginDescriptor(getClass().getResource(PLUGIN_B));
+ descriptorC = loadPluginDescriptor(getClass().getResource(PLUGIN_C));
}
void assertPluginJarFileExists(String pluginPath) {
- File pluginJarFile = new File(m2RepoDir, pluginPath);
+ URL pluginURL = getClass().getResource(pluginPath);
+ File pluginJarFile = FileUtils.toFile(pluginURL);
+
assertTrue(pluginJarFile.exists(), pluginJarFile.getAbsolutePath() + " does not exist and is needed for " +
"tests in " + PluginManagerTest.class.getName());
}
@@ -138,66 +127,14 @@ public class PluginManagerTest {
verifyPluginsShutdownInCorrectOrder(pluginLifecycleListenerMgr);
}
- @Test
- public void pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEmbeddedMode() throws Exception {
- PluginContainerConfiguration configuration = new PluginContainerConfiguration();
- configuration.setPluginFinder(new PluginFinder() {
- public Collection<URL> findPlugins() {
- List<URL> pluginURLs = new ArrayList<URL>();
- pluginURLs.add(getJMXPluginURL());
-
- return pluginURLs;
- }
- });
-
- PluginManager pluginMgr = new PluginManager();
- pluginMgr.setConfiguration(configuration);
- pluginMgr.initialize();
-
- String expectedAmpsVersion = jmxDescriptor.getAmpsVersion();
- String actualAmpsVersion = pluginMgr.getAmpsVersion(jmxDescriptor.getName());
-
- assertEquals(actualAmpsVersion, expectedAmpsVersion, "Failed to find ampsVersion in embedded mode for '" +
- jmxDescriptor.getName() + "' plugin");
- }
-
-// @Test
-// public void pluginManagerShouldReturnAmpsVersionOfLoadedPluginWhenInEnterpriseMode() throws Exception {
-// Plugin plugin = new Plugin();
-// plugin.setName(jmxDescriptor.getName());
-// plugin.setAmpsVersion("2.1");
-//
-// PluginContainerConfiguration configuration = new PluginContainerConfiguration();
-// configuration.setInsideAgent(true);
-// configuration.getPluginsOnServer().add(plugin);
-// configuration.setPluginFinder(new PluginFinder() {
-// public Collection<URL> findPlugins() {
-// List<URL> pluginURLs = new ArrayList<URL>();
-// pluginURLs.add(getJMXPluginURL());
-//
-// return pluginURLs;
-// }
-// });
-//
-// PluginManager pluginMgr = new PluginManager();
-// pluginMgr.setConfiguration(configuration);
-// pluginMgr.initialize();
-//
-// String expectedAmpsVersion = plugin.getAmpsVersion();
-// String actualAmpsVersion = pluginMgr.getAmpsVersion(jmxDescriptor.getName());
-//
-// assertEquals(actualAmpsVersion, expectedAmpsVersion, "Failed to find ampsVersion in embedded mode for '" +
-// jmxDescriptor.getName() + "' plugin");
-// }
-
private PluginContainerConfiguration createConfiguration() {
PluginContainerConfiguration configuration = new PluginContainerConfiguration();
configuration.setPluginFinder(new PluginFinder() {
public Collection<URL> findPlugins() {
List<URL> pluginURLs = new ArrayList<URL>();
- pluginURLs.add(getPlatformPluginURL());
- pluginURLs.add(getHostsPluginURL());
- pluginURLs.add(getAugeasPluginURL());
+ pluginURLs.add(getClass().getResource(PLUGIN_A));
+ pluginURLs.add(getClass().getResource(PLUGIN_B));
+ pluginURLs.add(getClass().getResource(PLUGIN_C));
return pluginURLs;
}
@@ -206,9 +143,9 @@ public class PluginManagerTest {
}
void verifyThatPluginsAreLoaded(PluginManager pluginMgr) throws Exception {
- assertPluginLoaded(platformDescriptor, pluginMgr);
- assertPluginLoaded(hostsDescriptor, pluginMgr);
- assertPluginLoaded(augeasDescriptor, pluginMgr);
+ assertPluginLoaded(descriptorA, pluginMgr);
+ assertPluginLoaded(descriptorB, pluginMgr);
+ assertPluginLoaded(descriptorC, pluginMgr);
}
void assertPluginLoaded(PluginDescriptor pluginDescriptor, PluginManager pluginMgr) throws Exception {
@@ -218,87 +155,57 @@ public class PluginManagerTest {
}
void verifyPluginsLoadedInCorrectOrder(FakePluginLifecycleListenerManager pluginLifecycleListenerMgr) throws Exception {
- assertPlatformPluginLoadedFirst(pluginLifecycleListenerMgr);
- assertAugeasPluginLoadedSecond(pluginLifecycleListenerMgr);
- assertHostsPluginLoadedThird(pluginLifecycleListenerMgr);
+ assertPluginALoadedFirst(pluginLifecycleListenerMgr);
+ assertPluginBLoadedSecond(pluginLifecycleListenerMgr);
+ assertPluginCLoadedThird(pluginLifecycleListenerMgr);
}
- void assertPlatformPluginLoadedFirst(FakePluginLifecycleListenerManager pluginLifecycleListenerMgr) throws Exception {
- int initOrder = pluginLifecycleListenerMgr.lifecycleTracker.getInitializationOrder(platformDescriptor.getName());
+ void assertPluginALoadedFirst(FakePluginLifecycleListenerManager pluginLifecycleListenerMgr) throws Exception {
+ int initOrder = pluginLifecycleListenerMgr.lifecycleTracker.getInitializationOrder(descriptorA.getName());
- assertEquals(initOrder, 0, "Expected " + platformDescriptor.getName() + " to be initialized first.");
+ assertEquals(initOrder, 0, "Expected " + descriptorA.getName() + " to be initialized first.");
}
- void assertAugeasPluginLoadedSecond(FakePluginLifecycleListenerManager pluginLifecycleListenerMgr) throws Exception {
- int initOrder = pluginLifecycleListenerMgr.lifecycleTracker.getInitializationOrder(augeasDescriptor.getName());
+ void assertPluginBLoadedSecond(FakePluginLifecycleListenerManager pluginLifecycleListenerMgr) throws Exception {
+ int initOrder = pluginLifecycleListenerMgr.lifecycleTracker.getInitializationOrder(descriptorB.getName());
- assertEquals(initOrder, 1, "Expected " + augeasDescriptor.getName() + " to be initialized second.");
+ assertEquals(initOrder, 1, "Expected " + descriptorB.getName() + " to be initialized second.");
}
- void assertHostsPluginLoadedThird(FakePluginLifecycleListenerManager pluginLifecycleListenerMgr) throws Exception {
- int initOrder = pluginLifecycleListenerMgr.lifecycleTracker.getInitializationOrder(hostsDescriptor.getName());
+ void assertPluginCLoadedThird(FakePluginLifecycleListenerManager pluginLifecycleListenerMgr) throws Exception {
+ int initOrder = pluginLifecycleListenerMgr.lifecycleTracker.getInitializationOrder(descriptorC.getName());
- assertEquals(initOrder, 2, "Expected " + hostsDescriptor.getName() + " to be initialized third.");
+ assertEquals(initOrder, 2, "Expected " + descriptorC.getName() + " to be initialized third.");
}
void verifyPluginsShutdownInCorrectOrder(FakePluginLifecycleListenerManager pluginLifecycleListenerMgr) throws Exception {
- assertHostsPluginShutdownFirst(pluginLifecycleListenerMgr);
- assertAugeasPluginShutdownSecond(pluginLifecycleListenerMgr);
- assertPlatformPluginShutdownThird(pluginLifecycleListenerMgr);
+ assertPluginCShutdownFirst(pluginLifecycleListenerMgr);
+ assertPluginBShutdownSecond(pluginLifecycleListenerMgr);
+ assertPluginAShutdownThird(pluginLifecycleListenerMgr);
}
- void assertHostsPluginShutdownFirst(FakePluginLifecycleListenerManager pluginLifecycleListenerMgr) throws Exception {
- int shutdownOrder = pluginLifecycleListenerMgr.lifecycleTracker.getShutdownOrder(hostsDescriptor.getName());
+ void assertPluginCShutdownFirst(FakePluginLifecycleListenerManager pluginLifecycleListenerMgr) throws Exception {
+ int shutdownOrder = pluginLifecycleListenerMgr.lifecycleTracker.getShutdownOrder(descriptorC.getName());
- assertEquals(shutdownOrder, 0, "Expected " + hostsDescriptor.getName() + " to be shutdown first.");
+ assertEquals(shutdownOrder, 0, "Expected " + descriptorC.getName() + " to be shutdown first.");
}
- void assertAugeasPluginShutdownSecond(FakePluginLifecycleListenerManager pluginLifecycleListenerMgr) throws Exception {
- int shutdownOrder = pluginLifecycleListenerMgr.lifecycleTracker.getShutdownOrder(augeasDescriptor.getName());
+ void assertPluginBShutdownSecond(FakePluginLifecycleListenerManager pluginLifecycleListenerMgr) throws Exception {
+ int shutdownOrder = pluginLifecycleListenerMgr.lifecycleTracker.getShutdownOrder(descriptorB.getName());
- assertEquals(shutdownOrder, 1, "Expected " + augeasDescriptor.getName() + " to be shutdown second.");
+ assertEquals(shutdownOrder, 1, "Expected " + descriptorB.getName() + " to be shutdown second.");
}
- void assertPlatformPluginShutdownThird(FakePluginLifecycleListenerManager pluginLifecycleListenerMgr) throws Exception {
- int shutdownOrder = pluginLifecycleListenerMgr.lifecycleTracker.getShutdownOrder(platformDescriptor.getName());
+ void assertPluginAShutdownThird(FakePluginLifecycleListenerManager pluginLifecycleListenerMgr) throws Exception {
+ int shutdownOrder = pluginLifecycleListenerMgr.lifecycleTracker.getShutdownOrder(descriptorA.getName());
- assertEquals(shutdownOrder, 2, "Expected " + platformDescriptor.getName() + " to be shutdown third.");
+ assertEquals(shutdownOrder, 2, "Expected " + descriptorA.getName() + " to be shutdown third.");
}
PluginDescriptor loadPluginDescriptor(URL pluginURL) throws PluginContainerException {
return AgentPluginDescriptorUtil.loadPluginDescriptorFromUrl(pluginURL);
}
- String getPluginName(URL pluginURL) throws Exception {
- PluginDescriptor descriptor = loadPluginDescriptor(pluginURL);
- return descriptor.getName();
- }
-
- URL getPlatformPluginURL() {
- return toURL(new File(m2RepoDir, PLATFORM_PLUGIN));
- }
-
- URL getHostsPluginURL() {
- return toURL(new File(m2RepoDir, HOSTS_PLUGIN));
- }
-
- URL getAugeasPluginURL() {
- return toURL(new File(m2RepoDir, AUGEAS_PLUGIN));
- }
-
- URL getJMXPluginURL() {
- return toURL(new File(m2RepoDir, JMX_PLUGIN));
- }
-
- URL toURL(File file) {
- try {
- return file.toURI().toURL();
- }
- catch (MalformedURLException e) {
- throw new RuntimeException(e);
- }
- }
-
static class FakePluginLifecycleListenerManager implements PluginLifecycleListenerManager {
Map<String, PluginLifecycleListener> listeners = new HashMap<String, PluginLifecycleListener>();
@@ -327,6 +234,10 @@ public class PluginManagerTest {
}
}
+ /**
+ * This is helper class that is used to track the order of start up and shutdown for the plugins used by these
+ * tests.
+ */
static class PluginLifecycleTracker {
private List<String> initializedPlugins = new LinkedList<String>();
diff --git a/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/plugin/plugin-A.jar b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/plugin/plugin-A.jar
new file mode 100644
index 0000000..c1537e8
Binary files /dev/null and b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/plugin/plugin-A.jar differ
diff --git a/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/plugin/plugin-B-depends-on-A.jar b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/plugin/plugin-B-depends-on-A.jar
new file mode 100644
index 0000000..7e3e43e
Binary files /dev/null and b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/plugin/plugin-B-depends-on-A.jar differ
diff --git a/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/plugin/plugin-C-depends-on-B.jar b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/plugin/plugin-C-depends-on-B.jar
new file mode 100644
index 0000000..31c6d3b
Binary files /dev/null and b/modules/core/plugin-container/src/test/resources/org/rhq/core/pc/plugin/plugin-C-depends-on-B.jar differ
14 years, 3 months
[rhq] Branch 'gwt' - modules/enterprise
by ips
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceSummaryView.java | 9 ++++-----
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceView.java | 1 +
2 files changed, 5 insertions(+), 5 deletions(-)
New commits:
commit 734e126f592053b08692ef7f508e7ab89f33ddc9
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Thu Mar 4 11:00:24 2010 -0500
display parent resourcetype name in resource summary header
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceSummaryView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceSummaryView.java
index 0cd388a..ed2da2e 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceSummaryView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceSummaryView.java
@@ -32,10 +32,8 @@ import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.FormItem;
-import com.smartgwt.client.widgets.form.fields.SectionItem;
import com.smartgwt.client.widgets.form.fields.SpacerItem;
import com.smartgwt.client.widgets.form.fields.StaticTextItem;
-import com.smartgwt.client.widgets.form.fields.TextItem;
import java.util.ArrayList;
import java.util.Collections;
@@ -83,7 +81,7 @@ public class ResourceSummaryView extends DynamicForm implements ResourceSelectLi
markForRedraw();
}
- private void loadValues() {
+ private void loadValues() {
GWTServiceLookup.getMeasurementDataService().findCurrentTraitsForResource(
resource.getId(),
DisplayType.SUMMARY,
@@ -106,6 +104,7 @@ public class ResourceSummaryView extends DynamicForm implements ResourceSelectLi
}
}
);
+
}
private void buildForm(ResourceType type) {
@@ -176,8 +175,8 @@ public class ResourceSummaryView extends DynamicForm implements ResourceSelectLi
setValue("typeItem", type.getName() + " (" + type.getPlugin() + ")");
setValue("descriptionItem", resource.getDescription());
setValue("versionItem", resource.getVersion());
- setValue("parentItem", resource.getParentResource() == null ? null : (resource.getParentResource().getName() +
- "'<a href=\"#Resource/" + resource.getParentResource().getId()) + "\">" + resource.getParentResource().getName() + "</a>'");
+ setValue("parentItem", resource.getParentResource() == null ? null : (resource.getParentResource().getResourceType().getName() +
+ " '<a href=\"#Resource/" + resource.getParentResource().getId()) + "\">" + resource.getParentResource().getName() + "</a>'");
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceView.java
index 63bcea4..651914f 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceView.java
@@ -94,6 +94,7 @@ public class ResourceView extends HLayout implements ViewRenderer {
} else {
ResourceCriteria criteria = new ResourceCriteria();
criteria.addFilterId(resourceId);
+ criteria.fetchParentResource(true);
resourceService.findResourcesByCriteria(criteria, new AsyncCallback<PageList<Resource>>() {
public void onFailure(Throwable caught) {
SC.say("Failed to load Resource with id " + resourceId + ": " + caught);
14 years, 3 months
[rhq] 8 commits - modules/core modules/enterprise pom.xml
by Heiko W. Rupp
modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml | 4
modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml | 20 +-
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/CustomContentUIBean.java | 6
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/CustomAlertSenderBackingBean.java | 10 +
modules/enterprise/server/plugins/alert-operations/pom.xml | 98 +++++-----
modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/AlertTokenReplacer.java | 8
modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java | 68 +++---
modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java | 41 ++--
modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/Token.java | 4
modules/enterprise/server/plugins/alert-operations/src/main/resources/operations.xhtml | 2
modules/enterprise/server/plugins/alert-operations/src/test/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacementTest.java | 3
pom.xml | 33 +--
12 files changed, 175 insertions(+), 122 deletions(-)
New commits:
commit b9e910bf92e1eed1c3ee8182742d49183ed41147
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Thu Mar 4 12:48:47 2010 +0100
BZ 570453 max varchar2 len on oracle is 4000 bytes.
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 eb2fd2a..00f006d 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml
@@ -99,8 +99,8 @@
<column name="SENDER" required="false" size="200" type="VARCHAR2"/>
<column name="RESULT_STATE" required="false" size="20" type="VARCHAR2"/>
<column name="MESSAGE" required="false" size="255" type="VARCHAR2"/>
- <column name="ALL_EMAILS" required="false" size="4096" type="VARCHAR2"/>
- <column name="EMAILS_FAILED" required="false" size="4096" type="VARCHAR2"/>
+ <column name="ALL_EMAILS" required="false" size="4000" type="VARCHAR2"/>
+ <column name="EMAILS_FAILED" required="false" size="4000" type="VARCHAR2"/>
</table>
<table name="RHQ_ALERT_CONDITION_LOG" tablespace="@@@LARGE_TABLESPACE_FOR_DATA@@@"
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
index 74c6038..f44251b 100644
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@ -3027,8 +3027,8 @@
<schema-addColumn table="RHQ_ALERT_NOTIF_LOG" column="SENDER" columnType="VARCHAR2" precision="200" />
<schema-addColumn table="RHQ_ALERT_NOTIF_LOG" column="RESULT_STATE" columnType="VARCHAR2" precision="20" />
<schema-addColumn table="RHQ_ALERT_NOTIF_LOG" column="MESSAGE" columnType="VARCHAR2" precision="255" />
- <schema-addColumn table="RHQ_ALERT_NOTIF_LOG" column="ALL_EMAILS" columnType="VARCHAR2" precision="4096" />
- <schema-addColumn table="RHQ_ALERT_NOTIF_LOG" column="EMAILS_FAILED" columnType="VARCHAR2" precision="4096" />
+ <schema-addColumn table="RHQ_ALERT_NOTIF_LOG" column="ALL_EMAILS" columnType="VARCHAR2" precision="4000" />
+ <schema-addColumn table="RHQ_ALERT_NOTIF_LOG" column="EMAILS_FAILED" columnType="VARCHAR2" precision="4000" />
</schemaSpec>
<schemaSpec version="2.77.5">
<schema-directSQL>
@@ -3191,9 +3191,9 @@
<schema-addColumn table="RHQ_BUNDLE_DEPLOY_HIST" column="AUDIT_MESSAGE" columnType="LONGVARCHAR" />
<!-- Changes to RHQ_BUNDLE_FILE -->
- <schema-alterColumn table="RHQ_BUNDLE_FILE" column="PACKAGE_VERSION_ID" nullable="FALSE" />
+ <schema-alterColumn table="RHQ_BUNDLE_FILE" column="PACKAGE_VERSION_ID" nullable="FALSE" />
</schemaSpec>
-
+
<schemaSpec version="2.78.1">
<schema-addColumn table="RHQ_BUNDLE" column="REPO_ID" columnType="INTEGER" />
<schema-directSQL>
@@ -3203,9 +3203,9 @@
FOREIGN KEY (REPO_ID)
REFERENCES RHQ_REPO (ID)
</statement>
- </schema-directSQL>
+ </schema-directSQL>
</schemaSpec>
-
+
<schemaSpec version="2.79">
<schema-directSQL>
<statement desc="Normalizing resource group descriptions">
@@ -3213,7 +3213,7 @@
</statement>
</schema-directSQL>
</schemaSpec>
-
+
<schemaSpec version="2.82">
<schema-directSQL>
<statement desc="Creating table RHQ_SAVED_SEARCH">
@@ -3227,17 +3227,17 @@
</schema-directSQL>
<schema-addColumn table="RHQ_SAVED_SEARCH" column="CONTEXT" columnType="VARCHAR2" precision="25" />
<schema-alterColumn table="RHQ_SAVED_SEARCH" column="CONTEXT" nullable="FALSE" />
-
+
<schema-addColumn table="RHQ_SAVED_SEARCH" column="NAME" columnType="VARCHAR2" precision="200" />
<schema-addColumn table="RHQ_SAVED_SEARCH" column="DESCRIPTION" columnType="VARCHAR2" precision="500" />
<schema-addColumn table="RHQ_SAVED_SEARCH" column="PATTERN" columnType="VARCHAR2" precision="1000" />
<schema-alterColumn table="RHQ_SAVED_SEARCH" column="PATTERN" nullable="FALSE" />
-
+
<schema-addColumn table="RHQ_SAVED_SEARCH" column="JPQL_TRANSLATION" columnType="VARCHAR2" precision="4000" />
<schema-addColumn table="RHQ_SAVED_SEARCH" column="LAST_COMPUTE_TIME" columnType="LONG" />
<schema-alterColumn table="RHQ_SAVED_SEARCH" column="LAST_COMPUTE_TIME" nullable="FALSE" />
<schema-addColumn table="RHQ_SAVED_SEARCH" column="RESULT_COUNT" columnType="LONG" />
-
+
<schema-addColumn table="RHQ_SAVED_SEARCH" column="SUBJECT_ID" columnType="INTEGER" />
<schema-alterColumn table="RHQ_SAVED_SEARCH" column="SUBJECT_ID" nullable="FALSE" />
<schema-addColumn table="RHQ_SAVED_SEARCH" column="GLOBAL" columnType="BOOLEAN" />
commit eac81485227312a19991d0e7731b830fb2f2b830
Merge: f93ec8c... d9d5866...
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Thu Mar 4 11:33:49 2010 +0100
Merge branch 'master' into alertPlugin
commit f93ec8ca78fb9c17d031ae85f670286ad6d154df
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Wed Mar 3 21:39:05 2010 +0100
Provide the operation name at the top of the parameters panel.
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java
index c7c8c26..6f39bae 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java
@@ -27,10 +27,8 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.seam.ScopeType;
-import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.Scope;
-import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
@@ -63,25 +61,14 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
private Configuration configuration;
private static final String ALERT_NOTIFICATIONS = "ALERT_NOTIFICATIONS";
+
+
+ private String operationName;
+
public OperationsBackingBean() {
log.info("new " + hashCode());
}
- @Override
- public void internalInit() {
-/* log.info("internalInit");
- try {
- getResId();
- getResourceName();
- obtainOperationIds();
- getOperationId();
- lookupConfiguration();
- }
- catch (Throwable t) {
- t.printStackTrace();
- }*/
- }
-
@Override
public void internalCleanup() {
@@ -107,6 +94,7 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
cleanProperty(alertParameters,OperationsSender.USABLE);
operationIds = new HashMap<String,Integer>(); // Clean out operations dropdown
operationId = null;
+ operationName = null;
}
@@ -122,6 +110,7 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
if (operationId != null ) {
persistProperty(alertParameters, OperationsSender.OPERATION_ID, operationId);
+ getOperationNameFromOperationIds();
lookupConfiguration();
}
@@ -144,8 +133,6 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
// call a SLSB method to get around lazy initialization of configDefs and configTemplates
ConfigurationManagerLocal configurationManager = LookupUtil.getConfigurationManager();
configuration = configurationManager.getConfigurationFromDefaultTemplate(configurationDefinition);
- // Configuration newConfiguration = configuration.deepCopy(false);
- log.info("lookupConfiguration: " + configuration + ", " + configuration.hashCode() );
}
} catch (Exception e) {
e.printStackTrace();
@@ -187,11 +174,9 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
public void setResMode(String resMode) {
this.resMode = resMode;
- log.info("setResMode: " + resMode);
}
public Integer getResId() {
- System.out.println("OperationsBackingBean.getResId");
if (resId==null) {
PropertySimple prop = alertParameters.getSimple(OperationsSender.RESOURCE_ID);
if (prop!=null)
@@ -203,7 +188,6 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
public void setResId(Integer resId) {
this.resId = resId;
- log.info("Set resid " + resId);
if (resId!=null) {
persistProperty(alertParameters,OperationsSender.RESOURCE_ID,resId);
}
@@ -232,15 +216,35 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
PropertySimple prop = alertParameters.getSimple(OperationsSender.OPERATION_ID);
if (prop!=null)
operationId = prop.getIntegerValue();
+
}
+ if(operationIds==null || operationIds.isEmpty())
+ obtainOperationIds();
+ getOperationNameFromOperationIds();
+
return operationId;
}
+ private void getOperationNameFromOperationIds() {
+ for (Map.Entry<String,Integer> ent : operationIds.entrySet()) {
+ if (ent.getValue().equals(operationId))
+ operationName=ent.getKey();
+ }
+ }
+
public void setOperationId(Integer operationId) {
this.operationId = operationId;
}
+ public String getOperationName() {
+ return operationName;
+ }
+
+ public void setOperationName(String operationName) {
+ this.operationName = operationName;
+ }
+
public Map<String, Integer> getOperationIds() {
obtainOperationIds();
@@ -253,7 +257,6 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
}
public ConfigurationDefinition getConfigurationDefinition() {
- System.out.println("OperationsBackingBean.getConfigurationDefinition");
if (configurationDefinition==null)
lookupConfiguration();
@@ -271,7 +274,6 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
public void setConfiguration(Configuration configuration) {
this.configuration = configuration;
- log.info("setC: " + configuration);
}
public String getNullConfigurationDefinitionMessage() {
@@ -294,7 +296,6 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
public void setTokenMode(String tokenMode) {
this.tokenMode = tokenMode;
- log.info("token mode" + tokenMode);
persistProperty(alertParameters, OperationsSender.TOKEN_MODE,tokenMode);
}
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/resources/operations.xhtml b/modules/enterprise/server/plugins/alert-operations/src/main/resources/operations.xhtml
index 98dcada..dc3a917 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/resources/operations.xhtml
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/resources/operations.xhtml
@@ -59,7 +59,7 @@
<h:messages />
<rich:panel rendered="#{not empty operationsBean.operationId}">
<br/>
- Parameters for <h:outputText value=" #{operationsBean.operationId}"/>
+ Parameters for operation '<h:outputText value=" #{operationsBean.operationName}"/>':
<p/>
<h:selectOneMenu id="tokenModeMenu" value="#{operationsBean.tokenMode}">
<f:selectItem itemValue="literal" itemLabel="Literal"/>
commit 6204586d5d601a564e6e96c35f6d473d3dee43b5
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Wed Mar 3 18:12:46 2010 +0100
Inject real Subject of current user and fix congifuration display directly after login.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/CustomContentUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/CustomContentUIBean.java
index 683057b..e39650c 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/CustomContentUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/CustomContentUIBean.java
@@ -26,6 +26,8 @@ import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.web.RequestParameter;
import org.jboss.seam.contexts.Context;
import org.jboss.seam.contexts.Contexts;
+
+import org.rhq.core.domain.auth.Subject;
import org.rhq.enterprise.server.alert.AlertNotificationManagerLocal;
import org.rhq.enterprise.server.plugin.pc.alert.AlertSenderInfo;
import org.rhq.enterprise.server.plugin.pc.alert.CustomAlertSenderBackingBean;
@@ -43,6 +45,9 @@ public class CustomContentUIBean {
@In
private AlertNotificationManagerLocal alertNotificationManager;
+ @In("#{webUser.subject}")
+ private Subject subject;
+
private String contentUrl;
public String getContentUrl() {
@@ -62,6 +67,7 @@ public class CustomContentUIBean {
notificationId);
if (backingBeanName != null && backingBean != null) {
+ backingBean.setWebUser(subject);
outjectBean(backingBeanName, backingBean);
}
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/CustomAlertSenderBackingBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/CustomAlertSenderBackingBean.java
index 12312f2..73ddf85 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/CustomAlertSenderBackingBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/CustomAlertSenderBackingBean.java
@@ -18,6 +18,7 @@
*/
package org.rhq.enterprise.server.plugin.pc.alert;
+import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.enterprise.server.configuration.ConfigurationManagerLocal;
@@ -32,6 +33,7 @@ public class CustomAlertSenderBackingBean {
/** Configuration from the per alert definition parameters */
protected Configuration alertParameters;
+ protected Subject webUser;
public Configuration getAlertParameters() {
return alertParameters;
@@ -41,6 +43,14 @@ public class CustomAlertSenderBackingBean {
this.alertParameters = alertParameters;
}
+ public Subject getWebUser() {
+ return webUser;
+ }
+
+ public void setWebUser(Subject webUser) {
+ this.webUser = webUser;
+ }
+
/**
* This method is called after constructing the bean and injecting the
* #alertParameters
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java
index dc41f01..c7c8c26 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java
@@ -130,17 +130,14 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
private void lookupConfiguration() {
-
try {
-// Subject subject = EnterpriseFacesContextUtility.getSubject();
- Subject subject = LookupUtil.getSubjectManager().getOverlord(); // TODO replace with real subject
OperationManagerLocal opMan = LookupUtil.getOperationManager();
obtainOperationIds();
if (operationId!=null) {
- OperationDefinition operationDefinition = opMan.getOperationDefinition(subject, operationId);
+ OperationDefinition operationDefinition = opMan.getOperationDefinition(webUser, operationId);
configurationDefinition = operationDefinition.getParametersConfigurationDefinition();
@@ -175,8 +172,7 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
if (resId!=null) {
OperationManagerLocal opMan = LookupUtil.getOperationManager();
- Subject subject = LookupUtil.getSubjectManager().getOverlord(); // TODO replace with real subject
- List<OperationDefinition> opDefs = opMan.findSupportedResourceOperations(subject, resId, false);
+ List<OperationDefinition> opDefs = opMan.findSupportedResourceOperations(webUser, resId, false);
for (OperationDefinition def : opDefs) {
operationIds.put(def.getDisplayName(),def.getId()); // TODO add more distinctive stuff in display
}
@@ -195,7 +191,7 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
}
public Integer getResId() {
-
+ System.out.println("OperationsBackingBean.getResId");
if (resId==null) {
PropertySimple prop = alertParameters.getSimple(OperationsSender.RESOURCE_ID);
if (prop!=null)
@@ -219,8 +215,7 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
if (resId!=null) {
ResourceManagerLocal resMgr = LookupUtil.getResourceManager();
- Subject subject = LookupUtil.getSubjectManager().getOverlord(); // TODO replace with real subject
- Resource res = resMgr.getResource(subject,resId);
+ Resource res = resMgr.getResource(webUser,resId);
resourceName = res.getName() + " (" + res.getResourceType().getName() + ")";
}
@@ -232,7 +227,7 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
}
public Integer getOperationId() {
-
+ System.out.println("OperationsBackingBean.getOperationId, operationId=" + operationId);
if (operationId ==null) {
PropertySimple prop = alertParameters.getSimple(OperationsSender.OPERATION_ID);
if (prop!=null)
@@ -258,10 +253,12 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
}
public ConfigurationDefinition getConfigurationDefinition() {
- return configurationDefinition;
-
+ System.out.println("OperationsBackingBean.getConfigurationDefinition");
+ if (configurationDefinition==null)
+ lookupConfiguration();
+ return configurationDefinition;
}
public void setConfigurationDefinition(ConfigurationDefinition configurationDefinition) {
commit e840b5ebe391a4e7dfdd75388319bef0cac29b7d
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Wed Mar 3 11:12:42 2010 +0100
Mvn exec-plugin executions need unique ids across the project.
Enable automatic build of the tokens documentation
diff --git a/modules/enterprise/server/plugins/alert-operations/pom.xml b/modules/enterprise/server/plugins/alert-operations/pom.xml
index 98f835e..6f99cce 100644
--- a/modules/enterprise/server/plugins/alert-operations/pom.xml
+++ b/modules/enterprise/server/plugins/alert-operations/pom.xml
@@ -52,6 +52,62 @@
</configuration>
</plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <version>1.1</version>
+ <executions>
+ <execution>
+ <!-- Generate tokens.xml file -->
+ <id>generate-tokens-xml</id>
+ <phase>install</phase>
+ <goals>
+ <goal>exec</goal>
+ </goals>
+ <configuration>
+ <executable>java</executable>
+ <workingDirectory>target</workingDirectory>
+ <arguments>
+ <argument>-cp</argument>
+ <argument>${project.build.directory}/${project.build.finalName}.jar</argument>
+ <argument>org.rhq.enterprise.server.plugins.alertOperations.PrintTokens</argument>
+ <argument>tokens.xml</argument>
+ </arguments>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>xml-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <!-- translate the tokens.xml file to confluence markup -->
+ <phase>install</phase>
+ <goals>
+ <goal>transform</goal>
+ </goals>
+ <configuration>
+ <transformationSets>
+ <transformationSet>
+ <dir>target</dir>
+ <stylesheet>src/main/token2confluence.xsl</stylesheet>
+ <includes>
+ <include>
+ tokens.xml
+ </include></includes>
+ <fileMappers>
+ <fileMapper implementation="org.codehaus.plexus.components.io.filemappers.FileExtensionMapper">
+ <targetExtension>.confluence</targetExtension>
+ </fileMapper>
+ </fileMappers>
+ </transformationSet>
+ </transformationSets>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
</build>
@@ -129,48 +185,6 @@
</executions>
</plugin>
-<!--
- <plugin>
- <artifactId>maven-dependency-plugin</artifactId>
- <version>2.0</version>
- <executions>
- <execution>
- <id>copy-resteasy-jars</id>
- <phase>process-resources</phase>
- <goals>
- <goal>copy</goal>
- </goals>
- <configuration>
- <artifactItems>
- <artifactItem>
- <groupId>org.jboss.resteasy</groupId>
- <artifactId>resteasy-jaxrs</artifactId>
- <version>${resteasy.version}</version>
- </artifactItem>
- <artifactItem>
- <groupId>org.jboss.resteasy</groupId>
- <artifactId>jaxrs-api</artifactId>
- <version>${resteasy.version}</version>
- </artifactItem>
- <artifactItem>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-simple</artifactId>
- <version>1.5.6</version>
- </artifactItem>
- <artifactItem>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <version>1.5.6</version>
- </artifactItem>
-
- </artifactItems>
- <outputDirectory>${project.build.outputDirectory}/lib</outputDirectory>
- </configuration>
- </execution>
- </executions>
- </plugin>
--->
-
</plugins>
</build>
</profile>
diff --git a/pom.xml b/pom.xml
index 191f86e..37afdcb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -554,10 +554,10 @@
<phase>generate-resources</phase>
<configuration>
<tasks>
- <tstamp>
+ <tstamp>
<format property="buildTime" pattern="MM/dd/yy hh:mm aa z" locale="en,US" timezone="GMT"/>
</tstamp>
- <mkdir dir="target"/>
+ <mkdir dir="target"/>
<echo file="target/build-time.properties" level="error">buildTime = ${buildTime}</echo>
</tasks>
</configuration>
@@ -569,7 +569,7 @@
<inherited>false</inherited>
<goals>
<goal>run</goal>
- </goals>
+ </goals>
<configuration>
<tasks>
<echo level="debug">buildTime = ${buildTime}</echo>
@@ -585,23 +585,24 @@
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
+ <id>generate-build-number-properties</id>
<phase>generate-resources</phase>
<goals>
<goal>exec</goal>
- </goals>
+ </goals>
+ <configuration>
+ <executable>git</executable>
+ <arguments>
+ <argument>log</argument>
+ <argument>--pretty=format:buildNumber = %h</argument>
+ <argument>-n1</argument>
+ </arguments>
+ <outputFile>${project.build.directory}/build-number.properties</outputFile>
+ </configuration>
</execution>
</executions>
- <configuration>
- <executable>git</executable>
- <arguments>
- <argument>log</argument>
- <argument>--pretty=format:buildNumber = %h</argument>
- <argument>-n1</argument>
- </arguments>
- <outputFile>${project.build.directory}/build-number.properties</outputFile>
- </configuration>
</plugin>
-
+
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
@@ -620,7 +621,7 @@
</execution>
</executions>
</plugin>
-
+
<!-- Ensure all code compiles and runs on Java 5 or later. -->
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
@@ -852,7 +853,7 @@
<property>
<name>rhq.m2.repo.url.oracle</name>
</property>
- </activation>
+ </activation>
<dependencies>
<!-- Oracle JDBC driver - required only if you want to run the tests, or dbsetup, against Oracle.
commit 8addeee897707dc3bddd898218ec1bea2b8ad7f1
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Tue Mar 2 21:40:50 2010 +0100
Don't clone, but deepCopy without the ids.
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java
index e355292..95217a2 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java
@@ -116,7 +116,7 @@ public class OperationsSender extends AlertSender {
if (parameters!=null && tokenMode.equals(INTERPRETED)) {
// We must not pass the original Config object, as this would mean
// our tokens get wiped out.
- theParameters = parameters.clone();
+ theParameters = parameters.deepCopy(false);
Map<String,PropertySimple> propsMap = theParameters.getSimpleProperties();
if (!propsMap.isEmpty()) {
ResourceManagerLocal resMgr = LookupUtil.getResourceManager();
commit 7cd1b3fac0ae4525f78bad4e8269768408d5f156
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Tue Mar 2 21:27:36 2010 +0100
Allow for camelCase in tokens. Actually use the provided target resource.
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/AlertTokenReplacer.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/AlertTokenReplacer.java
index e8c61dd..4966f22 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/AlertTokenReplacer.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/AlertTokenReplacer.java
@@ -50,7 +50,8 @@ public class AlertTokenReplacer {
public AlertTokenReplacer(Alert alert, OperationDefinition operationDefinition, Resource targetResource) {
this.alert = alert;
this.operationDefinition = operationDefinition;
- pattern = Pattern.compile("<%\\s*([a-z]+\\.[a-z0-9]+)\\s*%>");
+ this.targetResource = targetResource;
+ pattern = Pattern.compile("<%\\s*([a-zA-Z]+\\.[a-zA-Z0-9]+)\\s*%>");
}
/**
@@ -136,6 +137,9 @@ public class AlertTokenReplacer {
case TEST_FIX:
ret = THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG;
break;
+ case TEST_CAMEL:
+ ret ="camel";
+ break;
default:
ret = NOT_YET_IMPLEMENTED;
}
@@ -181,6 +185,8 @@ public class AlertTokenReplacer {
Subject overlord = LookupUtil.getSubjectManager().getOverlord();
Resource parent;
Resource platform = mgr.getPlaformOfResource(overlord,resource.getId());
+ if (platform==null)
+ platform=resource;
switch (token) {
case RESOURCE_ID:
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/Token.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/Token.java
index 2d810f0..4b90bc1 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/Token.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/Token.java
@@ -70,8 +70,10 @@ public enum Token {
// only for testing
TEST_ECHO(TokenClass.TEST,"echo", "Echo the input"),
- TEST_FIX(TokenClass.TEST,"fix", "Return a fixed string");
+ TEST_FIX(TokenClass.TEST,"fix", "Return a fixed string"),
+ TEST_CAMEL(TokenClass.TEST,"camelCase","Test matching of camels")
+ ;
private TokenClass tc;
private String name;
diff --git a/modules/enterprise/server/plugins/alert-operations/src/test/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacementTest.java b/modules/enterprise/server/plugins/alert-operations/src/test/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacementTest.java
index cf6c48d..45b03d6 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/test/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacementTest.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/test/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacementTest.java
@@ -56,6 +56,9 @@ public class TokenReplacementTest {
assert res != null;
assert res.equals(TEST_ECHO);
+ res = tr.replaceToken("test.camelCase");
+ assert res != null;
+ assert res.equals("camel");
/*
res = tr.replaceToken("alert.id");
assert res != null;
commit e09ef2624024f30c26e77a3220aff300db39d67d
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Tue Mar 2 15:20:12 2010 +0100
Clone the parameters before replacing tokens. Also pass the target resource to the replacer.
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java
index 635085a..e355292 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java
@@ -34,11 +34,13 @@ import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.operation.OperationDefinition;
+import org.rhq.core.domain.resource.Resource;
import org.rhq.enterprise.server.configuration.ConfigurationManagerLocal;
import org.rhq.enterprise.server.exception.ScheduleException;
import org.rhq.enterprise.server.operation.OperationManagerLocal;
import org.rhq.enterprise.server.operation.ResourceOperationSchedule;
import org.rhq.enterprise.server.plugin.pc.alert.AlertSender;
+import org.rhq.enterprise.server.resource.ResourceManagerLocal;
import org.rhq.enterprise.server.util.LookupUtil;
/**
@@ -75,7 +77,7 @@ public class OperationsSender extends AlertSender {
String opName = null;
OperationManagerLocal opMgr = LookupUtil.getOperationManager();
- Subject subject = LookupUtil.getSubjectManager().getOverlord(); // TODO get real subject
+ Subject subject = LookupUtil.getSubjectManager().getOverlord(); // TODO get real subject?
List<OperationDefinition> opdefs = opMgr.findSupportedResourceOperations(subject,resourceId,false);
OperationDefinition opDef = null;
@@ -109,26 +111,37 @@ public class OperationsSender extends AlertSender {
* If we have parameters and the user wants tokens to be interpreted, then loop
* over the parameters and do token replacement.
*/
- if (parameters!=null && tokenMode.equals(INTERPRETED)) {
- Map<String,PropertySimple> propsMap = parameters.getSimpleProperties();
- if (!propsMap.isEmpty()) {
- AlertTokenReplacer tr = new AlertTokenReplacer(alert, opDef, null);
- for (PropertySimple prop : propsMap.values()) {
- String tmp = prop.getStringValue();
- tmp = tr.replaceTokens(tmp);
- prop.setStringValue(tmp);
+ Configuration theParameters = null;
+ try {
+ if (parameters!=null && tokenMode.equals(INTERPRETED)) {
+ // We must not pass the original Config object, as this would mean
+ // our tokens get wiped out.
+ theParameters = parameters.clone();
+ Map<String,PropertySimple> propsMap = theParameters.getSimpleProperties();
+ if (!propsMap.isEmpty()) {
+ ResourceManagerLocal resMgr = LookupUtil.getResourceManager();
+ Resource targetResource = resMgr.getResource(subject,resourceId);
+ AlertTokenReplacer tr = new AlertTokenReplacer(alert, opDef, targetResource);
+ for (PropertySimple prop : propsMap.values()) {
+ String tmp = prop.getStringValue();
+ tmp = tr.replaceTokens(tmp);
+ prop.setStringValue(tmp);
+ }
}
}
+ else {
+ theParameters = parameters;
+ }
+ } catch (Exception e) {
+ e.printStackTrace(); // TODO: Customise this generated block
}
-
-
/*
- * Now fire off the operation with no delay and no repetition.
- */
+ * Now fire off the operation with no delay and no repetition.
+ */
ResourceOperationSchedule sched;
try {
- sched = opMgr.scheduleResourceOperation(subject, resourceId, opName, 0, 0, 0, 0, parameters,
+ sched = opMgr.scheduleResourceOperation(subject, resourceId, opName, 0, 0, 0, 0, theParameters,
"Alert operation for " + alert.getAlertDefinition().getName());
} catch (ScheduleException e) {
return new SenderResult(ResultState.FAILURE, "Scheduling of operation " + opName + " on resource " + resourceId + " failed: " + e.getMessage());
14 years, 3 months
[rhq] Branch 'alertPlugin' - modules/core
by Heiko W. Rupp
modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml | 4 +-
modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml | 20 +++++-----
2 files changed, 12 insertions(+), 12 deletions(-)
New commits:
commit b9e910bf92e1eed1c3ee8182742d49183ed41147
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Thu Mar 4 12:48:47 2010 +0100
BZ 570453 max varchar2 len on oracle is 4000 bytes.
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 eb2fd2a..00f006d 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/alert-schema.xml
@@ -99,8 +99,8 @@
<column name="SENDER" required="false" size="200" type="VARCHAR2"/>
<column name="RESULT_STATE" required="false" size="20" type="VARCHAR2"/>
<column name="MESSAGE" required="false" size="255" type="VARCHAR2"/>
- <column name="ALL_EMAILS" required="false" size="4096" type="VARCHAR2"/>
- <column name="EMAILS_FAILED" required="false" size="4096" type="VARCHAR2"/>
+ <column name="ALL_EMAILS" required="false" size="4000" type="VARCHAR2"/>
+ <column name="EMAILS_FAILED" required="false" size="4000" type="VARCHAR2"/>
</table>
<table name="RHQ_ALERT_CONDITION_LOG" tablespace="@@@LARGE_TABLESPACE_FOR_DATA@@@"
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
index 74c6038..f44251b 100644
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@ -3027,8 +3027,8 @@
<schema-addColumn table="RHQ_ALERT_NOTIF_LOG" column="SENDER" columnType="VARCHAR2" precision="200" />
<schema-addColumn table="RHQ_ALERT_NOTIF_LOG" column="RESULT_STATE" columnType="VARCHAR2" precision="20" />
<schema-addColumn table="RHQ_ALERT_NOTIF_LOG" column="MESSAGE" columnType="VARCHAR2" precision="255" />
- <schema-addColumn table="RHQ_ALERT_NOTIF_LOG" column="ALL_EMAILS" columnType="VARCHAR2" precision="4096" />
- <schema-addColumn table="RHQ_ALERT_NOTIF_LOG" column="EMAILS_FAILED" columnType="VARCHAR2" precision="4096" />
+ <schema-addColumn table="RHQ_ALERT_NOTIF_LOG" column="ALL_EMAILS" columnType="VARCHAR2" precision="4000" />
+ <schema-addColumn table="RHQ_ALERT_NOTIF_LOG" column="EMAILS_FAILED" columnType="VARCHAR2" precision="4000" />
</schemaSpec>
<schemaSpec version="2.77.5">
<schema-directSQL>
@@ -3191,9 +3191,9 @@
<schema-addColumn table="RHQ_BUNDLE_DEPLOY_HIST" column="AUDIT_MESSAGE" columnType="LONGVARCHAR" />
<!-- Changes to RHQ_BUNDLE_FILE -->
- <schema-alterColumn table="RHQ_BUNDLE_FILE" column="PACKAGE_VERSION_ID" nullable="FALSE" />
+ <schema-alterColumn table="RHQ_BUNDLE_FILE" column="PACKAGE_VERSION_ID" nullable="FALSE" />
</schemaSpec>
-
+
<schemaSpec version="2.78.1">
<schema-addColumn table="RHQ_BUNDLE" column="REPO_ID" columnType="INTEGER" />
<schema-directSQL>
@@ -3203,9 +3203,9 @@
FOREIGN KEY (REPO_ID)
REFERENCES RHQ_REPO (ID)
</statement>
- </schema-directSQL>
+ </schema-directSQL>
</schemaSpec>
-
+
<schemaSpec version="2.79">
<schema-directSQL>
<statement desc="Normalizing resource group descriptions">
@@ -3213,7 +3213,7 @@
</statement>
</schema-directSQL>
</schemaSpec>
-
+
<schemaSpec version="2.82">
<schema-directSQL>
<statement desc="Creating table RHQ_SAVED_SEARCH">
@@ -3227,17 +3227,17 @@
</schema-directSQL>
<schema-addColumn table="RHQ_SAVED_SEARCH" column="CONTEXT" columnType="VARCHAR2" precision="25" />
<schema-alterColumn table="RHQ_SAVED_SEARCH" column="CONTEXT" nullable="FALSE" />
-
+
<schema-addColumn table="RHQ_SAVED_SEARCH" column="NAME" columnType="VARCHAR2" precision="200" />
<schema-addColumn table="RHQ_SAVED_SEARCH" column="DESCRIPTION" columnType="VARCHAR2" precision="500" />
<schema-addColumn table="RHQ_SAVED_SEARCH" column="PATTERN" columnType="VARCHAR2" precision="1000" />
<schema-alterColumn table="RHQ_SAVED_SEARCH" column="PATTERN" nullable="FALSE" />
-
+
<schema-addColumn table="RHQ_SAVED_SEARCH" column="JPQL_TRANSLATION" columnType="VARCHAR2" precision="4000" />
<schema-addColumn table="RHQ_SAVED_SEARCH" column="LAST_COMPUTE_TIME" columnType="LONG" />
<schema-alterColumn table="RHQ_SAVED_SEARCH" column="LAST_COMPUTE_TIME" nullable="FALSE" />
<schema-addColumn table="RHQ_SAVED_SEARCH" column="RESULT_COUNT" columnType="LONG" />
-
+
<schema-addColumn table="RHQ_SAVED_SEARCH" column="SUBJECT_ID" columnType="INTEGER" />
<schema-alterColumn table="RHQ_SAVED_SEARCH" column="SUBJECT_ID" nullable="FALSE" />
<schema-addColumn table="RHQ_SAVED_SEARCH" column="GLOBAL" columnType="BOOLEAN" />
14 years, 3 months
[rhq] Branch 'alertPlugin' - 94 commits - .classpath etc/eclipse-tools etc/modules etc/samples modules/common modules/core modules/enterprise modules/plugins
by Heiko W. Rupp
.classpath | 5
etc/eclipse-tools/RHQ | 38
etc/eclipse-tools/maven/RHQ | 11
etc/modules/base-perspective-war/pom.xml | 233 -----
etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java | 38
etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java | 49 -
etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java | 41
etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java | 161 ---
etc/modules/base-perspective-war/src/main/resources/seam.properties | 3
etc/modules/base-perspective-war/src/main/webapp/WEB-INF/components.xml | 16
etc/modules/base-perspective-war/src/main/webapp/WEB-INF/faces-config.xml | 28
etc/modules/base-perspective-war/src/main/webapp/WEB-INF/includes/pageControls.xhtml | 103 --
etc/modules/base-perspective-war/src/main/webapp/WEB-INF/jboss-web.xml | 20
etc/modules/base-perspective-war/src/main/webapp/WEB-INF/templates/mainTemplate.xhtml | 68 -
etc/modules/base-perspective-war/src/main/webapp/WEB-INF/web.xml | 108 --
etc/modules/base-perspective-war/src/main/webapp/index.xhtml | 36
etc/samples/perspectives/sample-perspective/app/pom.xml | 36
etc/samples/perspectives/sample-perspective/perspective/pom.xml | 2
modules/common/filetemplate-bundle/pom.xml | 37
modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/CommandRecipeCommand.java | 56 +
modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java | 85 ++
modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/FileRecipeCommand.java | 85 ++
modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RealizeRecipeCommand.java | 74 +
modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeCommand.java | 43 +
modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java | 270 ++++++
modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java | 249 +++++
modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ScriptRecipeCommand.java | 51 +
modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java | 204 ++++
modules/common/pom.xml | 1
modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleAgentService.java | 7
modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleScheduleRequest.java | 56 +
modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleScheduleResponse.java | 66 +
modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleUpdateRequest.java | 31
modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleUpdateResponse.java | 31
modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/PluginMetadataParser.java | 16
modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleServerService.java | 27
modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleStatusUpdate.java | 33
modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleUpdateComplete.java | 31
modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml | 1
modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml | 17
modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java | 60 +
modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleDeployDefinition.java | 8
modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleFile.java | 16
modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java | 57 -
modules/core/domain/src/main/java/org/rhq/core/domain/content/InstalledPackage.java | 2
modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java | 76 +
modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleVersionCriteria.java | 86 ++
modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementBaseline.java | 6
modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceType.java | 8
modules/core/domain/src/test/java/org/rhq/core/domain/bundle/test/BundleTest.java | 42
modules/core/gui/src/main/java/org/rhq/core/gui/table/model/PagedListDataModel.java | 5
modules/core/gui/src/main/java/org/rhq/core/gui/table/renderer/AllRowsSelectorRenderer.java | 3
modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java | 90 +-
modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployRequest.java | 89 ++
modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployResult.java | 64 +
modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleFacet.java | 1
modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleManagerProvider.java | 52 +
modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/util/ResponseTimeLogParser.java | 154 ++-
modules/core/plugin-container/pom.xml | 6
modules/core/plugin-container/src/main/java/org/rhq/core/pc/ServerServices.java | 57 -
modules/core/plugin-container/src/main/java/org/rhq/core/pc/bundle/BundleManager.java | 199 ++++
modules/core/plugin-container/src/main/java/org/rhq/core/pc/content/ContentManager.java | 20
modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginValidator.java | 94 +-
modules/core/plugin-container/src/test/java/org/rhq/core/pc/plugin/PluginManagerTest.java | 9
modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java | 3
modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/ServiceContainer.java | 2
modules/enterprise/gui/base-perspective-jar/pom.xml | 199 ++++
modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java | 41
modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java | 49 +
modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java | 41
modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java | 161 +++
modules/enterprise/gui/base-perspective-jar/src/main/resources/seam.properties | 3
modules/enterprise/gui/base-perspective-war/pom.xml | 67 +
modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/components.xml | 16
modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/faces-config.xml | 28
modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/includes/pageControls.xhtml | 103 ++
modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/jboss-web.xml | 20
modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/templates/mainTemplate.xhtml | 70 +
modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/web.xml | 108 ++
modules/enterprise/gui/base-perspective-war/src/main/webapp/index.xhtml | 36
modules/enterprise/gui/pom.xml | 3
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/CustomContentUIBean.java | 6
modules/enterprise/gui/portal-war/src/main/webapp/rhq/perspective/main.xhtml | 2
modules/enterprise/pom.xml | 2
modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClientProxy.java | 23
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java | 425 +++++++++-
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerHelper.java | 34
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java | 129 ++-
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerRemote.java | 19
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java | 47 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java | 61 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java | 24
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java | 1
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/CustomAlertSenderBackingBean.java | 10
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/bundle/BundleServerPluginContainer.java | 5
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/bundle/BundleServerPluginFacet.java | 31
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/bundle/BundleServerPluginManager.java | 54 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginManager.java | 34
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java | 40
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java | 18
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java | 312 ++++++-
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/TestBundleServerPluginService.java | 202 ++++
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/TestBundleServerPluginServiceMBean.java | 24
modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java | 68 -
modules/enterprise/server/plugins/alert-operations/src/main/resources/operations.xhtml | 2
modules/enterprise/server/plugins/filetemplate-bundle/pom.xml | 37
modules/enterprise/server/plugins/filetemplate-bundle/src/main/java/org/rhq/enterprise/server/plugins/filetemplate/BundleServerPluginComponent.java | 52 +
modules/enterprise/server/plugins/filetemplate-bundle/src/main/resources/META-INF/rhq-serverplugin.xml | 2
modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml | 6
modules/enterprise/server/plugins/perspectives/policy/app/pom.xml | 94 ++
modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundleDetailsUIBean.java | 157 +++
modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundleVersionDetailsUIBean.java | 163 +++
modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java | 119 ++
modules/enterprise/server/plugins/perspectives/policy/app/src/main/resources/seam.properties | 3
modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/WEB-INF/components.xml | 16
modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundleDetails.xhtml | 108 ++
modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundleVersionDetails.xhtml | 120 ++
modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml | 87 ++
modules/enterprise/server/plugins/perspectives/policy/perspective/pom.xml | 156 +++
modules/enterprise/server/plugins/perspectives/policy/perspective/src/main/resources/META-INF/rhq-serverplugin.xml | 30
modules/enterprise/server/plugins/perspectives/policy/pom.xml | 28
modules/enterprise/server/plugins/pom.xml | 2
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheIfModuleDirectoryComponent.java | 5
modules/plugins/apache/src/main/resources/META-INF/rhq-plugin.xml | 2
modules/plugins/filetemplate-bundle/pom.xml | 13
modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java | 28
modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java | 278 ++++++
modules/plugins/filetemplate-bundle/src/main/resources/META-INF/rhq-plugin.xml | 2
modules/plugins/filetemplate-bundle/src/test/java/org/rhq/plugins/filetemplate/ProcessingRecipeContextTest.java | 248 +++++
modules/plugins/virt/src/main/java/org/rhq/plugins/virt/VirtualizationNetworkComponent.java | 7
130 files changed, 6518 insertions(+), 1439 deletions(-)
New commits:
commit eac81485227312a19991d0e7731b830fb2f2b830
Merge: f93ec8c... d9d5866...
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Thu Mar 4 11:33:49 2010 +0100
Merge branch 'master' into alertPlugin
commit d9d58661d22bf1698c11ea8fbb33b17ad0e38bac
Merge: b98aefb... 9092141...
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Wed Mar 3 20:52:29 2010 -0500
Merge branch 'bundle-copy' into bundle
commit 90921416205a3f3ab2bdd6aa7f32142053b6ed67
Merge: ac72b22... eea8401...
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Wed Mar 3 20:52:11 2010 -0500
Merge branch 'master' into bundle-copy
commit eea8401df5d7d8c508584ae266927e0286c381f1
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Wed Mar 3 20:48:59 2010 -0500
fixed this test so it isn't so brittle - not sure how master has been passing since we moved to 3.0.0
diff --git a/modules/core/plugin-container/pom.xml b/modules/core/plugin-container/pom.xml
index 4c39807..f950282 100644
--- a/modules/core/plugin-container/pom.xml
+++ b/modules/core/plugin-container/pom.xml
@@ -150,6 +150,10 @@
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
+ <systemPropertyVariables>
+ <rhq.version>${project.version}</rhq.version>
+ </systemPropertyVariables>
+
<excludedGroups>${rhq.testng.excludedGroups}</excludedGroups>
<!-- need to point the library path to the location of the native libraries -->
<argLine>-Dorg.hyperic.sigar.path=${project.build.directory}/jboss-sigar</argLine>
@@ -180,4 +184,4 @@
</repository>
</repositories>
-</project>
\ No newline at end of file
+</project>
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/plugin/PluginManagerTest.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/plugin/PluginManagerTest.java
index a7d27ed..a315276 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/plugin/PluginManagerTest.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/plugin/PluginManagerTest.java
@@ -47,13 +47,14 @@ import java.io.File;
public class PluginManagerTest {
- static final String PLATFORM_PLUGIN = "org/rhq/rhq-platform-plugin/1.4.0-SNAPSHOT/rhq-platform-plugin-1.4.0-SNAPSHOT.jar";
+ static final String VERSION = System.getProperty("rhq.version");
+ static final String PLATFORM_PLUGIN = "org/rhq/rhq-platform-plugin/" + VERSION + "/rhq-platform-plugin-" + VERSION + ".jar";
- static final String HOSTS_PLUGIN = "org/rhq/rhq-hosts-plugin/1.4.0-SNAPSHOT/rhq-hosts-plugin-1.4.0-SNAPSHOT.jar";
+ static final String HOSTS_PLUGIN = "org/rhq/rhq-hosts-plugin/" + VERSION + "/rhq-hosts-plugin-" + VERSION + ".jar";
- static final String AUGEAS_PLUGIN = "org/rhq/rhq-augeas-plugin/1.4.0-SNAPSHOT/rhq-augeas-plugin-1.4.0-SNAPSHOT.jar";
+ static final String AUGEAS_PLUGIN = "org/rhq/rhq-augeas-plugin/" + VERSION + "/rhq-augeas-plugin-" + VERSION + ".jar";
- static final String JMX_PLUGIN = "org/rhq/rhq-jmx-plugin/1.4.0-SNAPSHOT/rhq-jmx-plugin-1.4.0-SNAPSHOT.jar";
+ static final String JMX_PLUGIN = "org/rhq/rhq-jmx-plugin/" + VERSION + "/rhq-jmx-plugin-" + VERSION + ".jar";
String m2RepoDir;
commit b98aefb0383974059cfa56b7212f4c7a0f4792ff
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Wed Mar 3 20:20:22 2010 -0500
plugin validator caught this error - the service resource had createDeletePolicy set to both but the resource component's parent did not have create-child facet implemented and its delete facet method was empty (so it wasn't really implemented either). removing createDeletePolicy
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheIfModuleDirectoryComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheIfModuleDirectoryComponent.java
index cc8cb16..7a86201 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheIfModuleDirectoryComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheIfModuleDirectoryComponent.java
@@ -42,7 +42,7 @@ import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.plugins.apache.mapping.ApacheAugeasMapping;
import org.rhq.plugins.apache.util.AugeasNodeSearch;
-public class ApacheIfModuleDirectoryComponent implements ResourceComponent<ApacheDirectoryComponent>, ConfigurationFacet, DeleteResourceFacet{
+public class ApacheIfModuleDirectoryComponent implements ResourceComponent<ApacheDirectoryComponent>, ConfigurationFacet {
private ResourceContext<ApacheDirectoryComponent> context;
private List<String> position;
@@ -102,9 +102,6 @@ public class ApacheIfModuleDirectoryComponent implements ResourceComponent<Apach
report.setStatus(ConfigurationUpdateStatus.FAILURE);
}
}
- public void deleteResource() throws Exception {
-
- }
private AugeasNode getNode(AugeasNode virtualHost) {
List<AugeasNode> directories = AugeasNodeSearch.getNodeByParentParams(virtualHost, IFMODULE_DIRECTIVE_NAME, position);
diff --git a/modules/plugins/apache/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/apache/src/main/resources/META-INF/rhq-plugin.xml
index 930f3fc..0668ccb 100644
--- a/modules/plugins/apache/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/apache/src/main/resources/META-INF/rhq-plugin.xml
@@ -707,7 +707,7 @@
&UseCanonicalName;
&UseCanonicalPhysicalPort;
</resource-configuration>
- <service name="IfModule Parameters" discovery="ApacheIfModuleDirectoryDiscoveryComponent" class="ApacheIfModuleDirectoryComponent" createDeletePolicy="both">
+ <service name="IfModule Parameters" discovery="ApacheIfModuleDirectoryDiscoveryComponent" class="ApacheIfModuleDirectoryComponent">
<resource-configuration>
&IfModulePosition;
&Order;
commit ac72b22b34f6ccf523e434f29c5b972f855a7b11
Merge: 091f599... d882f20...
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Wed Mar 3 19:26:22 2010 -0500
Merge branch 'bundle' into master-copy
Conflicts:
.classpath
modules/core/dbutils/pom.xml
modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java
modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java
modules/enterprise/server/ear/pom.xml
modules/enterprise/server/plugins/pom.xml
diff --cc .classpath
index fe06650,1a35400..04464c1
--- a/.classpath
+++ b/.classpath
@@@ -1,9 -1,8 +1,10 @@@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="modules/common/jboss-as/src/main/java"/>
+ <classpathentry kind="src" path="modules/common/filetemplate-bundle/src/main/java"/>
+ <classpathentry kind="src" path="modules/common/filetemplate-bundle/src/test/java"/>
+ <classpathentry kind="src" path="modules/enterprise/gui/base-perspective-jar/src/main/java"/>
+ <classpathentry kind="src" path="modules/plugins/nss/src/main/java"/>
- <classpathentry kind="src" path="etc/modules/base-perspective-war/src/main/java"/>
<classpathentry kind="src" path="modules/enterprise/server/plugins/jboss-software/src/test/java"/>
<classpathentry kind="src" path="modules/enterprise/server/plugins/jboss-software/src/main/java"/>
<classpathentry kind="src" path="modules/enterprise/remoting/client-api/src/main/java"/>
diff --cc modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
index 8169695,b2b3b11..74c6038
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@@ -3157,30 -3182,77 +3182,88 @@@
FOREIGN KEY (BUNDLE_DEPLOY_ID)
REFERENCES RHQ_BUNDLE_DEPLOY (ID)
</statement>
- </schema-directSQL>
+ </schema-directSQL>
<schema-addColumn table="RHQ_BUNDLE_DEPLOY_HIST" column="SUBJECT_NAME" columnType="VARCHAR2" precision="255" />
<schema-addColumn table="RHQ_BUNDLE_DEPLOY_HIST" column="AUDIT_TIME" columnType="LONG" />
- <schema-alterColumn table="RHQ_BUNDLE_DEPLOY_HIST" column="AUDIT_TIME" nullable="FALSE" />
+ <schema-alterColumn table="RHQ_BUNDLE_DEPLOY_HIST" column="AUDIT_TIME" nullable="FALSE" />
<schema-addColumn table="RHQ_BUNDLE_DEPLOY_HIST" column="AUDIT_ACTION" columnType="VARCHAR2" precision="50" />
<schema-alterColumn table="RHQ_BUNDLE_DEPLOY_HIST" column="AUDIT_ACTION" nullable="FALSE" />
- <schema-addColumn table="RHQ_BUNDLE_DEPLOY_HIST" column="AUDIT_MESSAGE" columnType="LONGVARCHAR" />
-
+ <schema-addColumn table="RHQ_BUNDLE_DEPLOY_HIST" column="AUDIT_MESSAGE" columnType="LONGVARCHAR" />
+
<!-- Changes to RHQ_BUNDLE_FILE -->
- <schema-alterColumn table="RHQ_BUNDLE_FILE" column="PACKAGE_VERSION_ID" nullable="FALSE" />
-
+ <schema-alterColumn table="RHQ_BUNDLE_FILE" column="PACKAGE_VERSION_ID" nullable="FALSE" />
</schemaSpec>
-
+
+ <schemaSpec version="2.78.1">
+ <schema-addColumn table="RHQ_BUNDLE" column="REPO_ID" columnType="INTEGER" />
+ <schema-directSQL>
+ <statement desc="Creating RHQ_BUNDLE foreign key relation to RHQ_REPO">
+ ALTER TABLE RHQ_BUNDLE
+ ADD CONSTRAINT RHQ_REPO_ID_FK
+ FOREIGN KEY (REPO_ID)
+ REFERENCES RHQ_REPO (ID)
+ </statement>
+ </schema-directSQL>
+ </schemaSpec>
+
+ <schemaSpec version="2.79">
+ <schema-directSQL>
+ <statement desc="Normalizing resource group descriptions">
+ UPDATE RHQ_RESOURCE_GROUP SET DESCRIPTION = NULL WHERE DESCRIPTION = ''
+ </statement>
+ </schema-directSQL>
+ </schemaSpec>
+
+ <schemaSpec version="2.82">
+ <schema-directSQL>
+ <statement desc="Creating table RHQ_SAVED_SEARCH">
+ CREATE TABLE RHQ_SAVED_SEARCH ( ID INTEGER )
+ </statement>
+ </schema-directSQL>
+ <schema-directSQL>
+ <statement desc="Creating primary key for RHQ_AFFINITY_GROUP">
+ ALTER TABLE RHQ_SAVED_SEARCH ADD PRIMARY KEY ( ID )
+ </statement>
+ </schema-directSQL>
+ <schema-addColumn table="RHQ_SAVED_SEARCH" column="CONTEXT" columnType="VARCHAR2" precision="25" />
+ <schema-alterColumn table="RHQ_SAVED_SEARCH" column="CONTEXT" nullable="FALSE" />
+
+ <schema-addColumn table="RHQ_SAVED_SEARCH" column="NAME" columnType="VARCHAR2" precision="200" />
+ <schema-addColumn table="RHQ_SAVED_SEARCH" column="DESCRIPTION" columnType="VARCHAR2" precision="500" />
+ <schema-addColumn table="RHQ_SAVED_SEARCH" column="PATTERN" columnType="VARCHAR2" precision="1000" />
+ <schema-alterColumn table="RHQ_SAVED_SEARCH" column="PATTERN" nullable="FALSE" />
+
+ <schema-addColumn table="RHQ_SAVED_SEARCH" column="JPQL_TRANSLATION" columnType="VARCHAR2" precision="4000" />
+ <schema-addColumn table="RHQ_SAVED_SEARCH" column="LAST_COMPUTE_TIME" columnType="LONG" />
+ <schema-alterColumn table="RHQ_SAVED_SEARCH" column="LAST_COMPUTE_TIME" nullable="FALSE" />
+ <schema-addColumn table="RHQ_SAVED_SEARCH" column="RESULT_COUNT" columnType="LONG" />
+
+ <schema-addColumn table="RHQ_SAVED_SEARCH" column="SUBJECT_ID" columnType="INTEGER" />
+ <schema-alterColumn table="RHQ_SAVED_SEARCH" column="SUBJECT_ID" nullable="FALSE" />
+ <schema-addColumn table="RHQ_SAVED_SEARCH" column="GLOBAL" columnType="BOOLEAN" />
+ <schema-alterColumn table="RHQ_SAVED_SEARCH" column="GLOBAL" nullable="FALSE" />
+
+ <schema-directSQL>
+ <statement targetDBVendor="postgresql" desc="Inserting global default saved search 'Downed Platforms'">
+ INSERT INTO rhq_saved_search (id, context, name, description, pattern, last_compute_time, subject_id, global)
+ VALUES (1, 'Resource', 'Downed Platforms', 'All downed machines across the entire enterprise', 'down platform', 0, 1, true)
+ </statement>
+ <statement targetDBVendor="oracle" desc="Inserting global default saved search 'Downed Platforms'">
+ INSERT INTO rhq_saved_search (id, context, name, description, pattern, last_compute_time, subject_id, global)
+ VALUES (1, 'Resource', 'Downed Platforms', 'All downed machines across the entire enterprise', 'down platform', 0, 1, 1)
+ </statement>
+ </schema-directSQL>
+ <schema-directSQL>
+ <statement targetDBVendor="postgresql" desc="Inserting global default saved search 'Downed Servers'">
+ INSERT INTO rhq_saved_search (id, context, name, description, pattern, last_compute_time, subject_id, global)
+ VALUES (2, 'Resource', 'Downed Servers', 'All downed servers across the entire enterprise', 'down server', 0, 1, true)
+ </statement>
+ <statement targetDBVendor="oracle" desc="Inserting global default saved search 'Downed Servers'">
+ INSERT INTO rhq_saved_search (id, context, name, description, pattern, last_compute_time, subject_id, global)
+ VALUES (2, 'Resource', 'Downed Servers', 'All downed servers across the entire enterprise', 'down server', 0, 1, 1)
+ </statement>
+ </schema-directSQL>
+ </schemaSpec>
</dbupgrade>
</target>
</project>
diff --cc modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java
index 573e9c0,27a1375..4732698
--- a/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java
+++ b/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java
@@@ -348,60 -343,35 +348,60 @@@ public class SystemInfoFactory
public static TemplateEngine fetchTemplateEngine() {
- try{
- SystemInfo systemInfo = createSystemInfo();
-
- Map<String, String> tokens = new HashMap<String, String>();
- tokens.put(TOKEN_PREFIX+"hostname", systemInfo.getHostname());
-
- tokens.put(TOKEN_PREFIX+"os.name", systemInfo.getOperatingSystemName());
- tokens.put(TOKEN_PREFIX+"os.version", systemInfo.getOperatingSystemVersion());
- tokens.put(TOKEN_PREFIX+"os.type", systemInfo.getOperatingSystemType().toString());
- tokens.put(TOKEN_PREFIX+"cpu.count", Integer.toString(systemInfo.getNumberOfCpus()));
- tokens.put(TOKEN_PREFIX+"architecture", systemInfo.getSystemArchitecture());
-
- for (NetworkAdapterInfo networkAdapter : systemInfo.getAllNetworkAdapters()) {
- String key = TOKEN_PREFIX+"interfaces." + networkAdapter.getName();
- tokens.put(key + ".mac", networkAdapter.getMacAddressString());
- tokens.put(key + ".type", networkAdapter.getType());
- tokens.put(key + ".flags", networkAdapter.getAllFlags());
-
- if (!networkAdapter.getUnicastAddresses().isEmpty()) {
- tokens.put(key + ".address", networkAdapter.getUnicastAddresses().get(0).getHostAddress());
+ try {
+ SystemInfo systemInfo = createSystemInfo();
+
+ Map<String, String> tokens = new HashMap<String, String>();
+ tokens.put(TOKEN_PREFIX + "hostname", systemInfo.getHostname());
+
+ tokens.put(TOKEN_PREFIX + "os.name", systemInfo.getOperatingSystemName());
+ tokens.put(TOKEN_PREFIX + "os.version", systemInfo.getOperatingSystemVersion());
+ tokens.put(TOKEN_PREFIX + "os.type", systemInfo.getOperatingSystemType().toString());
+ tokens.put(TOKEN_PREFIX + "architecture", systemInfo.getSystemArchitecture());
+ try {
+ tokens.put(TOKEN_PREFIX + "cpu.count", Integer.toString(systemInfo.getNumberOfCpus()));
+ } catch (Exception e) {
+ tokens.put(TOKEN_PREFIX + "cpu.count", "?");
}
- if (!networkAdapter.getMulticastAddresses().isEmpty()) {
- tokens.put(key + ".multicast.address", networkAdapter.getMulticastAddresses().get(0).getHostAddress());
+
+ List<NetworkAdapterInfo> allNetworkAdapters = null;
+ try {
+ allNetworkAdapters = systemInfo.getAllNetworkAdapters();
+ } catch (Exception e) {
}
- }
- TemplateEngine templateEngine = new TemplateEngine(tokens);
- return templateEngine;
- }catch(Exception e){
- return new TemplateEngine(new HashMap());
+ if (allNetworkAdapters != null) {
+ for (NetworkAdapterInfo networkAdapter : allNetworkAdapters) {
+ String key = TOKEN_PREFIX + "interfaces." + networkAdapter.getName();
+ tokens.put(key + ".mac", networkAdapter.getMacAddressString());
+ tokens.put(key + ".type", networkAdapter.getType());
+ tokens.put(key + ".flags", networkAdapter.getAllFlags());
+
+ if (!networkAdapter.getUnicastAddresses().isEmpty()) {
+ tokens.put(key + ".address", networkAdapter.getUnicastAddresses().get(0).getHostAddress());
+ }
+ if (!networkAdapter.getMulticastAddresses().isEmpty()) {
+ tokens.put(key + ".multicast.address", networkAdapter.getMulticastAddresses().get(0)
+ .getHostAddress());
+ }
+ }
+ }
+
+ // create a base IP address - this one is known to java and should always exist no matter what platform we are on
+ try {
+ try {
+ tokens.put(TOKEN_PREFIX + "interfaces.java.address", InetAddress
+ .getByName(systemInfo.getHostname()).getHostAddress());
+ } catch (Exception e) {
+ tokens.put(TOKEN_PREFIX + "interfaces.java.address", InetAddress.getLocalHost().getHostAddress());
+ }
+ } catch (Exception e2) {
+ }
+
+ TemplateEngine templateEngine = new TemplateEngine(tokens);
+ return templateEngine;
+ } catch (Exception e) {
+ // some rare exception occurred that we didn't expect, rather than blow up entirely, just don't provide any values
+ return new TemplateEngine(new HashMap<String, String>());
}
}
--}
++}
commit 091f59945e654da8e2d140cc017d433331b1af7c
Merge: bc2d729... 966bc00...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Mar 3 17:45:15 2010 -0500
Merge branch 'bundle' into bundle-jay
commit bc2d7299246cc4a83411254c6d2b9a0c04123b28
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Mar 3 17:43:38 2010 -0500
added:
createBundleDeployDefinition
getBundleVersionFilenames
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleDeployDefinition.java b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleDeployDefinition.java
index b83c576..7c88e96 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleDeployDefinition.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleDeployDefinition.java
@@ -83,7 +83,7 @@ public class BundleDeployDefinition implements Serializable {
private Long mtime = System.currentTimeMillis();
@JoinColumn(name = "CONFIG_ID", referencedColumnName = "ID", nullable = true)
- @OneToOne(fetch = FetchType.LAZY, optional = true)
+ @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, optional = true)
private Configuration configuration;
@Column(name = "ENFORCE_POLICY", nullable = false)
@@ -107,6 +107,12 @@ public class BundleDeployDefinition implements Serializable {
// for JPA use
}
+ public BundleDeployDefinition(BundleVersion bundleVersion, String name) {
+ this.bundleVersion = bundleVersion;
+ this.name = name;
+ this.enforcePolicy = false;
+ }
+
public int getId() {
return id;
}
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 29b25cf..c9a3261 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
@@ -20,8 +20,10 @@ package org.rhq.enterprise.server.bundle;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
+import java.util.HashSet;
import java.util.List;
import java.util.Random;
+import java.util.Set;
import java.util.UUID;
import javax.ejb.EJB;
@@ -33,6 +35,7 @@ import javax.persistence.Query;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.rhq.core.clientapi.agent.configuration.ConfigurationUtility;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.bundle.Bundle;
@@ -41,6 +44,8 @@ import org.rhq.core.domain.bundle.BundleDeployment;
import org.rhq.core.domain.bundle.BundleFile;
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.definition.ConfigurationDefinition;
import org.rhq.core.domain.content.Architecture;
import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageType;
@@ -115,6 +120,44 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
@RequiredPermission(Permission.MANAGE_INVENTORY)
+ public BundleDeployDefinition createBundleDeployDefinition(Subject subject, int bundleVersionId, String name,
+ String description, Configuration configuration, boolean enforcePolicy, int enforcementInterval,
+ boolean pinToBundle) throws Exception {
+
+ if (null == name || "".equals(name.trim())) {
+ throw new IllegalArgumentException("Invalid bundleDeployDefinitionName: " + name);
+ }
+ BundleVersion bundleVersion = entityManager.find(BundleVersion.class, bundleVersionId);
+ if (null == bundleVersion) {
+ throw new IllegalArgumentException("Invalid bundleVersionId: " + bundleVersionId);
+ }
+ ConfigurationDefinition configDef = bundleVersion.getConfigurationDefinition();
+ if (null != configDef) {
+ if (null == configuration) {
+ throw new IllegalArgumentException(
+ "Missing Configuration. Configuration is required when the specified BundleVersion defines Configuration Properties.");
+ }
+ List<String> errors = ConfigurationUtility.validateConfiguration(configuration, configDef);
+ if (null != errors && !errors.isEmpty()) {
+ throw new IllegalArgumentException("Invalid Configuration: " + errors.toString());
+ }
+ }
+
+ BundleDeployDefinition deployDef = new BundleDeployDefinition(bundleVersion, name);
+ deployDef.setDescription(description);
+ deployDef.setConfiguration(configuration);
+ deployDef.setEnforcePolicy(enforcePolicy);
+ deployDef.setEnforcementInterval(enforcementInterval);
+ if (pinToBundle) {
+ deployDef.setBundle(bundleVersion.getBundle());
+ }
+
+ entityManager.persist(deployDef);
+
+ return deployDef;
+ }
+
+ @RequiredPermission(Permission.MANAGE_INVENTORY)
public BundleType createBundleType(Subject subject, String name, int resourceTypeId) throws Exception {
if (null == name || "".equals(name.trim())) {
throw new IllegalArgumentException("Invalid bundleTypeName: " + name);
@@ -283,6 +326,46 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
return (PackageType) packageTypeQuery.getSingleResult();
}
+ @RequiredPermission(Permission.MANAGE_INVENTORY)
+ public Set<String> getBundleVersionFilenames(Subject subject, int bundleVersionId, boolean withoutBundleFileOnly)
+ throws Exception {
+
+ BundleVersion bundleVersion = entityManager.find(BundleVersion.class, bundleVersionId);
+ if (null == bundleVersion) {
+ throw new IllegalArgumentException("Invalid bundleVersionId: " + bundleVersionId);
+ }
+
+ // parse the recipe (validation occurs here) and get the config def and list of files
+ BundleType bundleType = bundleVersion.getBundle().getBundleType();
+ BundleServerPluginFacet bp = BundleManagerHelper.getPluginContainer().getBundleServerPluginManager()
+ .getBundleServerPluginFacet(bundleType.getName());
+ RecipeParseResults parseResults = bp.parseRecipe(bundleVersion.getRecipe());
+
+ Set<String> result = parseResults.getBundleFileNames();
+
+ if (withoutBundleFileOnly) {
+ List<BundleFile> bundleFiles = bundleVersion.getBundleFiles();
+ Set<String> allFilenames = result;
+ result = new HashSet<String>(allFilenames.size() - bundleFiles.size());
+ for (String filename : allFilenames) {
+ boolean found = false;
+ for (BundleFile bundleFile : bundleFiles) {
+ String name = bundleFile.getPackageVersion().getGeneralPackage().getName();
+ if (name.equals(filename)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ result.add(filename);
+ }
+ }
+ }
+
+ return result;
+
+ }
+
@SuppressWarnings("unchecked")
public List<BundleType> getAllBundleTypes(Subject subject) {
// the list of types will be small, no need to support paging
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
index ec3b73b..22880be 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
@@ -20,6 +20,7 @@ package org.rhq.enterprise.server.bundle;
import java.io.InputStream;
import java.util.List;
+import java.util.Set;
import javax.ejb.Local;
@@ -30,6 +31,7 @@ import org.rhq.core.domain.bundle.BundleDeployment;
import org.rhq.core.domain.bundle.BundleFile;
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.content.Architecture;
import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleDeployDefinitionCriteria;
@@ -95,6 +97,24 @@ public interface BundleManagerLocal {
Bundle createBundle(Subject subject, String name, int bundleTypeId) throws Exception;
/**
+ * @param subject must be InventoryManager
+ * @param BundleVersionId the BundleVersion being deployed by this definition
+ * @param name a name for this definition. not null or empty
+ * @param description an optional longer description describing this deploy def
+ * @param configuration a Configuration (pojo) to be associated with this deploy def. Although
+ * it is not enforceable
+ * must be that of the associated BundleVersion.
+ * @param enforcePolicy if true enforce policy on deployments made with this deploy def
+ * @param enforceInterval if enforcePolicy is true check policy at this interval (in seconds), otherwise ignored
+ * @param pinToBundle if true this deploy def is disabled if a newer BundleVersion is generated for the Bundle
+ * @return
+ * @throws Exception
+ */
+ BundleDeployDefinition createBundleDeployDefinition(Subject subject, int bundleVersionId, String name,
+ String description, Configuration configuration, boolean enforcePolicy, int enforcementInterval,
+ boolean pinToBundle) throws Exception;
+
+ /**
* Not generally called. For use by Server Side Plugins when registering a Bundle Plugin.
*
* @param subject must be InventoryManager
@@ -114,6 +134,20 @@ public interface BundleManagerLocal {
BundleVersion createBundleVersion(Subject subject, int bundleId, String name, String bundleVersion, String recipe)
throws Exception;
+ /**
+ * 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 bundleVersionId the BundleVersion being queried
+ * @param withoutBundleFileOnly if true omit any filenames that already have a corresponding BundleFile for
+ * the BundleVersion.
+ * @return The List of filenames.
+ * @throws Exception
+ */
+ Set<String> getBundleVersionFilenames(Subject subject, int bundleVersionId, boolean withoutBundleFileOnly)
+ throws Exception;
+
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
// The remaining methods are shared with the Remote Interface.
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
index 24c6dae..45e946f 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
@@ -21,6 +21,7 @@ package org.rhq.enterprise.server.bundle;
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
import javax.persistence.EntityManager;
import javax.persistence.Query;
@@ -33,9 +34,12 @@ import org.testng.annotations.Test;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.Bundle;
+import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleFile;
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.Package;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
@@ -109,6 +113,12 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
for (Object removeMe : doomed) {
em.remove(em.getReference(BundleFile.class, ((BundleFile) removeMe).getId()));
}
+ // remove any orphaned bdds
+ q = em.createQuery("SELECT bdd FROM BundleDeployDefinition bdd WHERE bdd.name LIKE '" + TEST_PREFIX + "%'");
+ doomed = q.getResultList();
+ for (Object removeMe : doomed) {
+ em.remove(em.getReference(BundleDeployDefinition.class, ((BundleDeployDefinition) removeMe).getId()));
+ }
// remove packages which cascade remove packageversions
q = em.createQuery("SELECT p FROM Package p WHERE p.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
@@ -216,6 +226,47 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
}
@Test(enabled = TESTS_ENABLED)
+ public void testCreateBundleDeploymentDef() throws Exception {
+ Bundle b1 = createBundle("one");
+ assertNotNull(b1);
+ BundleVersion bv1 = createBundleVersion(b1.getName() + "-1", null, b1);
+ assertNotNull(bv1);
+ Configuration config = new Configuration();
+ BundleDeployDefinition bdd1;
+ try {
+ bdd1 = createDeployDefinition("one", bv1, config);
+ fail("Bad config was accepted");
+ } catch (Exception e) {
+ System.out.println("EXPECTED EXCEPTION: " + e);
+ // expected due to bad config
+ }
+ config.put(new PropertySimple("bundletest.property", "bundletest.property value"));
+ bdd1 = createDeployDefinition("one", bv1, config);
+ assertNotNull(bdd1);
+ }
+
+ @Test(enabled = TESTS_ENABLED)
+ public void testGetBundleFilenames() throws Exception {
+ Bundle b1 = createBundle("one");
+ assertNotNull(b1);
+ BundleVersion bv1 = createBundleVersion(b1.getName(), "1.0", b1);
+ assertNotNull(bv1);
+ Set<String> filenames = bundleManager.getBundleVersionFilenames(getOverlord(), bv1.getId(), true);
+ assertNotNull(filenames);
+ assertEquals(2, filenames.size());
+ BundleFile bf1 = bundleManager.addBundleFileViaByteArray(getOverlord(), bv1.getId(), TEST_PREFIX
+ + "-bundlefile-1", "1.0", null, "Test Bundle File # 1".getBytes(), false);
+ filenames = bundleManager.getBundleVersionFilenames(getOverlord(), bv1.getId(), true);
+ assertNotNull(filenames);
+ assertEquals(1, filenames.size());
+ BundleFile bf2 = bundleManager.addBundleFileViaByteArray(getOverlord(), bv1.getId(), TEST_PREFIX
+ + "-bundlefile-2", "1.0", null, "Test Bundle File # 2".getBytes(), false);
+ filenames = bundleManager.getBundleVersionFilenames(getOverlord(), bv1.getId(), true);
+ assertNotNull(filenames);
+ assertEquals(0, filenames.size());
+ }
+
+ @Test(enabled = TESTS_ENABLED)
public void testfindBundlesByCriteria() throws Exception {
Bundle b1 = createBundle("one");
Bundle b2 = createBundle("two");
@@ -343,6 +394,17 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
return bv;
}
+ private BundleDeployDefinition createDeployDefinition(String name, BundleVersion bv, Configuration config)
+ throws Exception {
+ final String fullName = TEST_PREFIX + "-bundledeploydef-" + name;
+ BundleDeployDefinition bdd = bundleManager.createBundleDeployDefinition(getOverlord(), bv.getId(), fullName,
+ fullName, config, false, -1, false);
+
+ assert bdd.getId() > 0;
+ assert bdd.getName().endsWith(fullName);
+ return bdd;
+ }
+
private ResourceType createResourceType(String name) throws Exception {
final String fullName = TEST_PREFIX + "-resourcetype-" + name;
ResourceType rt = new ResourceType(fullName, "BundleManagerBeanTest", ResourceCategory.PLATFORM, null);
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 dc43f97..3833955 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
@@ -188,13 +188,13 @@ public class TestBundleServerPluginService extends ServerPluginService implement
ConfigurationDefinition configDef;
Set<String> bundleFileNames;
- configDef = new ConfigurationDefinition("SampleBundle", "Stubbed ConfigDef for Sample Bundle");
- configDef.put(new PropertyDefinitionSimple("sample.bundle.deploy.directory",
- "Stubbed Property for deploy directory (must already exist on target platform)", true,
- PropertySimpleType.STRING));
+ configDef = new ConfigurationDefinition("bundletest-configdef", "Test Config Def for testing BundleVersion");
+ configDef.put(new PropertyDefinitionSimple("bundletest.property",
+ "Test property for BundleVersion Config Def testing", true, PropertySimpleType.STRING));
bundleFileNames = new HashSet<String>();
- bundleFileNames.add("sample-bundle.war");
+ bundleFileNames.add("bundletest-bundlefile-1");
+ bundleFileNames.add("bundletest-bundlefile-2");
return new RecipeParseResults(configDef, bundleFileNames);
}
commit 966bc00b7d6234614635ca5fd319cb57b8a2f12c
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Wed Mar 3 15:49:43 2010 -0500
add shell command recipe support
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/CommandRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/CommandRecipeCommand.java
new file mode 100644
index 0000000..e5db71d
--- /dev/null
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/CommandRecipeCommand.java
@@ -0,0 +1,56 @@
+/*
+ * 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, 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.bundle.filetemplate.recipe;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Declares that an existing script or shell command is to be invoked.
+ *
+ * @author John Mazzitelli
+ */
+public class CommandRecipeCommand implements RecipeCommand {
+
+ public String getName() {
+ return "command";
+ }
+
+ public void parse(RecipeParser parser, RecipeContext context, String[] args) {
+
+ if (args == null || args.length == 0) {
+ throw new IllegalArgumentException("Missing the command to execute");
+ }
+
+ String exe = args[0];
+ List<String> exeArgs = new ArrayList<String>(args.length - 1);
+ for (int i = 1; i < args.length; i++) {
+ exeArgs.add(args[i]);
+ }
+
+ context.addCommand(exe, exeArgs);
+
+ return;
+ }
+}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
index cb76a80..bc8932f 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
@@ -48,6 +48,7 @@ public class RecipeContext {
private final Set<String> replacementVariables;
private Configuration replacementVariableValues;
private final List<Script> scripts;
+ private final List<Command> commands;
public RecipeContext(String recipe) {
this.recipe = recipe;
@@ -56,6 +57,7 @@ public class RecipeContext {
this.realizedFiles = new HashSet<String>();
this.replacementVariables = new HashSet<String>();
this.scripts = new ArrayList<Script>();
+ this.commands = new ArrayList<Command>();
}
/**
@@ -190,8 +192,8 @@ public class RecipeContext {
}
class Script {
- private final List<String> args;
private final String exe;
+ private final List<String> args;
public Script(String exe, List<String> args) {
this.exe = exe;
@@ -207,10 +209,38 @@ public class RecipeContext {
}
}
+ /**
+ * Adds a command that the recipe wants invoked. This command refers to an existing
+ * executable or shell command.
+ *
+ * @param cmd the main executable that this command wants to execute
+ * @param exeArgs the arguments to pass to the command executable
+ */
+ public void addCommand(String exe, List<String> exeArgs) {
+ this.commands.add(new Command(exe, exeArgs));
+ }
+
+ class Command {
+ private final String exe;
+ private final List<String> args;
+
+ public Command(String exe, List<String> args) {
+ this.exe = exe;
+ this.args = args;
+ }
+
+ public String getExecutable() {
+ return exe;
+ }
+
+ public List<String> getArguments() {
+ return args;
+ }
+ }
+
@Override
public String toString() {
StringBuilder str = new StringBuilder("RecipeContext:\n");
- str.append("Recipe Text:\n").append(getRecipe()).append("\n");
str.append("Deploy Files: ").append(getDeployFiles()).append("\n");
str.append("Replacement Vars: ").append(getReplacementVariables()).append("\n");
@@ -227,6 +257,14 @@ public class RecipeContext {
for (Script script : this.scripts) {
str.append("* ").append(script.getExecutable()).append(" ").append(script.getArguments()).append("\n");
}
+
+ str.append("Commands: ").append("\n");
+ for (Command cmd : this.commands) {
+ str.append("* ").append(cmd.getExecutable()).append(" ").append(cmd.getArguments()).append("\n");
+ }
+
+ str.append("Recipe Text:\n-----------\n").append(getRecipe()).append("\n");
+
return str.toString();
}
}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
index 98f26f6..f22c04c 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
@@ -129,6 +129,7 @@ public class RecipeParser {
HashMap<String, RecipeCommand> commands = new HashMap<String, RecipeCommand>();
RecipeCommand[] knownCommands = new RecipeCommand[] { new ScriptRecipeCommand(), //
+ new CommandRecipeCommand(), //
new FileRecipeCommand(), //
new RealizeRecipeCommand(), //
new DeployRecipeCommand() //
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
index 3682c18..f4cb102 100644
--- a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
@@ -177,6 +177,22 @@ public class ProcessingRecipeContext extends RecipeContext {
}
}
+ @Override
+ public void addCommand(String exe, List<String> exeArgs) {
+ super.addCommand(exe, exeArgs);
+
+ ProcessExecution pe = new ProcessExecution(exe);
+ pe.setArguments(exeArgs);
+ pe.setWaitForCompletion(30 * 60 * 1000L);
+ pe.setCheckExecutableExists(false);
+ pe.setWorkingDirectory(this.baseWorkingDirectory);
+
+ ProcessExecutionResults results = this.systemInfo.executeProcess(pe);
+ if (results.getError() != null) {
+ throw new RuntimeException("Could not execute command [" + pe + "]: " + results, results.getError());
+ }
+ }
+
private void ensureExecutable(File scriptFile) {
boolean success;
diff --git a/modules/plugins/filetemplate-bundle/src/test/java/org/rhq/plugins/filetemplate/ProcessingRecipeContextTest.java b/modules/plugins/filetemplate-bundle/src/test/java/org/rhq/plugins/filetemplate/ProcessingRecipeContextTest.java
index 47b721f..188e127 100644
--- a/modules/plugins/filetemplate-bundle/src/test/java/org/rhq/plugins/filetemplate/ProcessingRecipeContextTest.java
+++ b/modules/plugins/filetemplate-bundle/src/test/java/org/rhq/plugins/filetemplate/ProcessingRecipeContextTest.java
@@ -40,6 +40,7 @@ import org.rhq.bundle.filetemplate.recipe.RecipeContext;
import org.rhq.bundle.filetemplate.recipe.RecipeParser;
import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.pluginapi.util.FileUtils;
+import org.rhq.core.system.OperatingSystemType;
import org.rhq.core.system.SystemInfo;
import org.rhq.core.system.SystemInfoFactory;
import org.rhq.core.util.stream.StreamUtil;
@@ -140,6 +141,24 @@ public class ProcessingRecipeContextTest {
assert echoOutputContent.trim().equals("hello");
}
+ public void testCommandRecipe() throws Exception {
+ File testDir = getTestDir("testcommand");
+ File echoOutput = new File(testDir, "out.txt");
+ echoOutput.getParentFile().mkdirs();
+
+ SystemInfo sysinfo = SystemInfoFactory.createSystemInfo();
+ if (sysinfo.getOperatingSystemType() == OperatingSystemType.WINDOWS) {
+ addRecipeCommand("command cmd /C \"echo helloWorld > '" + echoOutput.getAbsolutePath() + "'\"");
+ } else {
+ addRecipeCommand("command sh -c \"echo helloWorld > '" + echoOutput.getAbsolutePath() + "'\"");
+ }
+
+ RecipeContext context = parseRecipeNow(testDir);
+
+ String echoOutputContent = readFile(echoOutput);
+ assert echoOutputContent.trim().equals("helloWorld");
+ }
+
private ProcessingRecipeContext parseRecipeNow(File testDir) throws Exception {
ProcessingRecipeContext context = createRecipeContext(testDir);
return parseRecipeNow(context);
commit f93ec8ca78fb9c17d031ae85f670286ad6d154df
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Wed Mar 3 21:39:05 2010 +0100
Provide the operation name at the top of the parameters panel.
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java
index c7c8c26..6f39bae 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java
@@ -27,10 +27,8 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.seam.ScopeType;
-import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.Scope;
-import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
@@ -63,25 +61,14 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
private Configuration configuration;
private static final String ALERT_NOTIFICATIONS = "ALERT_NOTIFICATIONS";
+
+
+ private String operationName;
+
public OperationsBackingBean() {
log.info("new " + hashCode());
}
- @Override
- public void internalInit() {
-/* log.info("internalInit");
- try {
- getResId();
- getResourceName();
- obtainOperationIds();
- getOperationId();
- lookupConfiguration();
- }
- catch (Throwable t) {
- t.printStackTrace();
- }*/
- }
-
@Override
public void internalCleanup() {
@@ -107,6 +94,7 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
cleanProperty(alertParameters,OperationsSender.USABLE);
operationIds = new HashMap<String,Integer>(); // Clean out operations dropdown
operationId = null;
+ operationName = null;
}
@@ -122,6 +110,7 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
if (operationId != null ) {
persistProperty(alertParameters, OperationsSender.OPERATION_ID, operationId);
+ getOperationNameFromOperationIds();
lookupConfiguration();
}
@@ -144,8 +133,6 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
// call a SLSB method to get around lazy initialization of configDefs and configTemplates
ConfigurationManagerLocal configurationManager = LookupUtil.getConfigurationManager();
configuration = configurationManager.getConfigurationFromDefaultTemplate(configurationDefinition);
- // Configuration newConfiguration = configuration.deepCopy(false);
- log.info("lookupConfiguration: " + configuration + ", " + configuration.hashCode() );
}
} catch (Exception e) {
e.printStackTrace();
@@ -187,11 +174,9 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
public void setResMode(String resMode) {
this.resMode = resMode;
- log.info("setResMode: " + resMode);
}
public Integer getResId() {
- System.out.println("OperationsBackingBean.getResId");
if (resId==null) {
PropertySimple prop = alertParameters.getSimple(OperationsSender.RESOURCE_ID);
if (prop!=null)
@@ -203,7 +188,6 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
public void setResId(Integer resId) {
this.resId = resId;
- log.info("Set resid " + resId);
if (resId!=null) {
persistProperty(alertParameters,OperationsSender.RESOURCE_ID,resId);
}
@@ -232,15 +216,35 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
PropertySimple prop = alertParameters.getSimple(OperationsSender.OPERATION_ID);
if (prop!=null)
operationId = prop.getIntegerValue();
+
}
+ if(operationIds==null || operationIds.isEmpty())
+ obtainOperationIds();
+ getOperationNameFromOperationIds();
+
return operationId;
}
+ private void getOperationNameFromOperationIds() {
+ for (Map.Entry<String,Integer> ent : operationIds.entrySet()) {
+ if (ent.getValue().equals(operationId))
+ operationName=ent.getKey();
+ }
+ }
+
public void setOperationId(Integer operationId) {
this.operationId = operationId;
}
+ public String getOperationName() {
+ return operationName;
+ }
+
+ public void setOperationName(String operationName) {
+ this.operationName = operationName;
+ }
+
public Map<String, Integer> getOperationIds() {
obtainOperationIds();
@@ -253,7 +257,6 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
}
public ConfigurationDefinition getConfigurationDefinition() {
- System.out.println("OperationsBackingBean.getConfigurationDefinition");
if (configurationDefinition==null)
lookupConfiguration();
@@ -271,7 +274,6 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
public void setConfiguration(Configuration configuration) {
this.configuration = configuration;
- log.info("setC: " + configuration);
}
public String getNullConfigurationDefinitionMessage() {
@@ -294,7 +296,6 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
public void setTokenMode(String tokenMode) {
this.tokenMode = tokenMode;
- log.info("token mode" + tokenMode);
persistProperty(alertParameters, OperationsSender.TOKEN_MODE,tokenMode);
}
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/resources/operations.xhtml b/modules/enterprise/server/plugins/alert-operations/src/main/resources/operations.xhtml
index 98dcada..dc3a917 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/resources/operations.xhtml
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/resources/operations.xhtml
@@ -59,7 +59,7 @@
<h:messages />
<rich:panel rendered="#{not empty operationsBean.operationId}">
<br/>
- Parameters for <h:outputText value=" #{operationsBean.operationId}"/>
+ Parameters for operation '<h:outputText value=" #{operationsBean.operationName}"/>':
<p/>
<h:selectOneMenu id="tokenModeMenu" value="#{operationsBean.tokenMode}">
<f:selectItem itemValue="literal" itemLabel="Literal"/>
commit bd69d0afa634444ad62151d89d3a3f5daf7e4869
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Wed Mar 3 14:29:29 2010 -0500
get the script recipe command to work
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployRequest.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployRequest.java
index 2dd6e6d..741efc3 100644
--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployRequest.java
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployRequest.java
@@ -19,9 +19,12 @@
package org.rhq.core.pluginapi.bundle;
+import java.io.File;
import java.io.Serializable;
+import java.util.Map;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
+import org.rhq.core.domain.content.PackageVersion;
/**
* A request to deploy a bundle.
@@ -31,11 +34,44 @@ import org.rhq.core.domain.bundle.BundleDeployDefinition;
public class BundleDeployRequest implements Serializable {
private static final long serialVersionUID = 1L;
+ private File bundleFilesLocation;
private BundleDeployDefinition bundleDeployDefinition;
- private BundleManagerProvider bundleManager;
+ private BundleManagerProvider bundleManagerProvider;
+ private Map<PackageVersion, File> packageVersionFiles;
+
+ public BundleDeployRequest() {
+ }
+
+ /**
+ * This returns the location where the plugin container has downloaded the bundle files.
+ *
+ * @return the location where the bundle files have been downloaded
+ */
+ public File getBundleFilesLocation() {
+ return this.bundleFilesLocation;
+ }
+
+ public void setBundleFilesLocation(File bundleFilesLocation) {
+ this.bundleFilesLocation = bundleFilesLocation;
+ }
+
+ /**
+ * Maps all the package versions associated with the bundle and the locations
+ * where the package version contents can be found. These will all be located
+ * somewhere under the {@link #getBundleFilesLocation() bundle files location}.
+ *
+ * @return packages and their locations on the local file system
+ */
+ public Map<PackageVersion, File> getPackageVersionFiles() {
+ return this.packageVersionFiles;
+ }
+
+ public void setPackageVersionFiles(Map<PackageVersion, File> packageVersionFiles) {
+ this.packageVersionFiles = packageVersionFiles;
+ }
public BundleDeployDefinition getBundleDeployDefinition() {
- return bundleDeployDefinition;
+ return this.bundleDeployDefinition;
}
public void setBundleDeployDefinition(BundleDeployDefinition bundleDeployDefinition) {
@@ -43,11 +79,11 @@ public class BundleDeployRequest implements Serializable {
}
public BundleManagerProvider getBundleManagerProvider() {
- return bundleManager;
+ return this.bundleManagerProvider;
}
public void setBundleManagerProvider(BundleManagerProvider provider) {
- this.bundleManager = provider;
+ this.bundleManagerProvider = provider;
}
}
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 5db906f..4475be4 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
@@ -22,8 +22,13 @@
*/
package org.rhq.core.pc.bundle;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.OutputStream;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
@@ -45,12 +50,14 @@ import org.rhq.core.pc.PluginContainer;
import org.rhq.core.pc.PluginContainerConfiguration;
import org.rhq.core.pc.agent.AgentService;
import org.rhq.core.pc.inventory.InventoryManager;
+import org.rhq.core.pc.inventory.ResourceContainer;
import org.rhq.core.pc.util.ComponentUtil;
import org.rhq.core.pc.util.FacetLockType;
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.util.MessageDigestGenerator;
/**
* Manages the bundle subsystem, which allows bundles of content to be installed.
@@ -78,15 +85,26 @@ public class BundleManager extends AgentService implements BundleAgentService, B
public void shutdown() {
}
+ public List<PackageVersion> getAllBundleVersionPackageVersions(BundleVersion bundleVersion) throws Exception {
+ int bvId = bundleVersion.getId();
+ List<PackageVersion> pvs = getBundleServerService().getAllBundleVersionPackageVersions(bvId);
+ return pvs;
+ }
+
+ public long getFileContent(PackageVersion packageVersion, OutputStream outputStream) throws Exception {
+ long size = getBundleServerService().downloadPackageBits(packageVersion, outputStream);
+ return size;
+ }
+
public BundleScheduleResponse schedule(BundleScheduleRequest request) {
BundleScheduleResponse response = new BundleScheduleResponse();
try {
- BundleDeployDefinition bundleDef = request.getBundleDeployDefinition();
+ BundleDeployDefinition bundleDeployDef = request.getBundleDeployDefinition();
// find the resource that will handle the bundle processing
InventoryManager im = PluginContainer.getInstance().getInventoryManager();
- BundleType bundleType = bundleDef.getBundleVersion().getBundle().getBundleType();
+ BundleType bundleType = bundleDeployDef.getBundleVersion().getBundle().getBundleType();
ResourceType resourceType = bundleType.getResourceType();
Set<Resource> resources = im.getResourcesWithType(resourceType);
if (resources.isEmpty()) {
@@ -94,6 +112,12 @@ public class BundleManager extends AgentService implements BundleAgentService, B
}
int bundleHandlerResourceId = resources.iterator().next().getId();
+ // pull down the bundle files that the plugin will need in order to process the bundle
+ ResourceContainer resourceContainer = im.getResourceContainer(bundleHandlerResourceId);
+ File pluginTmpDir = resourceContainer.getResourceContext().getTemporaryDirectory();
+ File bundleFilesDir = new File(pluginTmpDir, "" + bundleDeployDef.getBundleVersion().getId());
+ Map<PackageVersion, File> downloadedFiles = downloadBundleFiles(bundleDeployDef, bundleFilesDir);
+
// get the bundle facet object that will process the bundle
int facetMethodTimeout = 4 * 60 * 60 * 1000; // 4 hours is given to the bundle plugin to do its thing
BundleFacet bundlePluginComponent = getBundleFacet(bundleHandlerResourceId, facetMethodTimeout);
@@ -102,6 +126,8 @@ public class BundleManager extends AgentService implements BundleAgentService, B
BundleDeployRequest deployRequest = new BundleDeployRequest();
deployRequest.setBundleManagerProvider(this);
deployRequest.setBundleDeployDefinition(request.getBundleDeployDefinition());
+ deployRequest.setBundleFilesLocation(bundleFilesDir);
+ deployRequest.setPackageVersionFiles(downloadedFiles);
BundleDeployResult result = bundlePluginComponent.deployBundle(deployRequest);
if (!result.isSuccess()) {
response.setErrorMessage(result.getErrorMessage());
@@ -114,15 +140,91 @@ public class BundleManager extends AgentService implements BundleAgentService, B
return response;
}
- public List<PackageVersion> getAllBundleVersionPackageVersions(BundleVersion bundleVersion) throws Exception {
- int bvId = bundleVersion.getId();
- List<PackageVersion> pvs = getBundleServerService().getAllBundleVersionPackageVersions(bvId);
- return pvs;
+ /**
+ * Downloads the bundle's files into the bundle plugin's tmp directory and returns that tmp directory.
+ *
+ * @param bundleDeployDef bundle deployment information, including what bundle files need to be downloaded
+ * @param downloadDir location where the bundle files should be downloaded
+ * @return map of the package versions to their files that were downloaded
+ * @throws Exception
+ */
+ private Map<PackageVersion, File> downloadBundleFiles(BundleDeployDefinition bundleDeployDef, File downloadDir)
+ throws Exception {
+
+ BundleVersion bundleVersion = bundleDeployDef.getBundleVersion();
+
+ // download all the bundle files to the bundle plugin's tmp directory
+ Map<PackageVersion, File> packageVersionFiles = new HashMap<PackageVersion, File>();
+ List<PackageVersion> packageVersions = getAllBundleVersionPackageVersions(bundleVersion);
+ for (PackageVersion packageVersion : packageVersions) {
+ File packageFile = new File(downloadDir, packageVersion.getFileName());
+
+ try {
+ verifyHash(packageVersion, packageFile);
+ } catch (Exception e) {
+ // file either doesn't exist or it hash doesn't match, download a new copy
+ packageFile.getParentFile().mkdirs();
+ FileOutputStream fos = new FileOutputStream(packageFile);
+ try {
+ long size = getFileContent(packageVersion, fos);
+ if (packageVersion.getFileSize() != null && size != packageVersion.getFileSize().longValue()) {
+ log.warn("Downloaded bundle file [" + packageVersion + "] but its size was [" + size
+ + "] when it was expected to be [" + packageVersion.getFileSize() + "].");
+ }
+ } finally {
+ fos.close();
+ }
+
+ // now try to verify it again, if this throws an exception, that is very bad and we need to abort
+ verifyHash(packageVersion, packageFile);
+ }
+
+ packageVersionFiles.put(packageVersion, packageFile);
+ }
+
+ return packageVersionFiles;
}
- public long getFileContent(PackageVersion packageVersion, OutputStream outputStream) throws Exception {
- long size = getBundleServerService().downloadPackageBits(packageVersion, outputStream);
- return size;
+ /**
+ * Checks to see if the package file's hash matches that of the given package version.
+ * If the file doesn't exist or the hash doesn't match, an exception is thrown.
+ * This method returns normally if the hash matches the file.
+ * If there is no known hash in the package version, this method returns normally.
+ *
+ * @param packageVersion contains the hash that is expected
+ * @param packageFile the local file whose hash is to be checked
+ * @throws Exception if the file does not match the hash or the file doesn't exist
+ */
+ private void verifyHash(PackageVersion packageVersion, File packageFile) throws Exception {
+ if (!packageFile.exists()) {
+ throw new Exception("Package version [" + packageVersion + "] does not exist, cannot check hash");
+ }
+
+ if (packageVersion.getMD5() != null) {
+ String realMD5 = MessageDigestGenerator.getDigestString(packageFile);
+ if (!packageVersion.getMD5().equals(realMD5)) {
+ throw new Exception("Package version [" + packageVersion + "] failed MD5 check. expected=["
+ + packageVersion.getMD5() + "], actual=[" + realMD5 + "]");
+ }
+ } else if (packageVersion.getSHA256() != null) {
+ FileInputStream is = new FileInputStream(packageFile);
+ try {
+ MessageDigestGenerator gen = new MessageDigestGenerator("SHA256");
+ gen.add(is);
+ String realSHA256 = gen.getDigestString();
+ if (!packageVersion.getSHA256().equals(realSHA256)) {
+ throw new Exception("Package version [" + packageVersion + "] failed SHA256 check. expected=["
+ + packageVersion.getSHA256() + "], actual=[" + realSHA256 + "]");
+ }
+ } finally {
+ is.close();
+ }
+
+ } else {
+ log.debug("Package version [" + packageVersion + "] has no MD5/SHA256 hash - not verifying it");
+ }
+
+ return;
}
/**
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
index cee69db..9536665 100644
--- a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
@@ -18,28 +18,18 @@
*/
package org.rhq.plugins.filetemplate;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rhq.bundle.filetemplate.recipe.RecipeParser;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleVersion;
-import org.rhq.core.domain.content.PackageVersion;
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.util.MessageDigestGenerator;
/**
* @author John Mazzitelli
@@ -68,42 +58,12 @@ public class FileTemplateBundlePluginServerComponent implements ResourceComponen
BundleDeployDefinition bundleDeployDef = request.getBundleDeployDefinition();
BundleVersion bundleVersion = bundleDeployDef.getBundleVersion();
- // download all the bundle files to our tmp directory
- Map<PackageVersion, File> packageVersionFiles = new HashMap<PackageVersion, File>();
- File tmpDir = new File(this.resourceContext.getTemporaryDirectory(), "" + bundleVersion.getId());
- BundleManagerProvider bundleManager = request.getBundleManagerProvider();
- List<PackageVersion> packageVersions = bundleManager.getAllBundleVersionPackageVersions(bundleVersion);
- for (PackageVersion packageVersion : packageVersions) {
- File packageFile = new File(tmpDir, packageVersion.getFileName());
-
- try {
- verifyHash(packageVersion, packageFile);
- } catch (Exception e) {
- // file either doesn't exist or it hash doesn't match, download a new copy
- packageFile.getParentFile().mkdirs();
- FileOutputStream fos = new FileOutputStream(packageFile);
- try {
- long size = bundleManager.getFileContent(packageVersion, fos);
- if (packageVersion.getFileSize() != null && size != packageVersion.getFileSize().longValue()) {
- log.warn("Downloaded bundle file [" + packageVersion + "] but its size was [" + size
- + "] when it was expected to be [" + packageVersion.getFileSize() + "].");
- }
- } finally {
- fos.close();
- }
-
- // now try to verify it again, if this throws an exception, that is very bad and we need to abort
- verifyHash(packageVersion, packageFile);
- }
-
- packageVersionFiles.put(packageVersion, packageFile);
- }
-
// process the recipe
String recipe = bundleVersion.getRecipe();
RecipeParser parser = new RecipeParser();
- ProcessingRecipeContext recipeContext = new ProcessingRecipeContext(recipe, packageVersionFiles,
- this.resourceContext.getSystemInformation(), tmpDir.getAbsolutePath());
+ ProcessingRecipeContext recipeContext = new ProcessingRecipeContext(recipe, request
+ .getPackageVersionFiles(), this.resourceContext.getSystemInformation(), request
+ .getBundleFilesLocation().getAbsolutePath());
recipeContext.setReplacementVariableValues(bundleDeployDef.getConfiguration());
parser.setReplaceReplacementVariables(true);
parser.parseRecipe(recipeContext);
@@ -114,46 +74,4 @@ public class FileTemplateBundlePluginServerComponent implements ResourceComponen
}
return result;
}
-
- /**
- * Checks to see if the package file's hash matches that of the given package version.
- * If the file doesn't exist or the hash doesn't match, an exception is thrown.
- * This method returns normally if the hash matches the file.
- * If there is no known hash in the package version, this method returns normally.
- *
- * @param packageVersion contains the hash that is expected
- * @param packageFile the local file whose hash is to be checked
- * @throws Exception if the file does not match the hash or the file doesn't exist
- */
- private void verifyHash(PackageVersion packageVersion, File packageFile) throws Exception {
- if (!packageFile.exists()) {
- throw new Exception("Package version [" + packageVersion + "] does not exist, cannot check hash");
- }
-
- if (packageVersion.getMD5() != null) {
- String realMD5 = MessageDigestGenerator.getDigestString(packageFile);
- if (!packageVersion.getMD5().equals(realMD5)) {
- throw new Exception("Package version [" + packageVersion + "] failed MD5 check. expected=["
- + packageVersion.getMD5() + "], actual=[" + realMD5 + "]");
- }
- } else if (packageVersion.getSHA256() != null) {
- FileInputStream is = new FileInputStream(packageFile);
- try {
- MessageDigestGenerator gen = new MessageDigestGenerator("SHA256");
- gen.add(is);
- String realSHA256 = gen.getDigestString();
- if (!packageVersion.getSHA256().equals(realSHA256)) {
- throw new Exception("Package version [" + packageVersion + "] failed SHA256 check. expected=["
- + packageVersion.getSHA256() + "], actual=[" + realSHA256 + "]");
- }
- } finally {
- is.close();
- }
-
- } else {
- log.debug("Package version [" + packageVersion + "] has no MD5/SHA256 hash - not verifying it");
- }
-
- return;
- }
}
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
index 26199d3..3682c18 100644
--- a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
@@ -23,6 +23,7 @@ import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -31,6 +32,7 @@ import java.util.Set;
import org.rhq.bundle.filetemplate.recipe.RecipeContext;
import org.rhq.bundle.filetemplate.recipe.RecipeParser;
import org.rhq.core.domain.content.PackageVersion;
+import org.rhq.core.system.OperatingSystemType;
import org.rhq.core.system.ProcessExecution;
import org.rhq.core.system.ProcessExecutionResults;
import org.rhq.core.system.SystemInfo;
@@ -162,6 +164,8 @@ public class ProcessingRecipeContext extends RecipeContext {
File scriptFile = new File(this.baseWorkingDirectory, exe);
+ ensureExecutable(scriptFile);
+
ProcessExecution pe = new ProcessExecution(scriptFile.getAbsolutePath());
pe.setArguments(exeArgs);
pe.setWaitForCompletion(30 * 60 * 1000L);
@@ -173,6 +177,35 @@ public class ProcessingRecipeContext extends RecipeContext {
}
}
+ private void ensureExecutable(File scriptFile) {
+ boolean success;
+
+ try {
+ Method m = File.class.getMethod("setExecutable", Boolean.TYPE, Boolean.TYPE);
+ Boolean r = (Boolean) m.invoke(scriptFile, Boolean.TRUE, Boolean.TRUE);
+ success = r.booleanValue();
+ } catch (Exception e) {
+ // Oh, if only we'd just stop dilly-dallying and move to JDK6 already
+ if (this.systemInfo.getOperatingSystemType() != OperatingSystemType.WINDOWS) {
+ ProcessExecution pe = new ProcessExecution("chmod");
+ pe.setArguments(new String[] { "u+x", scriptFile.getAbsolutePath() });
+ pe.setWaitForCompletion(30000L);
+ pe.setCheckExecutableExists(false);
+ pe.setWorkingDirectory(scriptFile.getParent());
+ ProcessExecutionResults chmodResults = this.systemInfo.executeProcess(pe);
+ success = (chmodResults.getExitCode() != null && chmodResults.getExitCode().intValue() == 0);
+ } else {
+ success = true; // assume we can execute it on windows
+ }
+ }
+
+ if (!success) {
+ throw new RuntimeException("Cannot ensure that script [" + scriptFile + "] is executable");
+ }
+
+ return;
+ }
+
private ProcessExecution getUnzipExecution(File file, String directory) {
String exe;
List<String> args = null;
diff --git a/modules/plugins/filetemplate-bundle/src/test/java/org/rhq/plugins/filetemplate/ProcessingRecipeContextTest.java b/modules/plugins/filetemplate-bundle/src/test/java/org/rhq/plugins/filetemplate/ProcessingRecipeContextTest.java
index 1099481..47b721f 100644
--- a/modules/plugins/filetemplate-bundle/src/test/java/org/rhq/plugins/filetemplate/ProcessingRecipeContextTest.java
+++ b/modules/plugins/filetemplate-bundle/src/test/java/org/rhq/plugins/filetemplate/ProcessingRecipeContextTest.java
@@ -122,18 +122,22 @@ public class ProcessingRecipeContextTest {
assert zippedFileContent.equals("zipped file content");
}
- @Test(enabled = false)
public void testScriptRecipe() throws Exception {
File testDir = getTestDir("testscript");
+ File testOutDir = getTestDir("testscript-out");
+ File echoOutput = new File(testOutDir, "out.txt");
+ echoOutput.getParentFile().mkdirs();
+ File script = writeFile("echo hello > \"" + echoOutput.getAbsolutePath() + "\"\n", testDir, "bin/test.sh");
- addRecipeCommand("script echo hello");
+ addRecipeCommand("script bin/test.sh");
RecipeContext context = parseRecipeNow(testDir);
Set<String> scripts = context.getScriptFiles();
assert scripts.size() == 1 : scripts;
- assert scripts.contains("run-me.sh") : scripts;
- assert scripts.contains("lots-o-params.sh") : scripts;
+ assert scripts.contains("bin/test.sh") : scripts;
+ String echoOutputContent = readFile(echoOutput);
+ assert echoOutputContent.trim().equals("hello");
}
private ProcessingRecipeContext parseRecipeNow(File testDir) throws Exception {
commit 062ce6a3fdeb4613a5c8e5dfb654d6b314718b10
Merge: 3a9c7df... 1dd05b6...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Mar 3 12:38:10 2010 -0500
Merge branch 'bundle' into bundle-jay
commit 3a9c7dfc0edc71be7c00f67db4d65737e5de3614
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Mar 3 12:37:58 2010 -0500
git forced commit
diff --git a/etc/eclipse-tools/RHQ Remote Debugging - Test.launch b/etc/eclipse-tools/RHQ Remote Debugging - Test.launch
index 821c398..e4e88fc 100644
--- a/etc/eclipse-tools/RHQ Remote Debugging - Test.launch
+++ b/etc/eclipse-tools/RHQ Remote Debugging - Test.launch
@@ -1,19 +1,19 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<launchConfiguration type="org.eclipse.jdt.launching.remoteJavaApplication">
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/rhq"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
-<listEntry value="4"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
-<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
-</listAttribute>
-<booleanAttribute key="org.eclipse.jdt.launching.ALLOW_TERMINATE" value="true"/>
-<mapAttribute key="org.eclipse.jdt.launching.CONNECT_MAP">
-<mapEntry key="port" value="8797"/>
-<mapEntry key="hostname" value="localhost"/>
-</mapAttribute>
-<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="rhq"/>
-<stringAttribute key="org.eclipse.jdt.launching.VM_CONNECTOR_ID" value="org.eclipse.jdt.launching.socketAttachConnector"/>
-</launchConfiguration>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.jdt.launching.remoteJavaApplication">
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+<listEntry value="/rhq"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+<listEntry value="4"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
+<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
+</listAttribute>
+<booleanAttribute key="org.eclipse.jdt.launching.ALLOW_TERMINATE" value="true"/>
+<mapAttribute key="org.eclipse.jdt.launching.CONNECT_MAP">
+<mapEntry key="port" value="8797"/>
+<mapEntry key="hostname" value="localhost"/>
+</mapAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="rhq"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_CONNECTOR_ID" value="org.eclipse.jdt.launching.socketAttachConnector"/>
+</launchConfiguration>
commit 1dd05b6d50a662d89c6aaf62c5e68a060df2bf5d
Merge: 95178af... f7bb4c6...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Mar 3 12:30:56 2010 -0500
Merge branch 'bundle' of ssh://git.fedorahosted.org/git/rhq/rhq into bundle
commit 95178af531e8185e90062e7122908ed4cc7f6597
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Mar 3 12:30:03 2010 -0500
git forced LT commit
diff --git a/etc/eclipse-tools/RHQ Remote Debugging - Test.launch b/etc/eclipse-tools/RHQ Remote Debugging - Test.launch
index 821c398..e4e88fc 100644
--- a/etc/eclipse-tools/RHQ Remote Debugging - Test.launch
+++ b/etc/eclipse-tools/RHQ Remote Debugging - Test.launch
@@ -1,19 +1,19 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<launchConfiguration type="org.eclipse.jdt.launching.remoteJavaApplication">
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/rhq"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
-<listEntry value="4"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
-<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
-</listAttribute>
-<booleanAttribute key="org.eclipse.jdt.launching.ALLOW_TERMINATE" value="true"/>
-<mapAttribute key="org.eclipse.jdt.launching.CONNECT_MAP">
-<mapEntry key="port" value="8797"/>
-<mapEntry key="hostname" value="localhost"/>
-</mapAttribute>
-<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="rhq"/>
-<stringAttribute key="org.eclipse.jdt.launching.VM_CONNECTOR_ID" value="org.eclipse.jdt.launching.socketAttachConnector"/>
-</launchConfiguration>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.jdt.launching.remoteJavaApplication">
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+<listEntry value="/rhq"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+<listEntry value="4"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
+<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
+</listAttribute>
+<booleanAttribute key="org.eclipse.jdt.launching.ALLOW_TERMINATE" value="true"/>
+<mapAttribute key="org.eclipse.jdt.launching.CONNECT_MAP">
+<mapEntry key="port" value="8797"/>
+<mapEntry key="hostname" value="localhost"/>
+</mapAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="rhq"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_CONNECTOR_ID" value="org.eclipse.jdt.launching.socketAttachConnector"/>
+</launchConfiguration>
commit 7104751dfca528c2cd03fefb4ad78427c2919220
Merge: a310714... 845e3c0...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Mar 3 12:29:38 2010 -0500
Merge branch 'bundle-jay' into bundle
commit 845e3c0f4782ff87ca0ecdc9d1d252841b3b5fe1
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Mar 3 12:29:25 2010 -0500
checkin of stable code
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleFile.java b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleFile.java
index dfd1b45..fcc7389 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleFile.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleFile.java
@@ -52,7 +52,7 @@ import org.rhq.core.domain.content.PackageVersion;
@NamedQuery(name = BundleFile.QUERY_FIND_ALL, query = "SELECT bf FROM BundleFile bf"), //
@NamedQuery(name = BundleFile.QUERY_FIND_BY_BUNDLE_VERSION_ID, query = "SELECT bf FROM BundleFile bf WHERE bf.bundleVersion.id = :id") //
})
-@SequenceGenerator(name = "SEQ", sequenceName = "RHQ_BUNDLE_CONFIG_ID_SEQ")
+@SequenceGenerator(name = "SEQ", sequenceName = "RHQ_BUNDLE_FILE_ID_SEQ")
@Table(name = "RHQ_BUNDLE_FILE")
@XmlAccessorType(XmlAccessType.FIELD)
public class BundleFile implements Serializable {
@@ -72,7 +72,7 @@ public class BundleFile implements Serializable {
@JoinColumn(name = "PACKAGE_ID", referencedColumnName = "ID", nullable = true)
@ManyToOne(fetch = FetchType.LAZY)
- private Package pkg;
+ private Package generalPackage;
@JoinColumn(name = "PACKAGE_VERSION_ID", referencedColumnName = "ID", nullable = false)
@ManyToOne(fetch = FetchType.LAZY)
@@ -99,11 +99,11 @@ public class BundleFile implements Serializable {
}
public Package getPackage() {
- return pkg;
+ return generalPackage;
}
public void setPackage(Package pkg) {
- this.pkg = pkg;
+ this.generalPackage = pkg;
}
public PackageVersion getPackageVersion() {
@@ -124,7 +124,7 @@ public class BundleFile implements Serializable {
final int prime = 31;
int result = 1;
result = prime * result + ((bundleVersion == null) ? 0 : bundleVersion.hashCode());
- result = prime * result + ((pkg == null) ? 0 : pkg.hashCode());
+ result = prime * result + ((generalPackage == null) ? 0 : generalPackage.hashCode());
result = prime * result + ((packageVersion == null) ? 0 : packageVersion.hashCode());
return result;
}
@@ -148,11 +148,11 @@ public class BundleFile implements Serializable {
return false;
}
- if (pkg == null) {
- if (other.pkg != null) {
+ if (generalPackage == null) {
+ if (other.generalPackage != null) {
return false;
}
- } else if (!pkg.equals(other.pkg)) {
+ } else if (!generalPackage.equals(other.generalPackage)) {
return false;
}
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceType.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceType.java
index f4582d0..69e8175 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceType.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceType.java
@@ -188,7 +188,7 @@ import org.rhq.core.domain.util.serial.ExternalizableStrategy;
+ "GROUP BY rt.name " //
+ " HAVING COUNT(rt.name) > 1"), //
@NamedQuery(name = ResourceType.QUERY_DYNAMIC_CONFIG_WITH_PLUGIN, query = "" //
- + "SELECT rt.plugin || ' - ' || rt.name, rt.plugin || '-' || rt.name FROM ResourceType rt" ) //
+ + "SELECT rt.plugin || ' - ' || rt.name, rt.plugin || '-' || rt.name FROM ResourceType rt") //
})
@NamedNativeQueries( {
// TODO: Add authz conditions to the below query.
@@ -236,14 +236,14 @@ import org.rhq.core.domain.util.serial.ExternalizableStrategy;
+ "WHERE rtp2.resource_type_id = crt2.id) " + "AND crt2.category = ? " +
// "ORDER BY crt2.name" +
")) ORDER BY name", resultSetMapping = ResourceType.MAPPING_FIND_CHILDREN_BY_CATEGORY) //
- })
+})
@SqlResultSetMapping(name = ResourceType.MAPPING_FIND_CHILDREN_BY_CATEGORY, entities = { @EntityResult(entityClass = ResourceType.class) })
// @Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
public class ResourceType implements Externalizable, Comparable<ResourceType> {
private static final long serialVersionUID = 2L;
public static final String TABLE_NAME = "RHQ_RESOURCE_TYPE";
-
+
public static final ResourceType ANY_PLATFORM_TYPE = null;
public static final String QUERY_FIND_BY_NAME = "ResourceType.findByName";
@@ -379,7 +379,7 @@ public class ResourceType implements Externalizable, Comparable<ResourceType> {
@OneToMany(mappedBy = "resourceType", cascade = CascadeType.ALL)
private Set<ProductVersion> productVersions;
- @OneToOne(mappedBy = "resourceType", fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE }, optional = true)
+ @OneToOne(mappedBy = "resourceType", fetch = FetchType.LAZY, cascade = CascadeType.ALL, optional = true)
private BundleType bundleType;
@Transient
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java
index ba53759..d9b77af 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java
@@ -19,12 +19,9 @@
package org.rhq.enterprise.server.bundle;
-import java.util.HashSet;
import java.util.Set;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
-import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
-import org.rhq.core.domain.configuration.definition.PropertySimpleType;
/**
* This class is general to all Bundle handling server side plugins. It is returned by the SSP when parsing
@@ -46,14 +43,6 @@ public class RecipeParseResults {
}
public ConfigurationDefinition getConfigDef() {
-
- // stub out a test ConfigDef here until we actual parse the recipe
- System.out.println("!!!!!! REMOVE THIS TEST CODE !!!!!!!!");
- configDef = new ConfigurationDefinition("SampleBundle", "Stubbed ConfigDef for Sample Bundle");
- configDef.put(new PropertyDefinitionSimple("sample.bundle.deploy.directory",
- "Stubbed Property for deploy directory (must already exist on target platform)", true,
- PropertySimpleType.STRING));
-
return configDef;
}
@@ -62,12 +51,6 @@ public class RecipeParseResults {
}
public Set<String> getBundleFileNames() {
- // stub out a test set of BundleFiles here until we actual parse the recipe. For now lets just deploy
- // a war file into an existing app server dir.
- System.out.println("!!!!!! REMOVE THIS TEST CODE !!!!!!!!");
- bundleFileNames = new HashSet<String>();
- bundleFileNames.add("sample-bundle.war");
-
return bundleFileNames;
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
index 1ca01c8..24c6dae 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
@@ -36,7 +36,9 @@ import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleFile;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageType;
+import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.content.Repo;
import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleVersionCriteria;
@@ -54,9 +56,9 @@ import org.rhq.enterprise.server.util.LookupUtil;
@Test
public class BundleManagerBeanTest extends AbstractEJB3Test {
- private static final String TEST_PREFIX = "bundletest";
+ private static final boolean TESTS_ENABLED = true;
- private static final boolean ENABLED = true;
+ private static final String TEST_PREFIX = "bundletest";
private BundleManagerLocal bundleManager;
@@ -65,7 +67,8 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
@BeforeMethod
public void beforeMethod() {
- super.startTest();
+ // try and clean up any junk that may be lying around from a failed run
+ cleanupDatabase();
this.ps = new TestBundleServerPluginService();
prepareCustomServerPluginService(this.ps);
@@ -76,6 +79,13 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
@AfterMethod(alwaysRun = true)
public void afterMethod() throws Exception {
+ cleanupDatabase();
+
+ unprepareServerPluginService();
+ this.ps = null;
+ }
+
+ private void cleanupDatabase() {
EntityManager em = null;
try {
@@ -86,42 +96,63 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
List doomed;
// clean up any tests that don't already clean up after themselves
- q = em.createQuery("SELECT bv FROM BundleVersion bv WHERE bv.bundle.name LIKE '" + TEST_PREFIX + "%'");
+
+ // remove bundleversions which cascade remove bundlefiles and bundledeploydefs
+ q = em.createQuery("SELECT bv FROM BundleVersion bv WHERE bv.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
for (Object removeMe : doomed) {
em.remove(em.getReference(BundleVersion.class, ((BundleVersion) removeMe).getId()));
}
-
+ // remove any orphaned bfs
+ q = em.createQuery("SELECT bf FROM BundleFile bf WHERE bf.generalPackage.name LIKE '" + TEST_PREFIX + "%'");
+ doomed = q.getResultList();
+ for (Object removeMe : doomed) {
+ em.remove(em.getReference(BundleFile.class, ((BundleFile) removeMe).getId()));
+ }
+ // remove packages which cascade remove packageversions
+ q = em.createQuery("SELECT p FROM Package p WHERE p.name LIKE '" + TEST_PREFIX + "%'");
+ doomed = q.getResultList();
+ for (Object removeMe : doomed) {
+ em.remove(em.getReference(Package.class, ((Package) removeMe).getId()));
+ }
+ // remove any orphaned pvs
+ q = em.createQuery("SELECT pv FROM PackageVersion pv WHERE pv.generalPackage.name LIKE '" + TEST_PREFIX
+ + "%'");
+ doomed = q.getResultList();
+ for (Object removeMe : doomed) {
+ em.remove(em.getReference(PackageVersion.class, ((PackageVersion) removeMe).getId()));
+ }
+ // remove bundles which cascade remove repos
q = em.createQuery("SELECT b FROM Bundle b WHERE b.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
for (Object removeMe : doomed) {
em.remove(em.getReference(Bundle.class, ((Bundle) removeMe).getId()));
}
-
+ // remove any orphaned repos
q = em.createQuery("SELECT r FROM Repo r WHERE r.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
for (Object removeMe : doomed) {
em.remove(em.getReference(Repo.class, ((Repo) removeMe).getId()));
}
-
+ // remove ResourceTypes which cascade remove BundleTypes and PackageTypes
+ q = em.createQuery("SELECT rt FROM ResourceType rt WHERE rt.name LIKE '" + TEST_PREFIX + "%'");
+ doomed = q.getResultList();
+ for (Object removeMe : doomed) {
+ em.remove(em.getReference(ResourceType.class, ((ResourceType) removeMe).getId()));
+ }
+ // remove any orphaned BundleTypes
q = em.createQuery("SELECT bt FROM BundleType bt WHERE bt.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
for (Object removeMe : doomed) {
em.remove(em.getReference(BundleType.class, ((BundleType) removeMe).getId()));
}
-
+ // remove any orphaned packagetypes
q = em.createQuery("SELECT pt FROM PackageType pt WHERE pt.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
for (Object removeMe : doomed) {
em.remove(em.getReference(PackageType.class, ((PackageType) removeMe).getId()));
}
- q = em.createQuery("SELECT rt FROM ResourceType rt WHERE rt.name LIKE '" + TEST_PREFIX + "%'");
- doomed = q.getResultList();
- for (Object removeMe : doomed) {
- em.remove(em.getReference(ResourceType.class, ((ResourceType) removeMe).getId()));
- }
-
getTransactionManager().commit();
em.close();
em = null;
@@ -136,14 +167,9 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
em.close();
}
}
-
- unprepareServerPluginService();
- this.ps = null;
-
- super.endTest();
}
- @Test(enabled = ENABLED)
+ @Test(enabled = TESTS_ENABLED)
public void testGetBundleTypes() throws Exception {
BundleType bt1 = createBundleType("one");
BundleType bt2 = createBundleType("two");
@@ -159,13 +185,13 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
assert btNames.contains(bt2.getName());
}
- @Test(enabled = ENABLED)
+ @Test(enabled = TESTS_ENABLED)
public void testCreateBundle() throws Exception {
Bundle b1 = createBundle("one");
assertNotNull(b1);
}
- @Test(enabled = ENABLED)
+ @Test(enabled = TESTS_ENABLED)
public void testCreateBundleVersion() throws Exception {
Bundle b1 = createBundle("one");
assertNotNull(b1);
@@ -177,7 +203,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
assertEquals("1.1", bv2.getVersion());
}
- @Test(enabled = ENABLED)
+ @Test(enabled = TESTS_ENABLED)
public void testAddBundleFiles() throws Exception {
Bundle b1 = createBundle("one");
assertNotNull(b1);
@@ -189,7 +215,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
+ "-bundlefile-2", "1.0", null, "Test Bundle File # 2".getBytes(), false);
}
- @Test(enabled = ENABLED)
+ @Test(enabled = TESTS_ENABLED)
public void testfindBundlesByCriteria() throws Exception {
Bundle b1 = createBundle("one");
Bundle b2 = createBundle("two");
@@ -246,7 +272,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
assertEquals(b.getName(), r.getName());
}
- @Test(enabled = ENABLED)
+ @Test(enabled = TESTS_ENABLED)
public void testfindBundleVersionsByCriteria() throws Exception {
Bundle b1 = createBundle("one");
BundleVersion bv1 = createBundleVersion(b1.getName(), "1.0", b1);
@@ -331,7 +357,8 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
}
private PackageType createPackageType(String name, ResourceType rt) throws Exception {
- final String fullName = TEST_PREFIX + "-packagetype-" + name;
+ // the package type is named the same as the bundle type
+ final String fullName = TEST_PREFIX + "-type-" + name;
PackageType pt = new PackageType(fullName, rt);
TransactionManager txMgr = getTransactionManager();
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 64bd5af..dc43f97 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
@@ -22,11 +22,15 @@ import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
+import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
+import org.rhq.core.domain.configuration.definition.PropertySimpleType;
import org.rhq.core.domain.plugin.PluginKey;
import org.rhq.core.domain.plugin.PluginStatusType;
import org.rhq.core.domain.plugin.ServerPlugin;
@@ -40,6 +44,7 @@ import org.rhq.enterprise.server.plugin.pc.ServerPluginManager;
import org.rhq.enterprise.server.plugin.pc.ServerPluginService;
import org.rhq.enterprise.server.plugin.pc.ServerPluginType;
import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginFacet;
import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginManager;
import org.rhq.enterprise.server.xmlschema.ServerPluginDescriptorMetadataParser;
import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType;
@@ -165,5 +170,33 @@ public class TestBundleServerPluginService extends ServerPluginService implement
components.put(environment.getPluginKey().getPluginName(), component);
return component;
}
+
+ @Override
+ public BundleServerPluginFacet getBundleServerPluginFacet(String bundleTypeName) {
+
+ return new TestBundlePluginComponent();
+ }
+ }
+
+ class TestBundlePluginComponent implements BundleServerPluginFacet {
+
+ public TestBundlePluginComponent() {
+ };
+
+ public RecipeParseResults parseRecipe(String recipe) throws Exception {
+
+ ConfigurationDefinition configDef;
+ Set<String> bundleFileNames;
+
+ configDef = new ConfigurationDefinition("SampleBundle", "Stubbed ConfigDef for Sample Bundle");
+ configDef.put(new PropertyDefinitionSimple("sample.bundle.deploy.directory",
+ "Stubbed Property for deploy directory (must already exist on target platform)", true,
+ PropertySimpleType.STRING));
+
+ bundleFileNames = new HashSet<String>();
+ bundleFileNames.add("sample-bundle.war");
+
+ return new RecipeParseResults(configDef, bundleFileNames);
+ }
}
}
\ No newline at end of file
commit a310714100956e5a1c6cd9fb452f5c94cdba35d5
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Mar 3 12:23:11 2010 -0500
Back to steady state - tests passing
notable changes:
- fixed sequence decl for BundleFile and changed pkg field to generalPackage for consistency
- took out test stub code from RecipeParseResults
- added test impl of BundleServerPluginFacet
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleFile.java b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleFile.java
index dfd1b45..fcc7389 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleFile.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleFile.java
@@ -52,7 +52,7 @@ import org.rhq.core.domain.content.PackageVersion;
@NamedQuery(name = BundleFile.QUERY_FIND_ALL, query = "SELECT bf FROM BundleFile bf"), //
@NamedQuery(name = BundleFile.QUERY_FIND_BY_BUNDLE_VERSION_ID, query = "SELECT bf FROM BundleFile bf WHERE bf.bundleVersion.id = :id") //
})
-@SequenceGenerator(name = "SEQ", sequenceName = "RHQ_BUNDLE_CONFIG_ID_SEQ")
+@SequenceGenerator(name = "SEQ", sequenceName = "RHQ_BUNDLE_FILE_ID_SEQ")
@Table(name = "RHQ_BUNDLE_FILE")
@XmlAccessorType(XmlAccessType.FIELD)
public class BundleFile implements Serializable {
@@ -72,7 +72,7 @@ public class BundleFile implements Serializable {
@JoinColumn(name = "PACKAGE_ID", referencedColumnName = "ID", nullable = true)
@ManyToOne(fetch = FetchType.LAZY)
- private Package pkg;
+ private Package generalPackage;
@JoinColumn(name = "PACKAGE_VERSION_ID", referencedColumnName = "ID", nullable = false)
@ManyToOne(fetch = FetchType.LAZY)
@@ -99,11 +99,11 @@ public class BundleFile implements Serializable {
}
public Package getPackage() {
- return pkg;
+ return generalPackage;
}
public void setPackage(Package pkg) {
- this.pkg = pkg;
+ this.generalPackage = pkg;
}
public PackageVersion getPackageVersion() {
@@ -124,7 +124,7 @@ public class BundleFile implements Serializable {
final int prime = 31;
int result = 1;
result = prime * result + ((bundleVersion == null) ? 0 : bundleVersion.hashCode());
- result = prime * result + ((pkg == null) ? 0 : pkg.hashCode());
+ result = prime * result + ((generalPackage == null) ? 0 : generalPackage.hashCode());
result = prime * result + ((packageVersion == null) ? 0 : packageVersion.hashCode());
return result;
}
@@ -148,11 +148,11 @@ public class BundleFile implements Serializable {
return false;
}
- if (pkg == null) {
- if (other.pkg != null) {
+ if (generalPackage == null) {
+ if (other.generalPackage != null) {
return false;
}
- } else if (!pkg.equals(other.pkg)) {
+ } else if (!generalPackage.equals(other.generalPackage)) {
return false;
}
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceType.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceType.java
index f4582d0..69e8175 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceType.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceType.java
@@ -188,7 +188,7 @@ import org.rhq.core.domain.util.serial.ExternalizableStrategy;
+ "GROUP BY rt.name " //
+ " HAVING COUNT(rt.name) > 1"), //
@NamedQuery(name = ResourceType.QUERY_DYNAMIC_CONFIG_WITH_PLUGIN, query = "" //
- + "SELECT rt.plugin || ' - ' || rt.name, rt.plugin || '-' || rt.name FROM ResourceType rt" ) //
+ + "SELECT rt.plugin || ' - ' || rt.name, rt.plugin || '-' || rt.name FROM ResourceType rt") //
})
@NamedNativeQueries( {
// TODO: Add authz conditions to the below query.
@@ -236,14 +236,14 @@ import org.rhq.core.domain.util.serial.ExternalizableStrategy;
+ "WHERE rtp2.resource_type_id = crt2.id) " + "AND crt2.category = ? " +
// "ORDER BY crt2.name" +
")) ORDER BY name", resultSetMapping = ResourceType.MAPPING_FIND_CHILDREN_BY_CATEGORY) //
- })
+})
@SqlResultSetMapping(name = ResourceType.MAPPING_FIND_CHILDREN_BY_CATEGORY, entities = { @EntityResult(entityClass = ResourceType.class) })
// @Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
public class ResourceType implements Externalizable, Comparable<ResourceType> {
private static final long serialVersionUID = 2L;
public static final String TABLE_NAME = "RHQ_RESOURCE_TYPE";
-
+
public static final ResourceType ANY_PLATFORM_TYPE = null;
public static final String QUERY_FIND_BY_NAME = "ResourceType.findByName";
@@ -379,7 +379,7 @@ public class ResourceType implements Externalizable, Comparable<ResourceType> {
@OneToMany(mappedBy = "resourceType", cascade = CascadeType.ALL)
private Set<ProductVersion> productVersions;
- @OneToOne(mappedBy = "resourceType", fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE }, optional = true)
+ @OneToOne(mappedBy = "resourceType", fetch = FetchType.LAZY, cascade = CascadeType.ALL, optional = true)
private BundleType bundleType;
@Transient
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java
index ba53759..d9b77af 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java
@@ -19,12 +19,9 @@
package org.rhq.enterprise.server.bundle;
-import java.util.HashSet;
import java.util.Set;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
-import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
-import org.rhq.core.domain.configuration.definition.PropertySimpleType;
/**
* This class is general to all Bundle handling server side plugins. It is returned by the SSP when parsing
@@ -46,14 +43,6 @@ public class RecipeParseResults {
}
public ConfigurationDefinition getConfigDef() {
-
- // stub out a test ConfigDef here until we actual parse the recipe
- System.out.println("!!!!!! REMOVE THIS TEST CODE !!!!!!!!");
- configDef = new ConfigurationDefinition("SampleBundle", "Stubbed ConfigDef for Sample Bundle");
- configDef.put(new PropertyDefinitionSimple("sample.bundle.deploy.directory",
- "Stubbed Property for deploy directory (must already exist on target platform)", true,
- PropertySimpleType.STRING));
-
return configDef;
}
@@ -62,12 +51,6 @@ public class RecipeParseResults {
}
public Set<String> getBundleFileNames() {
- // stub out a test set of BundleFiles here until we actual parse the recipe. For now lets just deploy
- // a war file into an existing app server dir.
- System.out.println("!!!!!! REMOVE THIS TEST CODE !!!!!!!!");
- bundleFileNames = new HashSet<String>();
- bundleFileNames.add("sample-bundle.war");
-
return bundleFileNames;
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
index 1ca01c8..24c6dae 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
@@ -36,7 +36,9 @@ import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleFile;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageType;
+import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.content.Repo;
import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleVersionCriteria;
@@ -54,9 +56,9 @@ import org.rhq.enterprise.server.util.LookupUtil;
@Test
public class BundleManagerBeanTest extends AbstractEJB3Test {
- private static final String TEST_PREFIX = "bundletest";
+ private static final boolean TESTS_ENABLED = true;
- private static final boolean ENABLED = true;
+ private static final String TEST_PREFIX = "bundletest";
private BundleManagerLocal bundleManager;
@@ -65,7 +67,8 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
@BeforeMethod
public void beforeMethod() {
- super.startTest();
+ // try and clean up any junk that may be lying around from a failed run
+ cleanupDatabase();
this.ps = new TestBundleServerPluginService();
prepareCustomServerPluginService(this.ps);
@@ -76,6 +79,13 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
@AfterMethod(alwaysRun = true)
public void afterMethod() throws Exception {
+ cleanupDatabase();
+
+ unprepareServerPluginService();
+ this.ps = null;
+ }
+
+ private void cleanupDatabase() {
EntityManager em = null;
try {
@@ -86,42 +96,63 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
List doomed;
// clean up any tests that don't already clean up after themselves
- q = em.createQuery("SELECT bv FROM BundleVersion bv WHERE bv.bundle.name LIKE '" + TEST_PREFIX + "%'");
+
+ // remove bundleversions which cascade remove bundlefiles and bundledeploydefs
+ q = em.createQuery("SELECT bv FROM BundleVersion bv WHERE bv.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
for (Object removeMe : doomed) {
em.remove(em.getReference(BundleVersion.class, ((BundleVersion) removeMe).getId()));
}
-
+ // remove any orphaned bfs
+ q = em.createQuery("SELECT bf FROM BundleFile bf WHERE bf.generalPackage.name LIKE '" + TEST_PREFIX + "%'");
+ doomed = q.getResultList();
+ for (Object removeMe : doomed) {
+ em.remove(em.getReference(BundleFile.class, ((BundleFile) removeMe).getId()));
+ }
+ // remove packages which cascade remove packageversions
+ q = em.createQuery("SELECT p FROM Package p WHERE p.name LIKE '" + TEST_PREFIX + "%'");
+ doomed = q.getResultList();
+ for (Object removeMe : doomed) {
+ em.remove(em.getReference(Package.class, ((Package) removeMe).getId()));
+ }
+ // remove any orphaned pvs
+ q = em.createQuery("SELECT pv FROM PackageVersion pv WHERE pv.generalPackage.name LIKE '" + TEST_PREFIX
+ + "%'");
+ doomed = q.getResultList();
+ for (Object removeMe : doomed) {
+ em.remove(em.getReference(PackageVersion.class, ((PackageVersion) removeMe).getId()));
+ }
+ // remove bundles which cascade remove repos
q = em.createQuery("SELECT b FROM Bundle b WHERE b.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
for (Object removeMe : doomed) {
em.remove(em.getReference(Bundle.class, ((Bundle) removeMe).getId()));
}
-
+ // remove any orphaned repos
q = em.createQuery("SELECT r FROM Repo r WHERE r.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
for (Object removeMe : doomed) {
em.remove(em.getReference(Repo.class, ((Repo) removeMe).getId()));
}
-
+ // remove ResourceTypes which cascade remove BundleTypes and PackageTypes
+ q = em.createQuery("SELECT rt FROM ResourceType rt WHERE rt.name LIKE '" + TEST_PREFIX + "%'");
+ doomed = q.getResultList();
+ for (Object removeMe : doomed) {
+ em.remove(em.getReference(ResourceType.class, ((ResourceType) removeMe).getId()));
+ }
+ // remove any orphaned BundleTypes
q = em.createQuery("SELECT bt FROM BundleType bt WHERE bt.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
for (Object removeMe : doomed) {
em.remove(em.getReference(BundleType.class, ((BundleType) removeMe).getId()));
}
-
+ // remove any orphaned packagetypes
q = em.createQuery("SELECT pt FROM PackageType pt WHERE pt.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
for (Object removeMe : doomed) {
em.remove(em.getReference(PackageType.class, ((PackageType) removeMe).getId()));
}
- q = em.createQuery("SELECT rt FROM ResourceType rt WHERE rt.name LIKE '" + TEST_PREFIX + "%'");
- doomed = q.getResultList();
- for (Object removeMe : doomed) {
- em.remove(em.getReference(ResourceType.class, ((ResourceType) removeMe).getId()));
- }
-
getTransactionManager().commit();
em.close();
em = null;
@@ -136,14 +167,9 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
em.close();
}
}
-
- unprepareServerPluginService();
- this.ps = null;
-
- super.endTest();
}
- @Test(enabled = ENABLED)
+ @Test(enabled = TESTS_ENABLED)
public void testGetBundleTypes() throws Exception {
BundleType bt1 = createBundleType("one");
BundleType bt2 = createBundleType("two");
@@ -159,13 +185,13 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
assert btNames.contains(bt2.getName());
}
- @Test(enabled = ENABLED)
+ @Test(enabled = TESTS_ENABLED)
public void testCreateBundle() throws Exception {
Bundle b1 = createBundle("one");
assertNotNull(b1);
}
- @Test(enabled = ENABLED)
+ @Test(enabled = TESTS_ENABLED)
public void testCreateBundleVersion() throws Exception {
Bundle b1 = createBundle("one");
assertNotNull(b1);
@@ -177,7 +203,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
assertEquals("1.1", bv2.getVersion());
}
- @Test(enabled = ENABLED)
+ @Test(enabled = TESTS_ENABLED)
public void testAddBundleFiles() throws Exception {
Bundle b1 = createBundle("one");
assertNotNull(b1);
@@ -189,7 +215,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
+ "-bundlefile-2", "1.0", null, "Test Bundle File # 2".getBytes(), false);
}
- @Test(enabled = ENABLED)
+ @Test(enabled = TESTS_ENABLED)
public void testfindBundlesByCriteria() throws Exception {
Bundle b1 = createBundle("one");
Bundle b2 = createBundle("two");
@@ -246,7 +272,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
assertEquals(b.getName(), r.getName());
}
- @Test(enabled = ENABLED)
+ @Test(enabled = TESTS_ENABLED)
public void testfindBundleVersionsByCriteria() throws Exception {
Bundle b1 = createBundle("one");
BundleVersion bv1 = createBundleVersion(b1.getName(), "1.0", b1);
@@ -331,7 +357,8 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
}
private PackageType createPackageType(String name, ResourceType rt) throws Exception {
- final String fullName = TEST_PREFIX + "-packagetype-" + name;
+ // the package type is named the same as the bundle type
+ final String fullName = TEST_PREFIX + "-type-" + name;
PackageType pt = new PackageType(fullName, rt);
TransactionManager txMgr = getTransactionManager();
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 64bd5af..dc43f97 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
@@ -22,11 +22,15 @@ import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
+import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
+import org.rhq.core.domain.configuration.definition.PropertySimpleType;
import org.rhq.core.domain.plugin.PluginKey;
import org.rhq.core.domain.plugin.PluginStatusType;
import org.rhq.core.domain.plugin.ServerPlugin;
@@ -40,6 +44,7 @@ import org.rhq.enterprise.server.plugin.pc.ServerPluginManager;
import org.rhq.enterprise.server.plugin.pc.ServerPluginService;
import org.rhq.enterprise.server.plugin.pc.ServerPluginType;
import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginFacet;
import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginManager;
import org.rhq.enterprise.server.xmlschema.ServerPluginDescriptorMetadataParser;
import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType;
@@ -165,5 +170,33 @@ public class TestBundleServerPluginService extends ServerPluginService implement
components.put(environment.getPluginKey().getPluginName(), component);
return component;
}
+
+ @Override
+ public BundleServerPluginFacet getBundleServerPluginFacet(String bundleTypeName) {
+
+ return new TestBundlePluginComponent();
+ }
+ }
+
+ class TestBundlePluginComponent implements BundleServerPluginFacet {
+
+ public TestBundlePluginComponent() {
+ };
+
+ public RecipeParseResults parseRecipe(String recipe) throws Exception {
+
+ ConfigurationDefinition configDef;
+ Set<String> bundleFileNames;
+
+ configDef = new ConfigurationDefinition("SampleBundle", "Stubbed ConfigDef for Sample Bundle");
+ configDef.put(new PropertyDefinitionSimple("sample.bundle.deploy.directory",
+ "Stubbed Property for deploy directory (must already exist on target platform)", true,
+ PropertySimpleType.STRING));
+
+ bundleFileNames = new HashSet<String>();
+ bundleFileNames.add("sample-bundle.war");
+
+ return new RecipeParseResults(configDef, bundleFileNames);
+ }
}
}
\ No newline at end of file
commit 6204586d5d601a564e6e96c35f6d473d3dee43b5
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Wed Mar 3 18:12:46 2010 +0100
Inject real Subject of current user and fix congifuration display directly after login.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/CustomContentUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/CustomContentUIBean.java
index 683057b..e39650c 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/CustomContentUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/CustomContentUIBean.java
@@ -26,6 +26,8 @@ import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.web.RequestParameter;
import org.jboss.seam.contexts.Context;
import org.jboss.seam.contexts.Contexts;
+
+import org.rhq.core.domain.auth.Subject;
import org.rhq.enterprise.server.alert.AlertNotificationManagerLocal;
import org.rhq.enterprise.server.plugin.pc.alert.AlertSenderInfo;
import org.rhq.enterprise.server.plugin.pc.alert.CustomAlertSenderBackingBean;
@@ -43,6 +45,9 @@ public class CustomContentUIBean {
@In
private AlertNotificationManagerLocal alertNotificationManager;
+ @In("#{webUser.subject}")
+ private Subject subject;
+
private String contentUrl;
public String getContentUrl() {
@@ -62,6 +67,7 @@ public class CustomContentUIBean {
notificationId);
if (backingBeanName != null && backingBean != null) {
+ backingBean.setWebUser(subject);
outjectBean(backingBeanName, backingBean);
}
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/CustomAlertSenderBackingBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/CustomAlertSenderBackingBean.java
index 12312f2..73ddf85 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/CustomAlertSenderBackingBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/CustomAlertSenderBackingBean.java
@@ -18,6 +18,7 @@
*/
package org.rhq.enterprise.server.plugin.pc.alert;
+import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.enterprise.server.configuration.ConfigurationManagerLocal;
@@ -32,6 +33,7 @@ public class CustomAlertSenderBackingBean {
/** Configuration from the per alert definition parameters */
protected Configuration alertParameters;
+ protected Subject webUser;
public Configuration getAlertParameters() {
return alertParameters;
@@ -41,6 +43,14 @@ public class CustomAlertSenderBackingBean {
this.alertParameters = alertParameters;
}
+ public Subject getWebUser() {
+ return webUser;
+ }
+
+ public void setWebUser(Subject webUser) {
+ this.webUser = webUser;
+ }
+
/**
* This method is called after constructing the bean and injecting the
* #alertParameters
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java
index dc41f01..c7c8c26 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java
@@ -130,17 +130,14 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
private void lookupConfiguration() {
-
try {
-// Subject subject = EnterpriseFacesContextUtility.getSubject();
- Subject subject = LookupUtil.getSubjectManager().getOverlord(); // TODO replace with real subject
OperationManagerLocal opMan = LookupUtil.getOperationManager();
obtainOperationIds();
if (operationId!=null) {
- OperationDefinition operationDefinition = opMan.getOperationDefinition(subject, operationId);
+ OperationDefinition operationDefinition = opMan.getOperationDefinition(webUser, operationId);
configurationDefinition = operationDefinition.getParametersConfigurationDefinition();
@@ -175,8 +172,7 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
if (resId!=null) {
OperationManagerLocal opMan = LookupUtil.getOperationManager();
- Subject subject = LookupUtil.getSubjectManager().getOverlord(); // TODO replace with real subject
- List<OperationDefinition> opDefs = opMan.findSupportedResourceOperations(subject, resId, false);
+ List<OperationDefinition> opDefs = opMan.findSupportedResourceOperations(webUser, resId, false);
for (OperationDefinition def : opDefs) {
operationIds.put(def.getDisplayName(),def.getId()); // TODO add more distinctive stuff in display
}
@@ -195,7 +191,7 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
}
public Integer getResId() {
-
+ System.out.println("OperationsBackingBean.getResId");
if (resId==null) {
PropertySimple prop = alertParameters.getSimple(OperationsSender.RESOURCE_ID);
if (prop!=null)
@@ -219,8 +215,7 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
if (resId!=null) {
ResourceManagerLocal resMgr = LookupUtil.getResourceManager();
- Subject subject = LookupUtil.getSubjectManager().getOverlord(); // TODO replace with real subject
- Resource res = resMgr.getResource(subject,resId);
+ Resource res = resMgr.getResource(webUser,resId);
resourceName = res.getName() + " (" + res.getResourceType().getName() + ")";
}
@@ -232,7 +227,7 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
}
public Integer getOperationId() {
-
+ System.out.println("OperationsBackingBean.getOperationId, operationId=" + operationId);
if (operationId ==null) {
PropertySimple prop = alertParameters.getSimple(OperationsSender.OPERATION_ID);
if (prop!=null)
@@ -258,10 +253,12 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
}
public ConfigurationDefinition getConfigurationDefinition() {
- return configurationDefinition;
-
+ System.out.println("OperationsBackingBean.getConfigurationDefinition");
+ if (configurationDefinition==null)
+ lookupConfiguration();
+ return configurationDefinition;
}
public void setConfigurationDefinition(ConfigurationDefinition configurationDefinition) {
commit f7bb4c6924ea155514a7818223737aa89b2aaa04
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Wed Mar 3 01:51:39 2010 -0500
add agent bundle plugin unit tests
diff --git a/.classpath b/.classpath
index c6a1ed2..fe06650 100644
--- a/.classpath
+++ b/.classpath
@@ -126,6 +126,7 @@
<classpathentry kind="src" path="modules/plugins/augeas/src/main/java"/>
<classpathentry kind="src" path="modules/plugins/augeas/src/test/java"/>
<classpathentry kind="src" path="modules/plugins/filetemplate-bundle/src/main/java"/>
+ <classpathentry kind="src" path="modules/plugins/filetemplate-bundle/src/test/java"/>
<classpathentry kind="src" path="modules/helpers/rtfilter/src/main/java"/>
<classpathentry kind="src" path="modules/helpers/pluginAnnotations/src/main/java"/>
<classpathentry kind="src" path="modules/helpers/pluginGen/src/main/java"/>
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
index ffe24f2..26199d3 100644
--- a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
@@ -34,6 +34,7 @@ import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.system.ProcessExecution;
import org.rhq.core.system.ProcessExecutionResults;
import org.rhq.core.system.SystemInfo;
+import org.rhq.core.util.file.FileUtil;
/**
* A recipe context that processes the recipe as it adds stuff to the context
@@ -61,7 +62,7 @@ public class ProcessingRecipeContext extends RecipeContext {
File existingFile = new File(this.baseWorkingDirectory, filename);
- ProcessExecution pe = getUnzipExecution(filename, directory);
+ ProcessExecution pe = getUnzipExecution(existingFile, directory);
if (pe != null) {
ProcessExecutionResults results = this.systemInfo.executeProcess(pe);
if (results.getError() != null) {
@@ -69,7 +70,7 @@ public class ProcessingRecipeContext extends RecipeContext {
} else if (results.getExitCode() == null || results.getExitCode().intValue() > 0) {
throw new RuntimeException("Failed to unbundle file [" + pe + "]: " + results);
}
- existingFile.delete();
+ // existingFile.delete(); WOULD WE WANT TO REMOVE THE COMPRESSED FILE?
} else {
// not a zipped format - just move the file to the directory as-is
File newFile = new File(directory, filename);
@@ -80,21 +81,27 @@ public class ProcessingRecipeContext extends RecipeContext {
}
@Override
- public void addFile(String filename, String directory) {
- super.addDeployFile(filename, directory);
+ public void addFile(String source, String destination) {
+ super.addFile(source, destination);
- File existingFile = new File(this.baseWorkingDirectory, filename);
- File newFile = new File(directory, filename);
- if (!existingFile.renameTo(newFile)) {
- throw new RuntimeException("Failed to move file [" + existingFile + "] to [" + newFile + "]");
+ File sourceFile = new File(this.baseWorkingDirectory, source);
+ File destinationFile = new File(destination);
+
+ try {
+ destinationFile.getParentFile().mkdirs();
+ FileUtil.copyFile(sourceFile, destinationFile);
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to copy file [" + sourceFile + "] to [" + destinationFile + "]", e);
}
+
+ return;
}
@Override
public void addRealizedFile(String file) {
super.addRealizedFile(file);
- File trueFile = new File(file);
+ File trueFile = new File(this.baseWorkingDirectory, file);
RecipeParser parser = getParser();
File realizedTmpFile = null;
FileWriter realizedTmpFileWriter = null;
@@ -166,42 +173,44 @@ public class ProcessingRecipeContext extends RecipeContext {
}
}
- private ProcessExecution getUnzipExecution(String filename, String directory) {
+ private ProcessExecution getUnzipExecution(File file, String directory) {
String exe;
List<String> args = null;
- if (filename.endsWith(".tar")) {
+ String filepath = file.getAbsolutePath();
+
+ if (filepath.endsWith(".tar")) {
exe = "tar";
args = new ArrayList<String>();
args.add("xf");
- args.add(filename);
+ args.add(filepath);
args.add("-C");
args.add(directory);
- } else if (filename.endsWith(".tar.bz2") || filename.endsWith(".tbz2") || filename.endsWith(".tbz")) {
+ } else if (filepath.endsWith(".tar.bz2") || filepath.endsWith(".tbz2") || filepath.endsWith(".tbz")) {
exe = "tar";
args = new ArrayList<String>();
args.add("xfj");
- args.add(filename);
+ args.add(filepath);
args.add("-C");
args.add(directory);
- } else if (filename.endsWith(".tar.gz") || filename.endsWith(".tgz")) {
+ } else if (filepath.endsWith(".tar.gz") || filepath.endsWith(".tgz")) {
exe = "tar";
args = new ArrayList<String>();
args.add("xfz");
- args.add(filename);
+ args.add(filepath);
args.add("-C");
args.add(directory);
- } else if (filename.endsWith(".zip")) {
+ } else if (filepath.endsWith(".zip")) {
exe = "unzip";
args = new ArrayList<String>();
- args.add(filename);
+ args.add(filepath);
args.add("-d");
args.add(directory);
- } else if (filename.endsWith(".rpm")) {
+ } else if (filepath.endsWith(".rpm")) {
exe = "rpm";
args = new ArrayList<String>();
args.add("-i");
- args.add(filename);
+ args.add(filepath);
if (directory != null && directory.length() > 0) {
args.add("--prefix");
args.add(directory);
@@ -213,6 +222,7 @@ public class ProcessingRecipeContext extends RecipeContext {
ProcessExecution pe = new ProcessExecution(exe);
pe.setArguments(args);
pe.setWaitForCompletion(30 * 60 * 1000L);
+ pe.setCheckExecutableExists(false);
pe.setWorkingDirectory(this.baseWorkingDirectory);
return pe;
}
diff --git a/modules/plugins/filetemplate-bundle/src/test/java/org/rhq/plugins/filetemplate/ProcessingRecipeContextTest.java b/modules/plugins/filetemplate-bundle/src/test/java/org/rhq/plugins/filetemplate/ProcessingRecipeContextTest.java
new file mode 100644
index 0000000..1099481
--- /dev/null
+++ b/modules/plugins/filetemplate-bundle/src/test/java/org/rhq/plugins/filetemplate/ProcessingRecipeContextTest.java
@@ -0,0 +1,225 @@
+/*
+ * 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, 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.filetemplate;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Map;
+import java.util.Set;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import org.rhq.bundle.filetemplate.recipe.RecipeContext;
+import org.rhq.bundle.filetemplate.recipe.RecipeParser;
+import org.rhq.core.domain.content.PackageVersion;
+import org.rhq.core.pluginapi.util.FileUtils;
+import org.rhq.core.system.SystemInfo;
+import org.rhq.core.system.SystemInfoFactory;
+import org.rhq.core.util.stream.StreamUtil;
+
+@Test
+public class ProcessingRecipeContextTest {
+ private StringBuilder recipe;
+
+ @BeforeMethod
+ public void cleanRecipeBeforeMethod() {
+ cleanRecipe();
+ }
+
+ @AfterClass
+ public void afterClass() throws IOException {
+ FileUtils.purge(getTmpDir(), true);
+ }
+
+ public void testRealizeRecipe() throws Exception {
+ File testDir = getTestDir("testrealize");
+ File file = writeFile("a b c\nhello<% var %>world\na b c\n", testDir, "config.txt");
+
+ addRecipeCommand("realize --file=" + file.getName());
+
+ ProcessingRecipeContext context = createRecipeContext(testDir);
+ context.addReplacementVariableValue("var", "BOO");
+ context = parseRecipeNow(context);
+
+ Set<String> files = context.getRealizedFiles();
+ assert files.size() == 1 : files;
+ assert files.contains(file.getName()) : files;
+
+ String realizedContent = readFile(file);
+ assert realizedContent.equals("a b c\nhelloBOOworld\na b c\n") : realizedContent;
+ }
+
+ public void testFileRecipe() throws Exception {
+ File testDir = getTestDir("testfile");
+ File testDestDir = getTestDir("testfile-dest");
+ File runme = writeFile("runme script", testDir, "run-me.sh");
+ File runmeDest = new File(testDestDir, "run-me.sh");
+ File another = writeFile("<wotgorilla/>", testDir, "META-INF/another.xml");
+ File anotherDest = new File(testDestDir, "/OTHER/another.xml");
+
+ addRecipeCommand("file --source=run-me.sh \"--destination=" + runmeDest + "\"");
+ addRecipeCommand("file -s META-INF/another.xml -d \"" + anotherDest + "\"");
+
+ RecipeContext context = parseRecipeNow(testDir);
+
+ Map<String, String> files = context.getFiles();
+ assert files.size() == 2 : files;
+ assert files.get("run-me.sh") != null : files;
+ assert files.get("run-me.sh").equals(runmeDest.getPath()) : files;
+ assert files.get("META-INF/another.xml") != null : files;
+ assert files.get("META-INF/another.xml").equals(anotherDest.getPath()) : files;
+
+ String runmeContent = readFile(runme);
+ String runmeDestContent = readFile(runmeDest);
+ assert runmeContent.equals(runmeDestContent) : runmeDestContent;
+ String anotherContent = readFile(another);
+ String anotherDestContent = readFile(anotherDest);
+ assert anotherContent.equals(anotherDestContent) : anotherDestContent;
+ }
+
+ public void testDeployRecipe() throws Exception {
+ File testDir = getTestDir("testdeploy");
+ File testDestDir = getTestDir("testdeploy-dest");
+ File unzippedFile = new File(testDestDir, "zipped-file.txt");
+ File zipFile = createZip("zipped file content", testDir, "deploy-test.zip", unzippedFile.getName());
+
+ addRecipeCommand("deploy -f " + zipFile.getName() + " -d \"" + testDestDir + "\"");
+
+ RecipeContext context = parseRecipeNow(testDir);
+
+ Map<String, String> files = context.getDeployFiles();
+ assert files.size() == 1 : files;
+ assert files.get(zipFile.getName()) != null;
+
+ String zippedFileContent = readFile(unzippedFile);
+ assert zippedFileContent.equals("zipped file content");
+ }
+
+ @Test(enabled = false)
+ public void testScriptRecipe() throws Exception {
+ File testDir = getTestDir("testscript");
+
+ addRecipeCommand("script echo hello");
+
+ RecipeContext context = parseRecipeNow(testDir);
+
+ Set<String> scripts = context.getScriptFiles();
+ assert scripts.size() == 1 : scripts;
+ assert scripts.contains("run-me.sh") : scripts;
+ assert scripts.contains("lots-o-params.sh") : scripts;
+ }
+
+ private ProcessingRecipeContext parseRecipeNow(File testDir) throws Exception {
+ ProcessingRecipeContext context = createRecipeContext(testDir);
+ return parseRecipeNow(context);
+ }
+
+ private ProcessingRecipeContext createRecipeContext(File testDir) {
+ Map<PackageVersion, File> packageVersionFiles = null; // TODO not used yet
+ SystemInfo sysinfo = SystemInfoFactory.createSystemInfo();
+ String cwd = testDir.getAbsolutePath();
+ ProcessingRecipeContext context = new ProcessingRecipeContext(getRecipe(), packageVersionFiles, sysinfo, cwd);
+ return context;
+ }
+
+ private ProcessingRecipeContext parseRecipeNow(ProcessingRecipeContext context) throws Exception {
+ RecipeParser parser = new RecipeParser();
+ parser.setReplaceReplacementVariables(true);
+ parser.parseRecipe(context);
+ return context;
+ }
+
+ private File getTestDir(String subdir) {
+ return new File(getTmpDir(), subdir);
+ }
+
+ private File getTmpDir() {
+ File tmpdir = new File(System.getProperty("java.io.tmpdir"), "processing-recipe-test");
+ tmpdir.mkdirs();
+ return tmpdir;
+ }
+
+ private void cleanRecipe() {
+ this.recipe = new StringBuilder();
+ }
+
+ private void addRecipeCommand(String commandLine) {
+ this.recipe.append(commandLine).append("\n");
+ }
+
+ private String getRecipe() {
+ return this.recipe.toString();
+ }
+
+ private String readFile(File file) throws Exception {
+ return new String(StreamUtil.slurp(new FileInputStream(file)));
+ }
+
+ private File writeFile(String content, File destDir, String fileName) throws Exception {
+ FileOutputStream out = null;
+
+ try {
+ File destFile = new File(destDir, fileName);
+ destFile.getParentFile().mkdirs();
+ out = new FileOutputStream(destFile);
+ out.write(content.getBytes());
+ return destFile;
+ } finally {
+ if (out != null) {
+ out.close();
+ }
+ }
+ }
+
+ private File createZip(String content, File destDir, String zipName, String entryName) throws Exception {
+ FileOutputStream stream = null;
+ ZipOutputStream out = null;
+
+ try {
+ destDir.mkdirs();
+ File zipFile = new File(destDir, zipName);
+ stream = new FileOutputStream(zipFile);
+ out = new ZipOutputStream(stream);
+
+ ZipEntry zipAdd = new ZipEntry(entryName);
+ zipAdd.setTime(System.currentTimeMillis());
+ out.putNextEntry(zipAdd);
+ out.write(content.getBytes());
+ return zipFile;
+ } finally {
+ if (out != null) {
+ out.close();
+ }
+ if (stream != null) {
+ stream.close();
+ }
+ }
+ }
+}
commit 150fa0766fb19d1fc6d7ce9918df5fab6848219e
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Wed Mar 3 01:50:55 2010 -0500
remove this broken link
diff --git a/dev-cli b/dev-cli
deleted file mode 120000
index 9e0363b..0000000
--- a/dev-cli
+++ /dev/null
@@ -1 +0,0 @@
-modules/enterprise/remoting/cli/target/rhq-remoting-cli-1.4.0-SNAPSHOT
\ No newline at end of file
commit 981a3c4c5c77774b62e1b4e37f6b341aea1e1f35
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Mar 2 20:30:39 2010 -0500
add realize recipe command
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java
index 5f14f2f..d73f871 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java
@@ -32,7 +32,7 @@ public class DeployRecipeCommand implements RecipeCommand {
return "deploy";
}
- public void parse(RecipeContext context, String[] args) {
+ public void parse(RecipeParser parser, RecipeContext context, String[] args) {
String sopts = ":f:d:";
LongOpt[] lopts = { new LongOpt("file", LongOpt.REQUIRED_ARGUMENT, null, 'f'),
new LongOpt("directory", LongOpt.REQUIRED_ARGUMENT, null, 'd') };
@@ -40,7 +40,7 @@ public class DeployRecipeCommand implements RecipeCommand {
String filename = null;
String directory = null;
- Getopt getopt = new Getopt(context.toString(), args, sopts, lopts);
+ Getopt getopt = new Getopt(getName(), args, sopts, lopts);
int code;
while ((code = getopt.getopt()) != -1) {
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/FileRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/FileRecipeCommand.java
index 3b74805..2984bab 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/FileRecipeCommand.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/FileRecipeCommand.java
@@ -32,7 +32,7 @@ public class FileRecipeCommand implements RecipeCommand {
return "file";
}
- public void parse(RecipeContext context, String[] args) {
+ public void parse(RecipeParser parser, RecipeContext context, String[] args) {
String sopts = ":s:d:";
LongOpt[] lopts = { new LongOpt("source", LongOpt.REQUIRED_ARGUMENT, null, 's'),
new LongOpt("destination", LongOpt.REQUIRED_ARGUMENT, null, 'd') };
@@ -40,7 +40,7 @@ public class FileRecipeCommand implements RecipeCommand {
String source = null;
String destination = null;
- Getopt getopt = new Getopt(context.toString(), args, sopts, lopts);
+ Getopt getopt = new Getopt(getName(), args, sopts, lopts);
int code;
while ((code = getopt.getopt()) != -1) {
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RealizeRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RealizeRecipeCommand.java
new file mode 100644
index 0000000..b187ed8
--- /dev/null
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RealizeRecipeCommand.java
@@ -0,0 +1,74 @@
+/*
+ * 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, 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.bundle.filetemplate.recipe;
+
+import gnu.getopt.Getopt;
+import gnu.getopt.LongOpt;
+
+public class RealizeRecipeCommand implements RecipeCommand {
+
+ public String getName() {
+ return "realize";
+ }
+
+ public void parse(RecipeParser parser, RecipeContext context, String[] args) {
+ String sopts = ":f:";
+ LongOpt[] lopts = { new LongOpt("file", LongOpt.REQUIRED_ARGUMENT, null, 'f') };
+
+ String file = null;
+
+ Getopt getopt = new Getopt(getName(), args, sopts, lopts);
+ int code;
+
+ while ((code = getopt.getopt()) != -1) {
+ switch (code) {
+ case ':':
+ case '?': {
+ throw new IllegalArgumentException("Bad recipe command.");
+ }
+
+ case 1: {
+ throw new IllegalArgumentException("Bad recipe command!");
+ }
+
+ case 'f': {
+ file = getopt.getOptarg();
+ break;
+ }
+
+ default: {
+ throw new IllegalArgumentException("Unexpected error in recipe command");
+ }
+
+ }
+ }
+
+ if (file == null) {
+ throw new IllegalArgumentException("Did not specify the file to realize");
+ }
+
+ context.addRealizedFile(file);
+ return;
+ }
+}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeCommand.java
index 7cfa964..01c1da3 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeCommand.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeCommand.java
@@ -34,9 +34,10 @@ public interface RecipeCommand {
/**
* Parses this recipe command and optionally puts information in the context.
- *
+ *
+ * @param parser the parser that is invoking this command
* @param context information where the parser can store information regarding the command that was processed
* @param args arguments passed to the command.
*/
- void parse(RecipeContext context, String[] args);
+ void parse(RecipeParser recipeParser, RecipeContext context, String[] args);
}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
index dcea274..cb76a80 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
@@ -34,15 +34,17 @@ import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
/**
- * Contains information that is gleened from a recipe after it is parsed.
+ * Contains information that is gleened from a recipe during and after it is parsed.
*
* @author John Mazzitelli
*/
public class RecipeContext {
+ private RecipeParser parser;
private final String recipe;
private final Map<String, String> deployFiles;
private final Map<String, String> files;
+ private final Set<String> realizedFiles;
private final Set<String> replacementVariables;
private Configuration replacementVariableValues;
private final List<Script> scripts;
@@ -51,11 +53,24 @@ public class RecipeContext {
this.recipe = recipe;
this.deployFiles = new HashMap<String, String>();
this.files = new HashMap<String, String>();
+ this.realizedFiles = new HashSet<String>();
this.replacementVariables = new HashSet<String>();
this.scripts = new ArrayList<Script>();
}
/**
+ * If this context is currently in use by a parser, this will be the reference to that parser.
+ * @return parser currently using this context
+ */
+ public RecipeParser getParser() {
+ return parser;
+ }
+
+ public void setParser(RecipeParser parser) {
+ this.parser = parser;
+ }
+
+ /**
* The full recipe that this context represents.
*
* @return the actual recipe text
@@ -95,6 +110,20 @@ public class RecipeContext {
}
/**
+ * Returns the pathnames of all files that are to be realized (meaning, those that should
+ * have replacement variables replaced).
+ *
+ * @return set of all realized files
+ */
+ public Set<String> getRealizedFiles() {
+ return this.realizedFiles;
+ }
+
+ public void addRealizedFile(String file) {
+ this.realizedFiles.add(file);
+ }
+
+ /**
* The names of all replacement variables that are found in the recipe.
*
* @return the replacement variables
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
index 13644e6..98f26f6 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
@@ -77,17 +77,22 @@ public class RecipeParser {
public void parseRecipe(RecipeContext context) throws Exception {
- BufferedReader recipeReader = new BufferedReader(new StringReader(context.getRecipe()));
- String line = recipeReader.readLine();
- while (line != null) {
- parseRecipeCommandLine(context, line);
- line = recipeReader.readLine();
+ context.setParser(this);
+ try {
+ BufferedReader recipeReader = new BufferedReader(new StringReader(context.getRecipe()));
+ String line = recipeReader.readLine();
+ while (line != null) {
+ parseRecipeCommandLine(context, line);
+ line = recipeReader.readLine();
+ }
+ } finally {
+ context.setParser(null);
}
return;
}
- public void parseRecipeCommandLine(RecipeContext context, String line) throws Exception {
+ protected void parseRecipeCommandLine(RecipeContext context, String line) throws Exception {
// ignore blank lines or comment lines that start with #
if (line == null || line.trim().length() == 0 || line.startsWith("#")) {
return;
@@ -112,7 +117,7 @@ public class RecipeParser {
}
try {
- recipeCommand.parse(context, arguments);
+ recipeCommand.parse(this, context, arguments);
} catch (Exception e) {
throw new Exception("Error in recipe, line [" + line + "]", e);
}
@@ -125,6 +130,7 @@ public class RecipeParser {
RecipeCommand[] knownCommands = new RecipeCommand[] { new ScriptRecipeCommand(), //
new FileRecipeCommand(), //
+ new RealizeRecipeCommand(), //
new DeployRecipeCommand() //
};
@@ -156,14 +162,9 @@ public class RecipeParser {
return replacementVariables;
}
- protected String replaceReplacementVariables(RecipeContext context, String input) {
+ public String replaceReplacementVariables(RecipeContext context, String input) {
- // don't bother if we have no values to replace them with
Configuration replacementValues = context.getReplacementVariableValues();
- if (replacementValues == null) {
- return input;
- }
-
TemplateEngine templateEngine = null;
StringBuffer buffer = new StringBuffer();
Matcher matcher = this.replacementVariableDeclarationPattern.matcher(input);
@@ -172,7 +173,7 @@ public class RecipeParser {
Matcher nameMatcher = this.replacementVariableNamePattern.matcher(next);
if (nameMatcher.find()) {
String key = nameMatcher.group();
- String value = replacementValues.getSimpleValue(key, null);
+ String value = (replacementValues != null) ? replacementValues.getSimpleValue(key, null) : null;
if (value == null) {
// our replacement values don't know how to replace the key, see if our system info template engine can
if (templateEngine == null) {
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ScriptRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ScriptRecipeCommand.java
index 2173c06..99a0c7c 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ScriptRecipeCommand.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ScriptRecipeCommand.java
@@ -32,7 +32,7 @@ public class ScriptRecipeCommand implements RecipeCommand {
return "script";
}
- public void parse(RecipeContext context, String[] args) {
+ public void parse(RecipeParser parser, RecipeContext context, String[] args) {
if (args == null || args.length == 0) {
throw new IllegalArgumentException("Missing the script command to execute");
diff --git a/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
index 7d5abef..bfa58e6 100644
--- a/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
+++ b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
@@ -40,6 +40,16 @@ public class RecipeParserTest {
cleanRecipe();
}
+ public void testRealizeRecipe() throws Exception {
+ addRecipeCommand("realize --file=<%opt.dir%>/config.ini");
+ RecipeParser parser = new RecipeParser();
+ RecipeContext context = new RecipeContext(getRecipe());
+ parser.parseRecipe(context);
+ Set<String> files = context.getRealizedFiles();
+ assert files.size() == 1 : files;
+ assert files.contains("<%opt.dir%>/config.ini") : files;
+ }
+
public void testFileRecipe() throws Exception {
addRecipeCommand("file --source=run-me.sh --destination=/opt/run.sh");
addRecipeCommand("file -s META-INF/another.xml -d /etc/another.xml");
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
index b0ae578..ffe24f2 100644
--- a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
@@ -19,13 +19,17 @@
package org.rhq.plugins.filetemplate;
+import java.io.BufferedReader;
import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.rhq.bundle.filetemplate.recipe.RecipeContext;
+import org.rhq.bundle.filetemplate.recipe.RecipeParser;
import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.system.ProcessExecution;
import org.rhq.core.system.ProcessExecutionResults;
@@ -87,6 +91,60 @@ public class ProcessingRecipeContext extends RecipeContext {
}
@Override
+ public void addRealizedFile(String file) {
+ super.addRealizedFile(file);
+
+ File trueFile = new File(file);
+ RecipeParser parser = getParser();
+ File realizedTmpFile = null;
+ FileWriter realizedTmpFileWriter = null;
+ BufferedReader reader = null;
+
+ try {
+
+ realizedTmpFile = File.createTempFile("rhq-realize-", ".tmp", trueFile.getParentFile());
+ realizedTmpFileWriter = new FileWriter(realizedTmpFile);
+
+ reader = new BufferedReader(new FileReader(trueFile));
+ String line = reader.readLine();
+ while (line != null) {
+ line = parser.replaceReplacementVariables(this, line);
+ realizedTmpFileWriter.write(line);
+ realizedTmpFileWriter.write("\n");
+ line = reader.readLine();
+ }
+
+ realizedTmpFileWriter.close();
+ realizedTmpFileWriter = null;
+ reader.close();
+ reader = null;
+
+ trueFile.delete(); // remove the one with the replacement variables in it
+ if (!realizedTmpFile.renameTo(trueFile)) {
+ throw new RuntimeException("Failed to rename realized tmp file [" + realizedTmpFile + "]");
+ }
+ } catch (Exception e) {
+ throw new RuntimeException("Cannot realize file [" + file + "]", e);
+ } finally {
+ if (realizedTmpFileWriter != null) {
+ try {
+ realizedTmpFileWriter.close();
+ } catch (Exception e) {
+ }
+ }
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (Exception e) {
+ }
+ }
+ if (realizedTmpFile != null && realizedTmpFile.exists()) {
+ realizedTmpFile.delete();
+ }
+ }
+ }
+
+ @Override
public void addReplacementVariables(Set<String> replacementVariables) {
super.addReplacementVariables(replacementVariables);
}
commit 3c52854a359fa4fb4fae21fc4d0b9323d0ee800b
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Mar 2 19:03:52 2010 -0500
support the file recipe command
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/FileRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/FileRecipeCommand.java
new file mode 100644
index 0000000..3b74805
--- /dev/null
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/FileRecipeCommand.java
@@ -0,0 +1,85 @@
+/*
+ * 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, 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.bundle.filetemplate.recipe;
+
+import gnu.getopt.Getopt;
+import gnu.getopt.LongOpt;
+
+public class FileRecipeCommand implements RecipeCommand {
+
+ public String getName() {
+ return "file";
+ }
+
+ public void parse(RecipeContext context, String[] args) {
+ String sopts = ":s:d:";
+ LongOpt[] lopts = { new LongOpt("source", LongOpt.REQUIRED_ARGUMENT, null, 's'),
+ new LongOpt("destination", LongOpt.REQUIRED_ARGUMENT, null, 'd') };
+
+ String source = null;
+ String destination = null;
+
+ Getopt getopt = new Getopt(context.toString(), args, sopts, lopts);
+ int code;
+
+ while ((code = getopt.getopt()) != -1) {
+ switch (code) {
+ case ':':
+ case '?': {
+ throw new IllegalArgumentException("Bad recipe command.");
+ }
+
+ case 1: {
+ throw new IllegalArgumentException("Bad recipe command!");
+ }
+
+ case 's': {
+ source = getopt.getOptarg();
+ break;
+ }
+
+ case 'd': {
+ destination = getopt.getOptarg();
+ break;
+ }
+
+ default: {
+ throw new IllegalArgumentException("Unexpected error in recipe command");
+ }
+
+ }
+ }
+
+ if (source == null) {
+ throw new IllegalArgumentException("Did not specify the source file to copy");
+ }
+
+ if (destination == null) {
+ throw new IllegalArgumentException("Did not specify the destination where the file should be copied");
+ }
+
+ context.addFile(source, destination);
+ return;
+ }
+}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
index fb911f3..dcea274 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
@@ -42,6 +42,7 @@ public class RecipeContext {
private final String recipe;
private final Map<String, String> deployFiles;
+ private final Map<String, String> files;
private final Set<String> replacementVariables;
private Configuration replacementVariableValues;
private final List<Script> scripts;
@@ -49,6 +50,7 @@ public class RecipeContext {
public RecipeContext(String recipe) {
this.recipe = recipe;
this.deployFiles = new HashMap<String, String>();
+ this.files = new HashMap<String, String>();
this.replacementVariables = new HashSet<String>();
this.scripts = new ArrayList<Script>();
}
@@ -77,6 +79,22 @@ public class RecipeContext {
}
/**
+ * Returns all the files that are strictly to be copied to some location.
+ * The key is the bundle file's name, the value is the full path and filename where
+ * the file should be copied to. No processing of these files will occur other than
+ * they are copied.
+ *
+ * @return map of all files to be deployed and the location where they are to be deployed
+ */
+ public Map<String, String> getFiles() {
+ return this.files;
+ }
+
+ public void addFile(String source, String destination) {
+ this.files.put(source, destination);
+ }
+
+ /**
* The names of all replacement variables that are found in the recipe.
*
* @return the replacement variables
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
index d18fd4b..13644e6 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
@@ -111,7 +111,11 @@ public class RecipeParser {
context.addReplacementVariables(replacementVars);
}
- recipeCommand.parse(context, arguments);
+ try {
+ recipeCommand.parse(context, arguments);
+ } catch (Exception e) {
+ throw new Exception("Error in recipe, line [" + line + "]", e);
+ }
return;
}
@@ -120,6 +124,7 @@ public class RecipeParser {
HashMap<String, RecipeCommand> commands = new HashMap<String, RecipeCommand>();
RecipeCommand[] knownCommands = new RecipeCommand[] { new ScriptRecipeCommand(), //
+ new FileRecipeCommand(), //
new DeployRecipeCommand() //
};
diff --git a/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
index 40bc7fb..7d5abef 100644
--- a/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
+++ b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
@@ -40,6 +40,20 @@ public class RecipeParserTest {
cleanRecipe();
}
+ public void testFileRecipe() throws Exception {
+ addRecipeCommand("file --source=run-me.sh --destination=/opt/run.sh");
+ addRecipeCommand("file -s META-INF/another.xml -d /etc/another.xml");
+ RecipeParser parser = new RecipeParser();
+ RecipeContext context = new RecipeContext(getRecipe());
+ parser.parseRecipe(context);
+ Map<String, String> files = context.getFiles();
+ assert files.size() == 2 : files;
+ assert files.get("run-me.sh") != null : files;
+ assert files.get("run-me.sh").equals("/opt/run.sh") : files;
+ assert files.get("META-INF/another.xml") != null : files;
+ assert files.get("META-INF/another.xml").equals("/etc/another.xml") : files;
+ }
+
public void testScriptRecipe() throws Exception {
addRecipeCommand("script run-me.sh");
addRecipeCommand("script lots-o-params.sh -d /opt/jboss -- foo.txt \"hello world\"");
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
index 2e0d1dc..b0ae578 100644
--- a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
@@ -76,6 +76,17 @@ public class ProcessingRecipeContext extends RecipeContext {
}
@Override
+ public void addFile(String filename, String directory) {
+ super.addDeployFile(filename, directory);
+
+ File existingFile = new File(this.baseWorkingDirectory, filename);
+ File newFile = new File(directory, filename);
+ if (!existingFile.renameTo(newFile)) {
+ throw new RuntimeException("Failed to move file [" + existingFile + "] to [" + newFile + "]");
+ }
+ }
+
+ @Override
public void addReplacementVariables(Set<String> replacementVariables) {
super.addReplacementVariables(replacementVariables);
}
commit 31cdbfd2db0c5220319665482b41984419dd4cbc
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Mar 2 18:14:44 2010 -0500
add script recipe command
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java
deleted file mode 100644
index 26d1b82..0000000
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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, 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.bundle.filetemplate.recipe;
-
-import gnu.getopt.Getopt;
-import gnu.getopt.LongOpt;
-
-/**
- * @deprecated I think this command will not be used - probably should delete it
- * @author mazz
- */
-public class ConfigdefRecipeCommand implements RecipeCommand {
-
- public String getName() {
- return "configdef";
- }
-
- public void parse(RecipeContext context, String[] args) {
- String sopts = ":f:";
- LongOpt[] lopts = { new LongOpt("file", LongOpt.REQUIRED_ARGUMENT, null, 'f') };
-
- String filename = null;
-
- Getopt getopt = new Getopt(context.toString(), args, sopts, lopts);
- int code;
-
- while ((code = getopt.getopt()) != -1) {
- switch (code) {
- case ':':
- case '?': {
- throw new IllegalArgumentException("Bad recipe argument.");
- }
-
- case 1: {
- throw new IllegalArgumentException("Bad recipe argument!");
- }
-
- case 'f': {
- filename = getopt.getOptarg();
- break;
- }
-
- default: {
- throw new IllegalArgumentException("Unexpected error in recipe command");
- }
- }
- }
-
- if (filename == null) {
- throw new IllegalArgumentException("Missing the -f argument to indicate what the config def filename is");
- }
-
- // TODO: what to do? can I delete this command entirely?
-
- return;
- }
-}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
index 43f0df1..fb911f3 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
@@ -23,8 +23,10 @@
package org.rhq.bundle.filetemplate.recipe;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -42,11 +44,13 @@ public class RecipeContext {
private final Map<String, String> deployFiles;
private final Set<String> replacementVariables;
private Configuration replacementVariableValues;
+ private final List<Script> scripts;
public RecipeContext(String recipe) {
this.recipe = recipe;
this.deployFiles = new HashMap<String, String>();
this.replacementVariables = new HashSet<String>();
+ this.scripts = new ArrayList<Script>();
}
/**
@@ -114,4 +118,68 @@ public class RecipeContext {
}
values.put(new PropertySimple(name, value));
}
+
+ /**
+ * Returns a set of all the names of scripts found in the recipe.
+ *
+ * @return script names
+ */
+ public Set<String> getScriptFiles() {
+ Set<String> scriptFiles = new HashSet<String>();
+ for (Script script : this.scripts) {
+ scriptFiles.add(script.getExecutable());
+ }
+ return scriptFiles;
+ }
+
+ /**
+ * Adds a script that the recipe wants invoked.
+ *
+ * @param exe the script executable
+ * @param exeArgs the arguments to pass to the script
+ */
+ public void addScript(String exe, List<String> exeArgs) {
+ this.scripts.add(new Script(exe, exeArgs));
+ }
+
+ class Script {
+ private final List<String> args;
+ private final String exe;
+
+ public Script(String exe, List<String> args) {
+ this.exe = exe;
+ this.args = args;
+ }
+
+ public String getExecutable() {
+ return exe;
+ }
+
+ public List<String> getArguments() {
+ return args;
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder str = new StringBuilder("RecipeContext:\n");
+ str.append("Recipe Text:\n").append(getRecipe()).append("\n");
+ str.append("Deploy Files: ").append(getDeployFiles()).append("\n");
+ str.append("Replacement Vars: ").append(getReplacementVariables()).append("\n");
+
+ str.append("Replacement Values: ");
+ Configuration values = getReplacementVariableValues();
+ if (values == null) {
+ str.append("<none>");
+ } else {
+ str.append(values.getProperties());
+ }
+ str.append("\n");
+
+ str.append("Script Files: ").append(getScriptFiles()).append("\n");
+ for (Script script : this.scripts) {
+ str.append("* ").append(script.getExecutable()).append(" ").append(script.getArguments()).append("\n");
+ }
+ return str.toString();
+ }
}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
index f8db1c8..d18fd4b 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
@@ -119,7 +119,7 @@ public class RecipeParser {
protected HashMap<String, RecipeCommand> createRecipeCommands() {
HashMap<String, RecipeCommand> commands = new HashMap<String, RecipeCommand>();
- RecipeCommand[] knownCommands = new RecipeCommand[] { new ConfigdefRecipeCommand(), //
+ RecipeCommand[] knownCommands = new RecipeCommand[] { new ScriptRecipeCommand(), //
new DeployRecipeCommand() //
};
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ScriptRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ScriptRecipeCommand.java
new file mode 100644
index 0000000..2173c06
--- /dev/null
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ScriptRecipeCommand.java
@@ -0,0 +1,51 @@
+/*
+ * 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, 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.bundle.filetemplate.recipe;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ScriptRecipeCommand implements RecipeCommand {
+
+ public String getName() {
+ return "script";
+ }
+
+ public void parse(RecipeContext context, String[] args) {
+
+ if (args == null || args.length == 0) {
+ throw new IllegalArgumentException("Missing the script command to execute");
+ }
+
+ String exe = args[0];
+ List<String> exeArgs = new ArrayList<String>(args.length - 1);
+ for (int i = 1; i < args.length; i++) {
+ exeArgs.add(args[i]);
+ }
+
+ context.addScript(exe, exeArgs);
+
+ return;
+ }
+}
diff --git a/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
index b2efdaf..40bc7fb 100644
--- a/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
+++ b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
@@ -24,6 +24,7 @@
package org.rhq.bundle.filetemplate.recipe;
import java.util.Map;
+import java.util.Set;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@@ -39,6 +40,19 @@ public class RecipeParserTest {
cleanRecipe();
}
+ public void testScriptRecipe() throws Exception {
+ addRecipeCommand("script run-me.sh");
+ addRecipeCommand("script lots-o-params.sh -d /opt/jboss -- foo.txt \"hello world\"");
+ addRecipeCommand("script run-me.sh with params");
+ RecipeParser parser = new RecipeParser();
+ RecipeContext context = new RecipeContext(getRecipe());
+ parser.parseRecipe(context);
+ Set<String> scripts = context.getScriptFiles();
+ assert scripts.size() == 2 : scripts;
+ assert scripts.contains("run-me.sh") : scripts;
+ assert scripts.contains("lots-o-params.sh") : scripts;
+ }
+
public void testSimpleRecipeReplacementVariables() throws Exception {
addRecipeCommand("# <% ignored.inside.comment %>");
addRecipeCommand("deploy -f jboss.tar -d \"<% opt.dir %>/jboss\"");
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 34902c0..99b8504 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
@@ -76,6 +76,8 @@ public class BundleServerPluginComponent implements ServerPluginComponent, Bundl
Set<String> bundleFileNames = new HashSet<String>();
Map<String, String> deployFiles = recipeContext.getDeployFiles();
bundleFileNames.addAll(deployFiles.keySet());
+ Set<String> scriptFiles = recipeContext.getScriptFiles();
+ bundleFileNames.addAll(scriptFiles);
ConfigurationDefinition configDef = null;
if (recipeContext.getReplacementVariables() != null) {
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
index 7f76757..cee69db 100644
--- a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
@@ -75,42 +75,25 @@ public class FileTemplateBundlePluginServerComponent implements ResourceComponen
List<PackageVersion> packageVersions = bundleManager.getAllBundleVersionPackageVersions(bundleVersion);
for (PackageVersion packageVersion : packageVersions) {
File packageFile = new File(tmpDir, packageVersion.getFileName());
- packageFile.getParentFile().mkdirs();
- FileOutputStream fos = new FileOutputStream(packageFile);
- try {
- long size = bundleManager.getFileContent(packageVersion, fos);
- if (packageVersion.getFileSize() != null && size != packageVersion.getFileSize().longValue()) {
- log.warn("Downloaded bundle file [" + packageVersion + "] but its size was [" + size
- + "] when it was expected to be [" + packageVersion.getFileSize() + "].");
- }
- } finally {
- fos.close();
- }
- // verify the content
- if (packageVersion.getMD5() != null) {
- String realMD5 = MessageDigestGenerator.getDigestString(packageFile);
- if (!packageVersion.getMD5().equals(realMD5)) {
- throw new Exception("Package version [" + packageVersion + "] failed MD5 check. expected=["
- + packageVersion.getMD5() + "], actual=[" + realMD5 + "]");
- }
- } else if (packageVersion.getSHA256() != null) {
- FileInputStream is = new FileInputStream(packageFile);
+ try {
+ verifyHash(packageVersion, packageFile);
+ } catch (Exception e) {
+ // file either doesn't exist or it hash doesn't match, download a new copy
+ packageFile.getParentFile().mkdirs();
+ FileOutputStream fos = new FileOutputStream(packageFile);
try {
- MessageDigestGenerator gen = new MessageDigestGenerator("SHA256");
- gen.add(is);
- String realSHA256 = gen.getDigestString();
- if (!packageVersion.getSHA256().equals(realSHA256)) {
- throw new Exception("Package version [" + packageVersion
- + "] failed SHA256 check. expected=[" + packageVersion.getSHA256() + "], actual=["
- + realSHA256 + "]");
+ long size = bundleManager.getFileContent(packageVersion, fos);
+ if (packageVersion.getFileSize() != null && size != packageVersion.getFileSize().longValue()) {
+ log.warn("Downloaded bundle file [" + packageVersion + "] but its size was [" + size
+ + "] when it was expected to be [" + packageVersion.getFileSize() + "].");
}
} finally {
- is.close();
+ fos.close();
}
- } else {
- log.debug("Package version [" + packageVersion + "] has no MD5/SHA256 hash - not verifying it");
+ // now try to verify it again, if this throws an exception, that is very bad and we need to abort
+ verifyHash(packageVersion, packageFile);
}
packageVersionFiles.put(packageVersion, packageFile);
@@ -131,4 +114,46 @@ public class FileTemplateBundlePluginServerComponent implements ResourceComponen
}
return result;
}
+
+ /**
+ * Checks to see if the package file's hash matches that of the given package version.
+ * If the file doesn't exist or the hash doesn't match, an exception is thrown.
+ * This method returns normally if the hash matches the file.
+ * If there is no known hash in the package version, this method returns normally.
+ *
+ * @param packageVersion contains the hash that is expected
+ * @param packageFile the local file whose hash is to be checked
+ * @throws Exception if the file does not match the hash or the file doesn't exist
+ */
+ private void verifyHash(PackageVersion packageVersion, File packageFile) throws Exception {
+ if (!packageFile.exists()) {
+ throw new Exception("Package version [" + packageVersion + "] does not exist, cannot check hash");
+ }
+
+ if (packageVersion.getMD5() != null) {
+ String realMD5 = MessageDigestGenerator.getDigestString(packageFile);
+ if (!packageVersion.getMD5().equals(realMD5)) {
+ throw new Exception("Package version [" + packageVersion + "] failed MD5 check. expected=["
+ + packageVersion.getMD5() + "], actual=[" + realMD5 + "]");
+ }
+ } else if (packageVersion.getSHA256() != null) {
+ FileInputStream is = new FileInputStream(packageFile);
+ try {
+ MessageDigestGenerator gen = new MessageDigestGenerator("SHA256");
+ gen.add(is);
+ String realSHA256 = gen.getDigestString();
+ if (!packageVersion.getSHA256().equals(realSHA256)) {
+ throw new Exception("Package version [" + packageVersion + "] failed SHA256 check. expected=["
+ + packageVersion.getSHA256() + "], actual=[" + realSHA256 + "]");
+ }
+ } finally {
+ is.close();
+ }
+
+ } else {
+ log.debug("Package version [" + packageVersion + "] has no MD5/SHA256 hash - not verifying it");
+ }
+
+ return;
+ }
}
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
index 1dbad78..2e0d1dc 100644
--- a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
@@ -80,6 +80,23 @@ public class ProcessingRecipeContext extends RecipeContext {
super.addReplacementVariables(replacementVariables);
}
+ @Override
+ public void addScript(String exe, List<String> exeArgs) {
+ super.addScript(exe, exeArgs);
+
+ File scriptFile = new File(this.baseWorkingDirectory, exe);
+
+ ProcessExecution pe = new ProcessExecution(scriptFile.getAbsolutePath());
+ pe.setArguments(exeArgs);
+ pe.setWaitForCompletion(30 * 60 * 1000L);
+ pe.setWorkingDirectory(scriptFile.getParent());
+
+ ProcessExecutionResults results = this.systemInfo.executeProcess(pe);
+ if (results.getError() != null) {
+ throw new RuntimeException("Could not execute script [" + pe + "]: " + results, results.getError());
+ }
+ }
+
private ProcessExecution getUnzipExecution(String filename, String directory) {
String exe;
List<String> args = null;
commit 870834d52077aebf478fc8c4eb420d095756d2e9
Merge: 3c61acc... f6fd9c9...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Tue Mar 2 16:11:25 2010 -0500
Merge branch 'bundle-jay' into bundle
Conflicts:
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
diff --cc modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
index a7cf52d,9e56e1e..1ca01c8
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
@@@ -65,10 -67,14 +67,10 @@@ public class BundleManagerBeanTest exte
public void beforeMethod() {
super.startTest();
- if (null == ps) {
- ps = new TestBundleServerPluginService();
- pc = ps.createMasterPluginContainer();
- } else {
- pc.initialize(ps.masterConfig);
- }
-
+ this.ps = new TestBundleServerPluginService();
+ prepareCustomServerPluginService(this.ps);
- bundleManagerBean = LookupUtil.getBundleManager();
+ bundleManager = LookupUtil.getBundleManager();
+ this.ps.startMasterPluginContainer();
}
@AfterMethod(alwaysRun = true)
commit f6fd9c9a4684c2eec48ee16fe4923d50203d8a80
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Tue Mar 2 16:06:42 2010 -0500
added a few more tests
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
index e8ac546..9e56e1e 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
@@ -33,8 +33,10 @@ import org.testng.annotations.Test;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.Bundle;
+import org.rhq.core.domain.bundle.BundleFile;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.Repo;
import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleVersionCriteria;
@@ -56,7 +58,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
private static final boolean ENABLED = true;
- private BundleManagerLocal bundleManagerBean;
+ private BundleManagerLocal bundleManager;
private TestBundleServerPluginService ps;
private MasterServerPluginContainer pc;
@@ -72,7 +74,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
pc.initialize(ps.masterConfig);
}
- bundleManagerBean = LookupUtil.getBundleManager();
+ bundleManager = LookupUtil.getBundleManager();
}
@AfterMethod(alwaysRun = true)
@@ -112,6 +114,12 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
em.remove(em.getReference(BundleType.class, ((BundleType) removeMe).getId()));
}
+ q = em.createQuery("SELECT pt FROM PackageType pt WHERE pt.name LIKE '" + TEST_PREFIX + "%'");
+ doomed = q.getResultList();
+ for (Object removeMe : doomed) {
+ em.remove(em.getReference(PackageType.class, ((PackageType) removeMe).getId()));
+ }
+
q = em.createQuery("SELECT rt FROM ResourceType rt WHERE rt.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
for (Object removeMe : doomed) {
@@ -144,7 +152,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
public void testGetBundleTypes() throws Exception {
BundleType bt1 = createBundleType("one");
BundleType bt2 = createBundleType("two");
- List<BundleType> bts = bundleManagerBean.getAllBundleTypes(LookupUtil.getSubjectManager().getOverlord());
+ List<BundleType> bts = bundleManager.getAllBundleTypes(LookupUtil.getSubjectManager().getOverlord());
assert bts.size() >= 2 : "should have at least 2 bundle types";
List<String> btNames = new ArrayList<String>();
@@ -157,6 +165,36 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
}
@Test(enabled = ENABLED)
+ public void testCreateBundle() throws Exception {
+ Bundle b1 = createBundle("one");
+ assertNotNull(b1);
+ }
+
+ @Test(enabled = ENABLED)
+ public void testCreateBundleVersion() throws Exception {
+ Bundle b1 = createBundle("one");
+ assertNotNull(b1);
+ BundleVersion bv1 = createBundleVersion(b1.getName() + "-1", null, b1);
+ assertNotNull(bv1);
+ assertEquals("1.0", bv1.getVersion());
+ BundleVersion bv2 = createBundleVersion(b1.getName() + "-2", null, b1);
+ assertNotNull(bv2);
+ assertEquals("1.1", bv2.getVersion());
+ }
+
+ @Test(enabled = ENABLED)
+ public void testAddBundleFiles() throws Exception {
+ Bundle b1 = createBundle("one");
+ assertNotNull(b1);
+ BundleVersion bv1 = createBundleVersion(b1.getName(), "1.0", b1);
+ assertNotNull(bv1);
+ BundleFile bf1 = bundleManager.addBundleFileViaByteArray(getOverlord(), bv1.getId(), TEST_PREFIX
+ + "-bundlefile-1", "1.0", null, "Test Bundle File # 1".getBytes(), false);
+ BundleFile bf2 = bundleManager.addBundleFileViaByteArray(getOverlord(), bv1.getId(), TEST_PREFIX
+ + "-bundlefile-2", "1.0", null, "Test Bundle File # 2".getBytes(), false);
+ }
+
+ @Test(enabled = ENABLED)
public void testfindBundlesByCriteria() throws Exception {
Bundle b1 = createBundle("one");
Bundle b2 = createBundle("two");
@@ -168,7 +206,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
String name = null;
// return all with no optional data
- bundles = bundleManagerBean.findBundlesByCriteria(getOverlord(), c);
+ bundles = bundleManager.findBundlesByCriteria(getOverlord(), c);
assertNotNull(bundles);
assertEquals(2, bundles.size());
b = bundles.get(0);
@@ -197,7 +235,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
c.addFilterBundleTypeName(b.getName());
c.fetchBundleVersions(true);
c.fetchRepo(true);
- bundles = bundleManagerBean.findBundlesByCriteria(getOverlord(), c);
+ bundles = bundleManager.findBundlesByCriteria(getOverlord(), c);
assertNotNull(bundles);
assertEquals(1, bundles.size());
b = bundles.get(0);
@@ -224,7 +262,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
BundleVersion bv = null;
// return all with no optional data
- bvs = bundleManagerBean.findBundleVersionsByCriteria(getOverlord(), c);
+ bvs = bundleManager.findBundleVersionsByCriteria(getOverlord(), c);
bv = bvs.get(1);
assertNotNull(bvs);
assertEquals(3, bvs.size());
@@ -238,7 +276,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
c.fetchBundle(true);
c.fetchDistribution(true);
c.fetchBundleDeployDefinitions(true);
- bvs = bundleManagerBean.findBundleVersionsByCriteria(getOverlord(), c);
+ bvs = bundleManager.findBundleVersionsByCriteria(getOverlord(), c);
assertNotNull(bvs);
assertEquals(1, bvs.size());
bv = bvs.get(0);
@@ -251,7 +289,9 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
private BundleType createBundleType(String name) throws Exception {
final String fullName = TEST_PREFIX + "-type-" + name;
- BundleType bt = bundleManagerBean.createBundleType(getOverlord(), fullName, createResourceType(name).getId());
+ ResourceType rt = createResourceType(name);
+ PackageType pt = createPackageType(name, rt);
+ BundleType bt = bundleManager.createBundleType(getOverlord(), fullName, rt.getId());
assert bt.getId() > 0;
assert bt.getName().endsWith(fullName);
@@ -265,7 +305,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
private Bundle createBundle(String name, BundleType bt) throws Exception {
final String fullName = TEST_PREFIX + "-bundle-" + name;
- Bundle b = bundleManagerBean.createBundle(getOverlord(), fullName, bt.getId());
+ Bundle b = bundleManager.createBundle(getOverlord(), fullName, bt.getId());
assert b.getId() > 0;
assert b.getName().endsWith(fullName);
@@ -273,10 +313,9 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
}
private BundleVersion createBundleVersion(String name, String version, Bundle bundle) throws Exception {
- final String fullName = TEST_PREFIX + "-version-" + version + "-" + name;
+ final String fullName = TEST_PREFIX + "-bundleversion-" + version + "-" + name;
final String recipe = "deploy -f " + TEST_PREFIX + ".zip -d <% test.path %>";
- BundleVersion bv = bundleManagerBean.createBundleVersion(getOverlord(), bundle.getId(), fullName, version,
- recipe);
+ BundleVersion bv = bundleManager.createBundleVersion(getOverlord(), bundle.getId(), fullName, version, recipe);
assert bv.getId() > 0;
assert bv.getName().endsWith(fullName);
@@ -296,6 +335,19 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
return rt;
}
+ private PackageType createPackageType(String name, ResourceType rt) throws Exception {
+ final String fullName = TEST_PREFIX + "-packagetype-" + name;
+ PackageType pt = new PackageType(fullName, rt);
+
+ TransactionManager txMgr = getTransactionManager();
+ txMgr.begin();
+ EntityManager em = getEntityManager();
+ em.persist(pt);
+ em.close();
+ txMgr.commit();
+ return pt;
+ }
+
private Subject getOverlord() {
return LookupUtil.getSubjectManager().getOverlord();
}
commit 3c61acc239ef4eb7e4bdd086cb5f533ca845e1c8
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Mar 2 15:57:09 2010 -0500
fix bundle test so the mock PC is started properly
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
index e8ac546..a7cf52d 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
@@ -65,18 +65,14 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
public void beforeMethod() {
super.startTest();
- if (null == ps) {
- ps = new TestBundleServerPluginService();
- pc = ps.createMasterPluginContainer();
- } else {
- pc.initialize(ps.masterConfig);
- }
-
+ this.ps = new TestBundleServerPluginService();
+ prepareCustomServerPluginService(this.ps);
bundleManagerBean = LookupUtil.getBundleManager();
+ this.ps.startMasterPluginContainer();
}
@AfterMethod(alwaysRun = true)
- public void afterMethod() {
+ public void afterMethod() throws Exception {
EntityManager em = null;
@@ -133,9 +129,8 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
}
}
- if (null != pc) {
- pc.shutdown();
- }
+ unprepareServerPluginService();
+ this.ps = null;
super.endTest();
}
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 dcbc951..64bd5af 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
@@ -39,18 +39,15 @@ import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment;
import org.rhq.enterprise.server.plugin.pc.ServerPluginManager;
import org.rhq.enterprise.server.plugin.pc.ServerPluginService;
import org.rhq.enterprise.server.plugin.pc.ServerPluginType;
-import org.rhq.enterprise.server.plugin.pc.generic.GenericServerPluginContainer;
-import org.rhq.enterprise.server.plugin.pc.generic.TestGenericServerPluginServiceMBean;
+import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginManager;
import org.rhq.enterprise.server.xmlschema.ServerPluginDescriptorMetadataParser;
import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType;
/**
- * Used as a mock service for the generic server plugin container.
+ * Used as a mock service for the bundle server plugin container.
*/
-public class TestBundleServerPluginService extends ServerPluginService implements TestGenericServerPluginServiceMBean {
- public enum State {
- INITIALIZED, STARTED, STOPPED, UNINITIALIZED
- }
+public class TestBundleServerPluginService extends ServerPluginService implements TestBundleServerPluginServiceMBean {
// public so tests can directly set these
public TestMasterServerPluginContainer master;
@@ -105,9 +102,7 @@ public class TestBundleServerPluginService extends ServerPluginService implement
}
}
- public class TestBundleServerPluginContainer extends GenericServerPluginContainer {
- public State state = State.UNINITIALIZED;
-
+ public class TestBundleServerPluginContainer extends BundleServerPluginContainer {
public TestBundleServerPluginContainer(MasterServerPluginContainer master) {
super(master);
}
@@ -117,56 +112,12 @@ public class TestBundleServerPluginService extends ServerPluginService implement
TestBundlePluginManager pm = new TestBundlePluginManager(this);
return pm;
}
-
- @Override
- public synchronized void initialize() throws Exception {
- if (state == State.UNINITIALIZED) {
- state = State.INITIALIZED;
- } else {
- System.out.println("!!! PC LIFECYCLE WAS BAD - THIS IS A BUG !!!");
- throw new IllegalStateException("not uninitialized: " + state);
- }
- super.initialize();
- }
-
- @Override
- public synchronized void start() {
- if (state == State.INITIALIZED) {
- state = State.STARTED;
- } else {
- System.out.println("!!! PC LIFECYCLE WAS BAD - THIS IS A BUG !!!");
- throw new IllegalStateException("not initialized: " + state);
- }
- super.start();
- }
-
- @Override
- public synchronized void stop() {
- if (state == State.STARTED) {
- state = State.STOPPED;
- } else {
- System.out.println("!!! PC LIFECYCLE WAS BAD - THIS IS A BUG !!!");
- throw new IllegalStateException("not started: " + state);
- }
- super.stop();
- }
-
- @Override
- public synchronized void shutdown() {
- if (state == State.STOPPED) {
- state = State.UNINITIALIZED;
- } else {
- System.out.println("!!! PC LIFECYCLE WAS BAD - THIS IS A BUG !!!");
- throw new IllegalStateException("not stopped: " + state);
- }
- super.shutdown();
- }
}
/**
* The test plugin manager.
*/
- class TestBundlePluginManager extends ServerPluginManager {
+ class TestBundlePluginManager extends BundleServerPluginManager {
public final Map<String, ServerPluginComponent> components;
public TestBundlePluginManager(TestBundleServerPluginContainer pc) {
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/TestBundleServerPluginServiceMBean.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/TestBundleServerPluginServiceMBean.java
new file mode 100644
index 0000000..80b2d7f
--- /dev/null
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/TestBundleServerPluginServiceMBean.java
@@ -0,0 +1,24 @@
+/*
+ * 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.bundle;
+
+import org.rhq.enterprise.server.plugin.pc.ServerPluginServiceManagement;
+
+public interface TestBundleServerPluginServiceMBean extends ServerPluginServiceManagement {
+}
\ No newline at end of file
commit 3a19b87d9f21a5ffa2df1ed6ea2d06421310adb1
Merge: 85ce0d5... cdccd36...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Tue Mar 2 15:14:51 2010 -0500
Merge branch 'bundle' into bundle-jay
commit cdccd367c9fd398dffba8e7fe6df5fab88fa772a
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Mar 2 15:12:37 2010 -0500
opps.. forgot to use the new constructor
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
index 3fe2852..7f76757 100644
--- a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
@@ -112,12 +112,15 @@ public class FileTemplateBundlePluginServerComponent implements ResourceComponen
} else {
log.debug("Package version [" + packageVersion + "] has no MD5/SHA256 hash - not verifying it");
}
+
+ packageVersionFiles.put(packageVersion, packageFile);
}
// process the recipe
String recipe = bundleVersion.getRecipe();
RecipeParser parser = new RecipeParser();
- ProcessingRecipeContext recipeContext = new ProcessingRecipeContext(recipe);
+ ProcessingRecipeContext recipeContext = new ProcessingRecipeContext(recipe, packageVersionFiles,
+ this.resourceContext.getSystemInformation(), tmpDir.getAbsolutePath());
recipeContext.setReplacementVariableValues(bundleDeployDef.getConfiguration());
parser.setReplaceReplacementVariables(true);
parser.parseRecipe(recipeContext);
commit 967a5f2371cb77591801bfd8d3dd97e3eb44a355
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Mar 2 15:10:53 2010 -0500
more bundle processing stuff - this attempts to process the deploy command
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
index c895107..43f0df1 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
@@ -28,6 +28,9 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.PropertySimple;
+
/**
* Contains information that is gleened from a recipe after it is parsed.
*
@@ -38,6 +41,7 @@ public class RecipeContext {
private final String recipe;
private final Map<String, String> deployFiles;
private final Set<String> replacementVariables;
+ private Configuration replacementVariableValues;
public RecipeContext(String recipe) {
this.recipe = recipe;
@@ -81,4 +85,33 @@ public class RecipeContext {
this.replacementVariables.addAll(replacementVariables);
}
+ /**
+ * If known, the returned value will contain values that are to be used to replace
+ * replacement variables found in the recipe.
+ *
+ * @return the replacement variable values
+ */
+ public Configuration getReplacementVariableValues() {
+ return this.replacementVariableValues;
+ }
+
+ public void setReplacementVariableValues(Configuration configuration) {
+ this.replacementVariableValues = configuration;
+ }
+
+ /**
+ * Adds the given name/value pair to the set of replacement variable values associated
+ * with this context.
+ *
+ * @param name
+ * @param value
+ */
+ public void addReplacementVariableValue(String name, String value) {
+ Configuration values = getReplacementVariableValues();
+ if (values == null) {
+ values = new Configuration();
+ setReplacementVariableValues(values);
+ }
+ values.put(new PropertySimple(name, value));
+ }
}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
index df797f4..f8db1c8 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
@@ -37,6 +37,10 @@ import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.system.SystemInfoFactory;
+import org.rhq.core.template.TemplateEngine;
+
/**
* Parses the file template recipe.
*
@@ -46,27 +50,41 @@ import java.util.regex.Pattern;
public class RecipeParser {
private Map<String, RecipeCommand> recipeCommands;
- // note that we use the same as the core util's template engine
- // the native system replacement variable prefix is used by the agent-side fact variable names
- private final Pattern replacementVariableDeclarationPattern = Pattern.compile("<%\\s*(\\w+\\.?)+\\s*%>");
- private final Pattern replacementVariableNamePattern = Pattern.compile("(\\w+\\.?)+");
- private final String systemReplacementVariablePrefix = "rhq.system.";
+ private Pattern replacementVariableDeclarationPattern;
+ private Pattern replacementVariableNamePattern;
+ private String systemReplacementVariablePrefix;
+ private boolean replaceVariables = false;
public RecipeParser() {
- setupRecipeCommands();
+ this.recipeCommands = createRecipeCommands();
+ setupReplacementPatterns();
+ }
+
+ /**
+ * If the parser should replace replacement variables with their corresponding values (as found in
+ * the parser context), <code>true</code> is returned. If <code>false</code> then the replacement
+ * variables remain as is when they are passed to their command processor objects.
+ *
+ * @return flag
+ */
+ public boolean isReplaceReplacementVariables() {
+ return this.replaceVariables;
}
- public RecipeContext parseRecipe(String recipe) throws Exception {
- RecipeContext context = new RecipeContext(recipe);
+ public void setReplaceReplacementVariables(boolean flag) {
+ this.replaceVariables = flag;
+ }
+
+ public void parseRecipe(RecipeContext context) throws Exception {
- BufferedReader recipeReader = new BufferedReader(new StringReader(recipe));
+ BufferedReader recipeReader = new BufferedReader(new StringReader(context.getRecipe()));
String line = recipeReader.readLine();
while (line != null) {
parseRecipeCommandLine(context, line);
line = recipeReader.readLine();
}
- return context;
+ return;
}
public void parseRecipeCommandLine(RecipeContext context, String line) throws Exception {
@@ -75,11 +93,15 @@ public class RecipeParser {
return;
}
+ if (isReplaceReplacementVariables()) {
+ line = replaceReplacementVariables(context, line);
+ }
+
String[] commandLineArray = splitCommandLine(line);
String commandName = commandLineArray[0];
String[] arguments = extractArguments(commandLineArray);
- RecipeCommand recipeCommand = recipeCommands.get(commandName);
+ RecipeCommand recipeCommand = this.recipeCommands.get(commandName);
if (recipeCommand == null) {
throw new Exception("Unknown command in recipe: " + commandName);
}
@@ -94,28 +116,30 @@ public class RecipeParser {
return;
}
- private void setupRecipeCommands() {
- recipeCommands = new HashMap<String, RecipeCommand>();
+ protected HashMap<String, RecipeCommand> createRecipeCommands() {
+ HashMap<String, RecipeCommand> commands = new HashMap<String, RecipeCommand>();
RecipeCommand[] knownCommands = new RecipeCommand[] { new ConfigdefRecipeCommand(), //
new DeployRecipeCommand() //
};
for (RecipeCommand recipeCommand : knownCommands) {
- recipeCommands.put(recipeCommand.getName(), recipeCommand);
+ commands.put(recipeCommand.getName(), recipeCommand);
}
+
+ return commands;
}
- private Set<String> getReplacementVariables(String cmdLine) {
+ protected Set<String> getReplacementVariables(String cmdLine) {
Set<String> replacementVariables = null;
Matcher matcher = this.replacementVariableDeclarationPattern.matcher(cmdLine);
while (matcher.find()) {
String replacementDeclaration = matcher.group();
- Matcher matcherInner = this.replacementVariableNamePattern.matcher(replacementDeclaration);
- if (!matcherInner.find()) {
+ Matcher nameMatcher = this.replacementVariableNamePattern.matcher(replacementDeclaration);
+ if (!nameMatcher.find()) {
throw new IllegalArgumentException("Bad replacement declaration [" + replacementDeclaration + "]");
}
- String replacementVariable = matcherInner.group();
+ String replacementVariable = nameMatcher.group();
if (!replacementVariable.startsWith(this.systemReplacementVariablePrefix)) {
if (replacementVariables == null) {
replacementVariables = new HashSet<String>(1);
@@ -127,7 +151,43 @@ public class RecipeParser {
return replacementVariables;
}
- private String[] splitCommandLine(String cmdLine) {
+ protected String replaceReplacementVariables(RecipeContext context, String input) {
+
+ // don't bother if we have no values to replace them with
+ Configuration replacementValues = context.getReplacementVariableValues();
+ if (replacementValues == null) {
+ return input;
+ }
+
+ TemplateEngine templateEngine = null;
+ StringBuffer buffer = new StringBuffer();
+ Matcher matcher = this.replacementVariableDeclarationPattern.matcher(input);
+ while (matcher.find()) {
+ String next = matcher.group();
+ Matcher nameMatcher = this.replacementVariableNamePattern.matcher(next);
+ if (nameMatcher.find()) {
+ String key = nameMatcher.group();
+ String value = replacementValues.getSimpleValue(key, null);
+ if (value == null) {
+ // our replacement values don't know how to replace the key, see if our system info template engine can
+ if (templateEngine == null) {
+ templateEngine = SystemInfoFactory.fetchTemplateEngine();
+ }
+ value = templateEngine.replaceTokens(next);
+ }
+ if (value != null) {
+ next = value;
+ }
+ }
+
+ // If we didn't find a replacement for the key then leave the original value unchanged
+ matcher.appendReplacement(buffer, next);
+ }
+ matcher.appendTail(buffer);
+ return buffer.toString();
+ }
+
+ protected String[] splitCommandLine(String cmdLine) {
ByteArrayInputStream in = new ByteArrayInputStream(cmdLine.getBytes());
StreamTokenizer strtok = new StreamTokenizer(new InputStreamReader(in));
List<String> args = new ArrayList<String>();
@@ -163,11 +223,20 @@ public class RecipeParser {
return args.toArray(new String[args.size()]);
}
- private String[] extractArguments(String[] commandLine) {
+ protected String[] extractArguments(String[] commandLine) {
// strip the first element (the command name) from the array, leaving only the arguments
int newLength = commandLine.length - 1;
String[] argsOnly = new String[newLength];
System.arraycopy(commandLine, 1, argsOnly, 0, newLength);
return argsOnly;
}
+
+ private void setupReplacementPatterns() {
+ // note that we use the same as the core util's template engine
+ // the native system replacement variable prefix is used by the agent-side fact variable names
+ this.replacementVariableDeclarationPattern = Pattern.compile("<%\\s*(\\w+\\.?)+\\s*%>");
+ this.replacementVariableNamePattern = Pattern.compile("(\\w+\\.?)+");
+ this.systemReplacementVariablePrefix = SystemInfoFactory.TOKEN_PREFIX;
+ }
+
}
diff --git a/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
index 7d58b88..b2efdaf 100644
--- a/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
+++ b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
@@ -28,6 +28,8 @@ import java.util.Map;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
+import org.rhq.core.system.SystemInfoFactory;
+
@Test
public class RecipeParserTest {
private StringBuilder recipe;
@@ -43,7 +45,8 @@ public class RecipeParserTest {
addRecipeCommand("deploy -f tomcat.tar -d <%opt.dir%>/tomcat");
addRecipeCommand("deploy -f jboss.zip -d <%rhq.system.hostname%>/opt/tomcat"); // this is ignored, its an agent fact variable
RecipeParser parser = new RecipeParser();
- RecipeContext context = parser.parseRecipe(getRecipe());
+ RecipeContext context = new RecipeContext(getRecipe());
+ parser.parseRecipe(context);
Map<String, String> files = context.getDeployFiles();
assert files.containsKey("jboss.tar") : files;
assert files.get("jboss.tar").equals("<% opt.dir %>/jboss") : files;
@@ -55,11 +58,30 @@ public class RecipeParserTest {
assert context.getReplacementVariables().size() == 1 : context.getReplacementVariables();
}
+ public void testSimpleRecipeReplaceReplacementVariables() throws Exception {
+ addRecipeCommand("deploy -f jboss.tar -d <% opt.dir %>/jboss");
+ addRecipeCommand("deploy -f jboss2.tar -d <%unknown%>/jboss");
+ addRecipeCommand("deploy -f jboss3.tar -d <% rhq.system.hostname %>/jboss");
+ RecipeParser parser = new RecipeParser();
+ parser.setReplaceReplacementVariables(true);
+ RecipeContext context = new RecipeContext(getRecipe());
+ context.addReplacementVariableValue("opt.dir", "/foo/bar");
+ parser.parseRecipe(context);
+ Map<String, String> files = context.getDeployFiles();
+ assert files.containsKey("jboss.tar") : files;
+ assert files.get("jboss.tar").equals("/foo/bar/jboss") : files;
+ assert files.containsKey("jboss2.tar") : files;
+ assert files.get("jboss2.tar").equals("<%unknown%>/jboss") : files;
+ assert files.containsKey("jboss3.tar") : files;
+ assert files.get("jboss3.tar").equals(SystemInfoFactory.createSystemInfo().getHostname() + "/jboss") : files;
+ }
+
public void testSimpleRecipe() throws Exception {
addRecipeCommand("deploy -f jboss.tar -d /opt/jboss");
addRecipeCommand("deploy -f tomcat.tar -d /opt/tomcat");
RecipeParser parser = new RecipeParser();
- RecipeContext context = parser.parseRecipe(getRecipe());
+ RecipeContext context = new RecipeContext(getRecipe());
+ parser.parseRecipe(context);
Map<String, String> files = context.getDeployFiles();
assert files.containsKey("jboss.tar") : files;
assert files.get("jboss.tar").equals("/opt/jboss") : files;
@@ -72,7 +94,8 @@ public class RecipeParserTest {
addRecipeCommand("deploy -f jboss.tar --directory='/opt/jboss'");
addRecipeCommand("deploy -f tomcat.tar \"--directory=/opt/tomcat\"");
RecipeParser parser = new RecipeParser();
- RecipeContext context = parser.parseRecipe(getRecipe());
+ RecipeContext context = new RecipeContext(getRecipe());
+ parser.parseRecipe(context);
Map<String, String> files = context.getDeployFiles();
assert files.containsKey("jboss1.zip") : files;
assert files.get("jboss1.zip").equals("/opt/jboss1") : files;
@@ -87,7 +110,8 @@ public class RecipeParserTest {
RecipeParser parser = new RecipeParser();
try {
- parser.parseRecipe(getRecipe());
+ RecipeContext context = new RecipeContext(getRecipe());
+ parser.parseRecipe(context);
assert false : "This should have failed - need to provide a -d to the deploy command";
} catch (Exception ok) {
// to be expected
@@ -97,7 +121,8 @@ public class RecipeParserTest {
addRecipeCommand("deploy -d /opt/jboss");
try {
- parser.parseRecipe(getRecipe());
+ RecipeContext context = new RecipeContext(getRecipe());
+ parser.parseRecipe(context);
assert false : "This should have failed - need to provide a -f to the deploy command";
} catch (Exception ok) {
// to be expected
@@ -118,7 +143,8 @@ public class RecipeParserTest {
addRecipeCommand("### comment here");
addRecipeCommand("");
RecipeParser parser = new RecipeParser();
- RecipeContext context = parser.parseRecipe(getRecipe());
+ RecipeContext context = new RecipeContext(getRecipe());
+ parser.parseRecipe(context);
Map<String, String> files = context.getDeployFiles();
assert files.containsKey("jboss.tar") : files;
assert files.get("jboss.tar").equals("/opt/jboss") : files;
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 147f2a5..34902c0 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
@@ -70,16 +70,17 @@ public class BundleServerPluginComponent implements ServerPluginComponent, Bundl
public RecipeParseResults parseRecipe(String recipe) throws Exception {
RecipeParser parser = new RecipeParser();
- RecipeContext parserContext = parser.parseRecipe(recipe);
+ RecipeContext recipeContext = new RecipeContext(recipe);
+ parser.parseRecipe(recipeContext);
Set<String> bundleFileNames = new HashSet<String>();
- Map<String, String> deployFiles = deployFiles = parserContext.getDeployFiles();
+ Map<String, String> deployFiles = recipeContext.getDeployFiles();
bundleFileNames.addAll(deployFiles.keySet());
ConfigurationDefinition configDef = null;
- if (parserContext.getReplacementVariables() != null) {
+ if (recipeContext.getReplacementVariables() != null) {
configDef = new ConfigurationDefinition("replacementVariables", null);
- for (String replacementVar : parserContext.getReplacementVariables()) {
+ for (String replacementVar : recipeContext.getReplacementVariables()) {
PropertyDefinitionSimple prop = new PropertyDefinitionSimple(replacementVar, null, false,
PropertySimpleType.STRING);
configDef.put(prop);
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
index a1320ad..3fe2852 100644
--- a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
@@ -21,11 +21,14 @@ package org.rhq.plugins.filetemplate;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.rhq.bundle.filetemplate.recipe.RecipeParser;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.content.PackageVersion;
@@ -66,6 +69,7 @@ public class FileTemplateBundlePluginServerComponent implements ResourceComponen
BundleVersion bundleVersion = bundleDeployDef.getBundleVersion();
// download all the bundle files to our tmp directory
+ Map<PackageVersion, File> packageVersionFiles = new HashMap<PackageVersion, File>();
File tmpDir = new File(this.resourceContext.getTemporaryDirectory(), "" + bundleVersion.getId());
BundleManagerProvider bundleManager = request.getBundleManagerProvider();
List<PackageVersion> packageVersions = bundleManager.getAllBundleVersionPackageVersions(bundleVersion);
@@ -110,7 +114,13 @@ public class FileTemplateBundlePluginServerComponent implements ResourceComponen
}
}
- // TODO all bundle files are downloaded - now process the bundle
+ // process the recipe
+ String recipe = bundleVersion.getRecipe();
+ RecipeParser parser = new RecipeParser();
+ ProcessingRecipeContext recipeContext = new ProcessingRecipeContext(recipe);
+ recipeContext.setReplacementVariableValues(bundleDeployDef.getConfiguration());
+ parser.setReplaceReplacementVariables(true);
+ parser.parseRecipe(recipeContext);
} catch (Throwable t) {
log.error("Failed to deploy bundle [" + request + "]", t);
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
new file mode 100644
index 0000000..1dbad78
--- /dev/null
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
@@ -0,0 +1,133 @@
+/*
+ * 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.plugins.filetemplate;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.rhq.bundle.filetemplate.recipe.RecipeContext;
+import org.rhq.core.domain.content.PackageVersion;
+import org.rhq.core.system.ProcessExecution;
+import org.rhq.core.system.ProcessExecutionResults;
+import org.rhq.core.system.SystemInfo;
+
+/**
+ * A recipe context that processes the recipe as it adds stuff to the context
+ *
+ * @author John Mazzitelli
+ */
+public class ProcessingRecipeContext extends RecipeContext {
+
+ private final Map<PackageVersion, File> packageVersionFiles;
+ private final SystemInfo systemInfo;
+ private String baseWorkingDirectory;
+
+ public ProcessingRecipeContext(String recipe, Map<PackageVersion, File> packageVersionFiles, SystemInfo systemInfo,
+ String baseWorkingDirectory) {
+
+ super(recipe);
+ this.packageVersionFiles = packageVersionFiles;
+ this.systemInfo = systemInfo;
+ this.baseWorkingDirectory = baseWorkingDirectory; // the directory that existing bundle filenames will be relative to
+ }
+
+ @Override
+ public void addDeployFile(String filename, String directory) {
+ super.addDeployFile(filename, directory);
+
+ File existingFile = new File(this.baseWorkingDirectory, filename);
+
+ ProcessExecution pe = getUnzipExecution(filename, directory);
+ if (pe != null) {
+ ProcessExecutionResults results = this.systemInfo.executeProcess(pe);
+ if (results.getError() != null) {
+ throw new RuntimeException("Could not unbundle file [" + pe + "]: " + results, results.getError());
+ } else if (results.getExitCode() == null || results.getExitCode().intValue() > 0) {
+ throw new RuntimeException("Failed to unbundle file [" + pe + "]: " + results);
+ }
+ existingFile.delete();
+ } else {
+ // not a zipped format - just move the file to the directory as-is
+ File newFile = new File(directory, filename);
+ if (!existingFile.renameTo(newFile)) {
+ throw new RuntimeException("Failed to move [" + existingFile + "] to [" + newFile + "]");
+ }
+ }
+ }
+
+ @Override
+ public void addReplacementVariables(Set<String> replacementVariables) {
+ super.addReplacementVariables(replacementVariables);
+ }
+
+ private ProcessExecution getUnzipExecution(String filename, String directory) {
+ String exe;
+ List<String> args = null;
+
+ if (filename.endsWith(".tar")) {
+ exe = "tar";
+ args = new ArrayList<String>();
+ args.add("xf");
+ args.add(filename);
+ args.add("-C");
+ args.add(directory);
+ } else if (filename.endsWith(".tar.bz2") || filename.endsWith(".tbz2") || filename.endsWith(".tbz")) {
+ exe = "tar";
+ args = new ArrayList<String>();
+ args.add("xfj");
+ args.add(filename);
+ args.add("-C");
+ args.add(directory);
+ } else if (filename.endsWith(".tar.gz") || filename.endsWith(".tgz")) {
+ exe = "tar";
+ args = new ArrayList<String>();
+ args.add("xfz");
+ args.add(filename);
+ args.add("-C");
+ args.add(directory);
+ } else if (filename.endsWith(".zip")) {
+ exe = "unzip";
+ args = new ArrayList<String>();
+ args.add(filename);
+ args.add("-d");
+ args.add(directory);
+ } else if (filename.endsWith(".rpm")) {
+ exe = "rpm";
+ args = new ArrayList<String>();
+ args.add("-i");
+ args.add(filename);
+ if (directory != null && directory.length() > 0) {
+ args.add("--prefix");
+ args.add(directory);
+ }
+ } else {
+ return null; // isn't a unzippable package, we'll just copy it as is
+ }
+
+ ProcessExecution pe = new ProcessExecution(exe);
+ pe.setArguments(args);
+ pe.setWaitForCompletion(30 * 60 * 1000L);
+ pe.setWorkingDirectory(this.baseWorkingDirectory);
+ return pe;
+ }
+}
commit 85ce0d5d01e8b74849346640590edcff1afe8b6f
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Tue Mar 2 15:10:22 2010 -0500
SLSB work for Bundles
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 6d67e56..29b25cf 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
@@ -18,6 +18,8 @@
*/
package org.rhq.enterprise.server.bundle;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
import java.util.List;
import java.util.Random;
import java.util.UUID;
@@ -32,11 +34,17 @@ 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.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleDeployment;
+import org.rhq.core.domain.bundle.BundleFile;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.content.Architecture;
+import org.rhq.core.domain.content.Package;
+import org.rhq.core.domain.content.PackageType;
+import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.content.Repo;
import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleDeployDefinitionCriteria;
@@ -48,6 +56,9 @@ import org.rhq.core.domain.util.PersistenceUtility;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.authz.AuthorizationManagerLocal;
import org.rhq.enterprise.server.authz.PermissionException;
+import org.rhq.enterprise.server.authz.RequiredPermission;
+import org.rhq.enterprise.server.content.ContentManagerLocal;
+import org.rhq.enterprise.server.content.RepoManagerLocal;
import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginFacet;
import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal;
import org.rhq.enterprise.server.util.CriteriaQueryGenerator;
@@ -70,49 +81,208 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
private AuthorizationManagerLocal authorizationManager;
@EJB
+ private ContentManagerLocal contentManager;
+
+ @EJB
+ private RepoManagerLocal repoManager;
+
+ @EJB
private ResourceTypeManagerLocal resourceTypeManager;
- public Bundle createBundle(Subject subject, Bundle bundle) {
- if (null == bundle || null == bundle.getName())
- throw new IllegalArgumentException("Missing one or more of: bundle, name");
+ @RequiredPermission(Permission.MANAGE_INVENTORY)
+ public Bundle createBundle(Subject subject, String name, int bundleTypeId) {
+ if (null == name || "".equals(name.trim())) {
+ throw new IllegalArgumentException("Invalid bundleName: " + name);
+ }
- // add the implicit bundle repo, if necessary
- if (null == bundle.getRepo()) {
- Repo repo = new Repo(bundle.getName());
- repo.setCandidate(false);
- repo.setSyncSchedule(null);
- bundle.setRepo(repo);
+ BundleType bundleType = entityManager.find(BundleType.class, bundleTypeId);
+ if (null == bundleType) {
+ throw new IllegalArgumentException("Invalid bundleTypeId: " + bundleTypeId);
}
- log.info("Creating bundle: " + bundle);
+ Bundle bundle = new Bundle(name, bundleType);
+
+ // add the implicit bundle repo
+ Repo repo = new Repo(name);
+ repo.setCandidate(false);
+ repo.setSyncSchedule(null);
+ bundle.setRepo(repo);
+ log.info("Creating bundle: " + bundle);
entityManager.persist(bundle);
+
return bundle;
}
- public BundleType createBundleType(Subject subject, BundleType bundleType) throws Exception {
- if (null == bundleType || null == bundleType.getName())
- throw new IllegalArgumentException("Missing one or more of: bundleType, name");
+ @RequiredPermission(Permission.MANAGE_INVENTORY)
+ public BundleType createBundleType(Subject subject, String name, int resourceTypeId) throws Exception {
+ if (null == name || "".equals(name.trim())) {
+ throw new IllegalArgumentException("Invalid bundleTypeName: " + name);
+ }
+ ResourceType resourceType = entityManager.find(ResourceType.class, resourceTypeId);
+ if (null == resourceType) {
+ throw new IllegalArgumentException("Invalid resourceeTypeId: " + resourceTypeId);
+ }
+
+ BundleType bundleType = new BundleType(name, resourceType);
entityManager.persist(bundleType);
return bundleType;
}
- public BundleVersion createBundleVersion(Subject subject, int bundleId, BundleVersion bundleVersion)
+ @RequiredPermission(Permission.MANAGE_INVENTORY)
+ public BundleVersion createBundleVersion(Subject subject, int bundleId, String name, String version, String recipe)
throws Exception {
+ if (null == name || "".equals(name.trim())) {
+ throw new IllegalArgumentException("Invalid bundleVersionName: " + name);
+ }
+
Bundle bundle = entityManager.find(Bundle.class, bundleId);
+ if (null == bundle) {
+ throw new IllegalArgumentException("Invalid bundleId: " + bundleId);
+ }
+
+ // parse the recipe (validation occurs here) and get the config def and list of files
+ BundleType bundleType = bundle.getBundleType();
+ BundleServerPluginFacet bp = BundleManagerHelper.getPluginContainer().getBundleServerPluginManager()
+ .getBundleServerPluginFacet(bundleType.getName());
+ RecipeParseResults results = bp.parseRecipe(recipe);
- if (null == bundleVersion || null == bundle || null == bundleVersion.getRecipe())
- throw new IllegalArgumentException("Missing one or more of: bundle, bundleVersion, recipe");
+ // ensure we have a version
+ version = getVersion(version, bundle);
- // parse the recipe and get the config def and list of files
- BundleServerPluginFacet bp;
- // bp.parseRecipe;
+ BundleVersion bundleVersion = new BundleVersion(name, version, bundle, recipe);
+ bundleVersion.setConfigurationDefinition(results.getConfigDef());
entityManager.persist(bundleVersion);
return bundleVersion;
}
+ private String getVersion(String version, Bundle bundle) {
+ if (!(null == version || "".equals(version.trim()))) {
+ return version;
+ }
+
+ BundleVersion currentBundleVersion = null;
+ for (BundleVersion bundleVersion : bundle.getBundleVersions()) {
+ if ((null == currentBundleVersion) || (bundleVersion.getId() > currentBundleVersion.getId())) {
+ currentBundleVersion = bundleVersion;
+ }
+ }
+
+ // note - this is the same algo used by ResourceClientProxy in updatebackingContent (for a resource)
+ String oldVersion = (null == currentBundleVersion) ? null : currentBundleVersion.getVersion();
+ String newVersion = "1.0";
+ if (oldVersion != null && oldVersion.length() != 0) {
+ String[] parts = oldVersion.split("[^a-zA-Z0-9]");
+ String lastPart = parts[parts.length - 1];
+ try {
+ int lastNumber = Integer.parseInt(lastPart);
+ newVersion = oldVersion.substring(0, oldVersion.length() - lastPart.length()) + (lastNumber + 1);
+ } catch (NumberFormatException nfe) {
+ newVersion = oldVersion + ".1";
+ }
+ }
+
+ return newVersion;
+ }
+
+ @RequiredPermission(Permission.MANAGE_INVENTORY)
+ public BundleFile addBundleFile(Subject subject, int bundleVersionId, String name, String version,
+ Architecture architecture, InputStream fileStream, boolean pinToPackage) throws Exception {
+
+ if (null == name || "".equals(name.trim())) {
+ throw new IllegalArgumentException("Invalid bundleFileName: " + name);
+ }
+ if (null == version || "".equals(version.trim())) {
+ throw new IllegalArgumentException("Invalid bundleFileVersion: " + version);
+ }
+ if (null == fileStream) {
+ throw new IllegalArgumentException("Invalid fileStream: " + null);
+ }
+ BundleVersion bundleVersion = entityManager.find(BundleVersion.class, bundleVersionId);
+ if (null == bundleVersion) {
+ throw new IllegalArgumentException("Invalid bundleVersionId: " + bundleVersionId);
+ }
+
+ // Create the PackageVersion the BundleFile is tied to. This implicitly creates the
+ // Package for the PackageVersion.
+ Bundle bundle = bundleVersion.getBundle();
+ PackageType packageType = getBundleTypePackageType(bundle.getBundleType());
+ architecture = (null == architecture) ? contentManager.getNoArchitecture() : architecture;
+ PackageVersion packageVersion = contentManager.createPackageVersion(name, packageType.getId(), version,
+ architecture.getId(), fileStream);
+
+ // Create the mapping between the Bundle's Repo and the BundleFile's PackageVersion
+ Repo repo = bundle.getRepo();
+ repoManager.addPackageVersionsToRepo(subject, repo.getId(), new int[] { packageVersion.getId() });
+
+ // Classify the Package with the Bundle name in order to distinguish it from the same package name for
+ // a different bundle.
+ Package generalPackage = packageVersion.getGeneralPackage();
+ generalPackage.setClassification(bundle.getName());
+
+ // With all the plumbing in place, create and persist the BundleFile. Tie it to the Package if the caller
+ // wants this BundleFile pinned to themost recent version.
+ BundleFile bundleFile = new BundleFile();
+ bundleFile.setBundleVersion(bundleVersion);
+ bundleFile.setPackageVersion(packageVersion);
+ if (pinToPackage) {
+ bundleFile.setPackage(generalPackage);
+ }
+
+ entityManager.persist(bundleFile);
+
+ return bundleFile;
+ }
+
+ @RequiredPermission(Permission.MANAGE_INVENTORY)
+ public BundleFile addBundleFileViaByteArray(Subject subject, int bundleVersionId, String name, String version,
+ Architecture architecture, byte[] fileBytes, boolean pinToPackage) throws Exception {
+
+ return addBundleFile(subject, bundleVersionId, name, version, architecture,
+ new ByteArrayInputStream(fileBytes), pinToPackage);
+ }
+
+ @RequiredPermission(Permission.MANAGE_INVENTORY)
+ public BundleFile addBundleFileViaPackageVersion(Subject subject, int bundleVersionId, String name,
+ int packageVersionId, boolean pinToPackage) throws Exception {
+
+ if (null == name || "".equals(name.trim())) {
+ throw new IllegalArgumentException("Invalid bundleFileName: " + name);
+ }
+ BundleVersion bundleVersion = entityManager.find(BundleVersion.class, bundleVersionId);
+ if (null == bundleVersion) {
+ throw new IllegalArgumentException("Invalid bundleVersionId: " + bundleVersionId);
+ }
+ PackageVersion packageVersion = entityManager.find(PackageVersion.class, packageVersionId);
+ if (null == packageVersion) {
+ throw new IllegalArgumentException("Invalid packageVersionId: " + packageVersionId);
+ }
+
+ // With all the plumbing in place, create and persist the BundleFile. Tie it to the Package if the caller
+ // wants this BundleFile pinned to themost recent version.
+ BundleFile bundleFile = new BundleFile();
+ bundleFile.setBundleVersion(bundleVersion);
+ bundleFile.setPackageVersion(packageVersion);
+ if (pinToPackage) {
+ bundleFile.setPackage(packageVersion.getGeneralPackage());
+ }
+
+ entityManager.persist(bundleFile);
+
+ return bundleFile;
+ }
+
+ private PackageType getBundleTypePackageType(BundleType bundleType) {
+
+ Query packageTypeQuery = entityManager.createNamedQuery(PackageType.QUERY_FIND_BY_RESOURCE_TYPE_ID_AND_NAME);
+ packageTypeQuery.setParameter("typeId", bundleType.getResourceType().getId());
+ packageTypeQuery.setParameter("name", bundleType.getName());
+
+ return (PackageType) packageTypeQuery.getSingleResult();
+ }
+
@SuppressWarnings("unchecked")
public List<BundleType> getAllBundleTypes(Subject subject) {
// the list of types will be small, no need to support paging
@@ -198,8 +368,7 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
try {
ResourceType linuxPlatformResourceType = this.resourceTypeManager.getResourceTypeByNameAndPlugin("Linux",
"Platforms");
- BundleType bundleType = new BundleType(UUID.randomUUID().toString(), linuxPlatformResourceType);
- return createBundleType(subject, bundleType);
+ return createBundleType(subject, UUID.randomUUID().toString(), linuxPlatformResourceType.getId());
} catch (Exception e) {
e.printStackTrace();
return null;
@@ -215,9 +384,8 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
int randomIndex = random.nextInt(bundleTypes.size());
bundleType = bundleTypes.get(randomIndex);
}
- Bundle bundle = new Bundle(UUID.randomUUID().toString(), bundleType);
- bundle = createBundle(subject, bundle);
+ Bundle bundle = createBundle(subject, UUID.randomUUID().toString(), bundleType.getId());
// Add 1 to 5 bundle versions.
int bundleVersionCount = random.nextInt(5) + 1;
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerHelper.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerHelper.java
new file mode 100644
index 0000000..7ba49db
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerHelper.java
@@ -0,0 +1,34 @@
+package org.rhq.enterprise.server.bundle;
+
+import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.ServerPluginServiceManagement;
+import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginContainer;
+import org.rhq.enterprise.server.util.LookupUtil;
+
+public class BundleManagerHelper {
+
+ public static BundleServerPluginContainer getPluginContainer() {
+ BundleServerPluginContainer pc;
+
+ try {
+ ServerPluginServiceManagement mbean = LookupUtil.getServerPluginService();
+ if (!mbean.isMasterPluginContainerStarted()) {
+ throw new IllegalStateException("The master plugin container is not started!");
+ }
+
+ MasterServerPluginContainer master = mbean.getMasterPluginContainer();
+ pc = master.getPluginContainerByClass(BundleServerPluginContainer.class);
+ } catch (IllegalStateException ise) {
+ throw ise;
+ } catch (Exception e) {
+ throw new IllegalStateException("Cannot obtain the Bundle plugin container!", e);
+ }
+
+ if (pc == null) {
+ throw new IllegalStateException("Bundle plugin container is null!");
+ }
+
+ return pc;
+ }
+
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
index 42f573d..ec3b73b 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
@@ -18,6 +18,7 @@
*/
package org.rhq.enterprise.server.bundle;
+import java.io.InputStream;
import java.util.List;
import javax.ejb.Local;
@@ -26,8 +27,10 @@ import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleDeployment;
+import org.rhq.core.domain.bundle.BundleFile;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.content.Architecture;
import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleDeployDefinitionCriteria;
import org.rhq.core.domain.criteria.BundleDeploymentCriteria;
@@ -43,26 +46,73 @@ import org.rhq.core.domain.util.PageList;
public interface BundleManagerLocal {
/**
+ * 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 bundle required fields: name
+ * @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
+ * @param architecture architecture appropriate for the backing package. Defaults to noarch (i.e. any architecture).
+ * @param fileStream the file bits
+ * @param pinToPackage if true a new version of the backing package can trigger automatic creation of a new
+ * BundleVersion. if false new versions of the backing package have no effect on the BundleFile or its BundleVersion.
+ * @return the new BundleFile
+ * @throws Exception
+ */
+ BundleFile addBundleFile(Subject subject, int bundleVersionId, String bundleFileName, String version,
+ Architecture architecture, InputStream fileStream, boolean pinToPackage) throws Exception;
+
+ /**
+ * A convenience method taking a byte array as opposed to a stream for the file bits.
+ *
+ * @see {@link addBundleFile(Subject, int, String, String, Architecture, InputStream, boolean)}
+ */
+ BundleFile addBundleFileViaByteArray(Subject subject, int bundleVersionId, String name, String version,
+ Architecture architecture, byte[] fileBytes, boolean pinToPackage) throws Exception;
+
+ /**
+ * @param subject must be InventoryManager
+ * @param bundleVersionId id of the BundleVersion incorporating this BundleFile
+ * @param name name of the BundleFile (and the resulting Package)
+ * @param packageVersionId id of the PackageVersion this BundleFile is tied to for this BundleVersion. It is assumed
+ * the PackageVersion is already associated with the Bundle's Repo and the package is classified for the
+ * Bundle.
+ * @param pinToPackage if true a new version of the backing package can trigger automatic creation of a new
+ * BundleVersion. if false new versions of the backing package have no effect on the BundleFile or its BundleVersion.
+ * @return the new BundleFile
+ * @throws Exception
+ */
+ BundleFile addBundleFileViaPackageVersion(Subject subject, int bundleVersionId, String name, int packageVersionId,
+ boolean pinToPackage) throws Exception;
+
+ /**
+ * @param subject must be InventoryManager
+ * @param name not null or empty
+ * @param bundleTypeId valid bundleType
* @return the persisted Bundle (id is assigned)
*/
- Bundle createBundle(Subject subject, Bundle bundle) throws Exception;
+ Bundle createBundle(Subject subject, String name, int bundleTypeId) throws Exception;
/**
+ * Not generally called. For use by Server Side Plugins when registering a Bundle Plugin.
+ *
* @param subject must be InventoryManager
- * @param bundleType required fields: name
+ * @param name not null or empty
+ * @param resourceTypeId id of the ResourceType that handles this BundleType
* @return the persisted BundleType (id is assigned)
*/
- BundleType createBundleType(Subject subject, BundleType bundleType) throws Exception;
+ BundleType createBundleType(Subject subject, String name, int resourceTypeId) throws Exception;
/**
* @param subject must be InventoryManager
- * @param int bundleId the bundle for which this will be the next version
- * @param bundleVersion required fields: recipe (the full recipe as a String)
+ * @param bundleId the bundle for which this will be the next version
+ * @param name not null or empty
+ * @param bundleVersion optional. If not supplied set to 1.0 for first version, or incremented (as best as possible) for subsequent version
* @return the persisted BundleVersion (id is assigned)
*/
- BundleVersion createBundleVersion(Subject subject, int bundleId, BundleVersion bundleVersion) throws Exception;
+ BundleVersion createBundleVersion(Subject subject, int bundleId, String name, String bundleVersion, String recipe)
+ throws Exception;
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
index e381dd4..e8ac546 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
@@ -41,6 +41,7 @@ import org.rhq.core.domain.criteria.BundleVersionCriteria;
import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.util.PageList;
+import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainer;
import org.rhq.enterprise.server.test.AbstractEJB3Test;
import org.rhq.enterprise.server.util.LookupUtil;
@@ -57,8 +58,20 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
private BundleManagerLocal bundleManagerBean;
+ private TestBundleServerPluginService ps;
+ private MasterServerPluginContainer pc;
+
@BeforeMethod
public void beforeMethod() {
+ super.startTest();
+
+ if (null == ps) {
+ ps = new TestBundleServerPluginService();
+ pc = ps.createMasterPluginContainer();
+ } else {
+ pc.initialize(ps.masterConfig);
+ }
+
bundleManagerBean = LookupUtil.getBundleManager();
}
@@ -119,6 +132,12 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
em.close();
}
}
+
+ if (null != pc) {
+ pc.shutdown();
+ }
+
+ super.endTest();
}
@Test(enabled = ENABLED)
@@ -232,8 +251,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
private BundleType createBundleType(String name) throws Exception {
final String fullName = TEST_PREFIX + "-type-" + name;
- BundleType bt = new BundleType(fullName, createResourceType(name));
- bt = bundleManagerBean.createBundleType(getOverlord(), bt);
+ BundleType bt = bundleManagerBean.createBundleType(getOverlord(), fullName, createResourceType(name).getId());
assert bt.getId() > 0;
assert bt.getName().endsWith(fullName);
@@ -247,8 +265,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
private Bundle createBundle(String name, BundleType bt) throws Exception {
final String fullName = TEST_PREFIX + "-bundle-" + name;
- Bundle b = new Bundle(fullName, bt);
- b = bundleManagerBean.createBundle(getOverlord(), b);
+ Bundle b = bundleManagerBean.createBundle(getOverlord(), fullName, bt.getId());
assert b.getId() > 0;
assert b.getName().endsWith(fullName);
@@ -257,9 +274,9 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
private BundleVersion createBundleVersion(String name, String version, Bundle bundle) throws Exception {
final String fullName = TEST_PREFIX + "-version-" + version + "-" + name;
- final String recipe = TEST_PREFIX + "-recipe-" + name;
- BundleVersion bv = new BundleVersion(fullName, version, bundle, recipe);
- bv = bundleManagerBean.createBundleVersion(getOverlord(), bv);
+ final String recipe = "deploy -f " + TEST_PREFIX + ".zip -d <% test.path %>";
+ BundleVersion bv = bundleManagerBean.createBundleVersion(getOverlord(), bundle.getId(), fullName, version,
+ recipe);
assert bv.getId() > 0;
assert bv.getName().endsWith(fullName);
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
new file mode 100644
index 0000000..dcbc951
--- /dev/null
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/TestBundleServerPluginService.java
@@ -0,0 +1,218 @@
+/*
+ * 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.bundle;
+
+import java.io.File;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
+import org.rhq.core.domain.plugin.PluginKey;
+import org.rhq.core.domain.plugin.PluginStatusType;
+import org.rhq.core.domain.plugin.ServerPlugin;
+import org.rhq.core.util.MessageDigestGenerator;
+import org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainerConfiguration;
+import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
+import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment;
+import org.rhq.enterprise.server.plugin.pc.ServerPluginManager;
+import org.rhq.enterprise.server.plugin.pc.ServerPluginService;
+import org.rhq.enterprise.server.plugin.pc.ServerPluginType;
+import org.rhq.enterprise.server.plugin.pc.generic.GenericServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.generic.TestGenericServerPluginServiceMBean;
+import org.rhq.enterprise.server.xmlschema.ServerPluginDescriptorMetadataParser;
+import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType;
+
+/**
+ * Used as a mock service for the generic server plugin container.
+ */
+public class TestBundleServerPluginService extends ServerPluginService implements TestGenericServerPluginServiceMBean {
+ public enum State {
+ INITIALIZED, STARTED, STOPPED, UNINITIALIZED
+ }
+
+ // public so tests can directly set these
+ public TestMasterServerPluginContainer master;
+ public TestBundleServerPluginContainer bundlePC;
+ public MasterServerPluginContainerConfiguration masterConfig;
+
+ public TestBundleServerPluginService() {
+ // build the config at constructor time so tests have it even before the PC is initialized
+ File dir = new File(System.getProperty("java.io.tmpdir"), "test-server-plugins");
+ this.masterConfig = new MasterServerPluginContainerConfiguration(dir, dir, dir, null);
+ }
+
+ @Override
+ public MasterServerPluginContainer createMasterPluginContainer() {
+ this.master = new TestMasterServerPluginContainer();
+ this.master.initialize(this.masterConfig);
+ return this.master;
+ }
+
+ /**
+ * The test master PC
+ */
+ class TestMasterServerPluginContainer extends MasterServerPluginContainer {
+ @Override
+ protected List<AbstractTypeServerPluginContainer> createPluginContainers() {
+ ArrayList<AbstractTypeServerPluginContainer> pcs = new ArrayList<AbstractTypeServerPluginContainer>(1);
+ bundlePC = new TestBundleServerPluginContainer(this);
+ pcs.add(bundlePC);
+ return pcs;
+ }
+
+ @Override
+ protected ClassLoader createRootServerPluginClassLoader() {
+ return this.getClass().getClassLoader();
+ }
+
+ @Override
+ protected Map<URL, ? extends ServerPluginDescriptorType> preloadAllPlugins() throws Exception {
+ // if our test never setup any plugins, ignore it and just return an empty map
+ File pluginDir = getConfiguration().getPluginDirectory();
+ if (pluginDir == null || pluginDir.listFiles() == null || pluginDir.listFiles().length == 0) {
+ return new HashMap<URL, ServerPluginDescriptorType>();
+ } else {
+ return super.preloadAllPlugins();
+ }
+ }
+
+ @Override
+ protected List<PluginKey> getDisabledPluginKeys() {
+ // in the real world, the db is checked for enable flag, here we say all plugins are enabled
+ return new ArrayList<PluginKey>();
+ }
+ }
+
+ public class TestBundleServerPluginContainer extends GenericServerPluginContainer {
+ public State state = State.UNINITIALIZED;
+
+ public TestBundleServerPluginContainer(MasterServerPluginContainer master) {
+ super(master);
+ }
+
+ @Override
+ protected ServerPluginManager createPluginManager() {
+ TestBundlePluginManager pm = new TestBundlePluginManager(this);
+ return pm;
+ }
+
+ @Override
+ public synchronized void initialize() throws Exception {
+ if (state == State.UNINITIALIZED) {
+ state = State.INITIALIZED;
+ } else {
+ System.out.println("!!! PC LIFECYCLE WAS BAD - THIS IS A BUG !!!");
+ throw new IllegalStateException("not uninitialized: " + state);
+ }
+ super.initialize();
+ }
+
+ @Override
+ public synchronized void start() {
+ if (state == State.INITIALIZED) {
+ state = State.STARTED;
+ } else {
+ System.out.println("!!! PC LIFECYCLE WAS BAD - THIS IS A BUG !!!");
+ throw new IllegalStateException("not initialized: " + state);
+ }
+ super.start();
+ }
+
+ @Override
+ public synchronized void stop() {
+ if (state == State.STARTED) {
+ state = State.STOPPED;
+ } else {
+ System.out.println("!!! PC LIFECYCLE WAS BAD - THIS IS A BUG !!!");
+ throw new IllegalStateException("not started: " + state);
+ }
+ super.stop();
+ }
+
+ @Override
+ public synchronized void shutdown() {
+ if (state == State.STOPPED) {
+ state = State.UNINITIALIZED;
+ } else {
+ System.out.println("!!! PC LIFECYCLE WAS BAD - THIS IS A BUG !!!");
+ throw new IllegalStateException("not stopped: " + state);
+ }
+ super.shutdown();
+ }
+ }
+
+ /**
+ * The test plugin manager.
+ */
+ class TestBundlePluginManager extends ServerPluginManager {
+ public final Map<String, ServerPluginComponent> components;
+
+ public TestBundlePluginManager(TestBundleServerPluginContainer pc) {
+ super(pc);
+ components = new HashMap<String, ServerPluginComponent>();
+ }
+
+ @Override
+ protected ServerPlugin getPlugin(ServerPluginEnvironment env) {
+
+ try {
+ Configuration pluginConfig = null;
+ Configuration scheduledJobsConfig = null;
+ ConfigurationDefinition configDef;
+
+ ServerPluginDescriptorType pluginDescriptor = env.getPluginDescriptor();
+
+ configDef = ServerPluginDescriptorMetadataParser.getPluginConfigurationDefinition(pluginDescriptor);
+ if (configDef != null) {
+ pluginConfig = configDef.getDefaultTemplate().createConfiguration();
+ }
+
+ configDef = ServerPluginDescriptorMetadataParser.getScheduledJobsDefinition(pluginDescriptor);
+ if (configDef != null) {
+ scheduledJobsConfig = configDef.getDefaultTemplate().createConfiguration();
+ }
+
+ File pluginFile = new File(env.getPluginUrl().toURI());
+ ServerPlugin plugin = new ServerPlugin(0, env.getPluginKey().getPluginName(), pluginFile.getName(),
+ pluginDescriptor.getDisplayName(), true, PluginStatusType.INSTALLED, pluginDescriptor
+ .getDescription(), "", MessageDigestGenerator.getDigestString(pluginFile), pluginDescriptor
+ .getVersion(), pluginDescriptor.getVersion(), pluginConfig, scheduledJobsConfig,
+ new ServerPluginType(pluginDescriptor).stringify(), System.currentTimeMillis(), System
+ .currentTimeMillis());
+ return plugin;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ protected ServerPluginComponent createServerPluginComponent(ServerPluginEnvironment environment)
+ throws Exception {
+ ServerPluginComponent component = super.createServerPluginComponent(environment);
+ components.put(environment.getPluginKey().getPluginName(), component);
+ return component;
+ }
+ }
+}
\ No newline at end of file
commit bf127b50c0157b289c78b9073002931bb131ea00
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Mar 2 13:52:43 2010 -0500
be defensive when building the template engine replacement variables - get as many variables as we can, ignoring native errors if we hit them
diff --git a/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java b/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java
index 27a1375..573e9c0 100644
--- a/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java
+++ b/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java
@@ -26,10 +26,11 @@ import java.io.File;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
+import java.net.InetAddress;
import java.net.URL;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
-import java.util.TreeMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -43,7 +44,11 @@ import org.rhq.core.util.exception.ThrowableUtil;
* @author John Mazzitelli
*/
public class SystemInfoFactory {
- private static final String TOKEN_PREFIX = "rhq.system.";
+ /**
+ * All template engine replacement variables that this factory's template engine will know about
+ * will be prefixed with this string.
+ */
+ public static final String TOKEN_PREFIX = "rhq.system.";
private static final Log LOG = LogFactory.getLog(SystemInfoFactory.class);
@@ -343,35 +348,60 @@ public class SystemInfoFactory {
public static TemplateEngine fetchTemplateEngine() {
- try{
- SystemInfo systemInfo = createSystemInfo();
-
- Map<String, String> tokens = new HashMap<String, String>();
- tokens.put(TOKEN_PREFIX+"hostname", systemInfo.getHostname());
-
- tokens.put(TOKEN_PREFIX+"os.name", systemInfo.getOperatingSystemName());
- tokens.put(TOKEN_PREFIX+"os.version", systemInfo.getOperatingSystemVersion());
- tokens.put(TOKEN_PREFIX+"os.type", systemInfo.getOperatingSystemType().toString());
- tokens.put(TOKEN_PREFIX+"cpu.count", Integer.toString(systemInfo.getNumberOfCpus()));
- tokens.put(TOKEN_PREFIX+"architecture", systemInfo.getSystemArchitecture());
-
- for (NetworkAdapterInfo networkAdapter : systemInfo.getAllNetworkAdapters()) {
- String key = TOKEN_PREFIX+"interfaces." + networkAdapter.getName();
- tokens.put(key + ".mac", networkAdapter.getMacAddressString());
- tokens.put(key + ".type", networkAdapter.getType());
- tokens.put(key + ".flags", networkAdapter.getAllFlags());
-
- if (!networkAdapter.getUnicastAddresses().isEmpty()) {
- tokens.put(key + ".address", networkAdapter.getUnicastAddresses().get(0).getHostAddress());
+ try {
+ SystemInfo systemInfo = createSystemInfo();
+
+ Map<String, String> tokens = new HashMap<String, String>();
+ tokens.put(TOKEN_PREFIX + "hostname", systemInfo.getHostname());
+
+ tokens.put(TOKEN_PREFIX + "os.name", systemInfo.getOperatingSystemName());
+ tokens.put(TOKEN_PREFIX + "os.version", systemInfo.getOperatingSystemVersion());
+ tokens.put(TOKEN_PREFIX + "os.type", systemInfo.getOperatingSystemType().toString());
+ tokens.put(TOKEN_PREFIX + "architecture", systemInfo.getSystemArchitecture());
+ try {
+ tokens.put(TOKEN_PREFIX + "cpu.count", Integer.toString(systemInfo.getNumberOfCpus()));
+ } catch (Exception e) {
+ tokens.put(TOKEN_PREFIX + "cpu.count", "?");
}
- if (!networkAdapter.getMulticastAddresses().isEmpty()) {
- tokens.put(key + ".multicast.address", networkAdapter.getMulticastAddresses().get(0).getHostAddress());
+
+ List<NetworkAdapterInfo> allNetworkAdapters = null;
+ try {
+ allNetworkAdapters = systemInfo.getAllNetworkAdapters();
+ } catch (Exception e) {
}
- }
- TemplateEngine templateEngine = new TemplateEngine(tokens);
- return templateEngine;
- }catch(Exception e){
- return new TemplateEngine(new HashMap());
+ if (allNetworkAdapters != null) {
+ for (NetworkAdapterInfo networkAdapter : allNetworkAdapters) {
+ String key = TOKEN_PREFIX + "interfaces." + networkAdapter.getName();
+ tokens.put(key + ".mac", networkAdapter.getMacAddressString());
+ tokens.put(key + ".type", networkAdapter.getType());
+ tokens.put(key + ".flags", networkAdapter.getAllFlags());
+
+ if (!networkAdapter.getUnicastAddresses().isEmpty()) {
+ tokens.put(key + ".address", networkAdapter.getUnicastAddresses().get(0).getHostAddress());
+ }
+ if (!networkAdapter.getMulticastAddresses().isEmpty()) {
+ tokens.put(key + ".multicast.address", networkAdapter.getMulticastAddresses().get(0)
+ .getHostAddress());
+ }
+ }
+ }
+
+ // create a base IP address - this one is known to java and should always exist no matter what platform we are on
+ try {
+ try {
+ tokens.put(TOKEN_PREFIX + "interfaces.java.address", InetAddress
+ .getByName(systemInfo.getHostname()).getHostAddress());
+ } catch (Exception e) {
+ tokens.put(TOKEN_PREFIX + "interfaces.java.address", InetAddress.getLocalHost().getHostAddress());
+ }
+ } catch (Exception e2) {
+ }
+
+ TemplateEngine templateEngine = new TemplateEngine(tokens);
+ return templateEngine;
+ } catch (Exception e) {
+ // some rare exception occurred that we didn't expect, rather than blow up entirely, just don't provide any values
+ return new TemplateEngine(new HashMap<String, String>());
}
}
}
\ No newline at end of file
commit 1ad822fe979dbc3e7e05b525ad49022a73b57fd3
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Mar 2 13:04:35 2010 -0500
cherry picking two commits b10d6026bba36c90530077dec3f22475c34ac69c and
3b7d6dc377c6c5e211ce8b868ccd0801f0b57a7a to pick up fixes to the template engine
Catch and exception and return an empty template enginer if SystemInfoFactory throws and exception. Reorder operations in ConfigurationManager to not swallow a null exception.
Conflicts:
modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java
diff --git a/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java b/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java
index 2558b44..27a1375 100644
--- a/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java
+++ b/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java
@@ -343,10 +343,12 @@ public class SystemInfoFactory {
public static TemplateEngine fetchTemplateEngine() {
+ try{
SystemInfo systemInfo = createSystemInfo();
Map<String, String> tokens = new HashMap<String, String>();
tokens.put(TOKEN_PREFIX+"hostname", systemInfo.getHostname());
+
tokens.put(TOKEN_PREFIX+"os.name", systemInfo.getOperatingSystemName());
tokens.put(TOKEN_PREFIX+"os.version", systemInfo.getOperatingSystemVersion());
tokens.put(TOKEN_PREFIX+"os.type", systemInfo.getOperatingSystemType().toString());
@@ -366,7 +368,10 @@ public class SystemInfoFactory {
tokens.put(key + ".multicast.address", networkAdapter.getMulticastAddresses().get(0).getHostAddress());
}
}
- TemplateEngine templateEngine = new TemplateEngine(tokens);
+ TemplateEngine templateEngine = new TemplateEngine(tokens);
return templateEngine;
+ }catch(Exception e){
+ return new TemplateEngine(new HashMap());
+ }
}
}
\ No newline at end of file
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java
index 580da62..8c3d50c 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java
@@ -22,8 +22,18 @@
*/
package org.rhq.core.pc.configuration;
+import java.util.LinkedList;
+import java.util.Queue;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.agent.configuration.ConfigurationAgentService;
import org.rhq.core.clientapi.agent.configuration.ConfigurationUpdateRequest;
@@ -46,15 +56,6 @@ import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet;
import org.rhq.core.system.SystemInfoFactory;
import org.rhq.core.template.TemplateEngine;
-import java.util.LinkedList;
-import java.util.Queue;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
/**
* Manages configuration of all resources across all plugins.
*
@@ -185,21 +186,20 @@ public class ConfigurationManager extends AgentService implements ContainerServi
Configuration structuredConfig = facet.loadStructuredConfiguration();
TemplateEngine templateEngine = SystemInfoFactory.fetchTemplateEngine();
-
+
if (structuredConfig != null) {
prepareConfigForMergeIntoStructured(configuration, structuredConfig);
for (RawConfiguration rawConfig : configuration.getRawConfigurations()) {
String contents = templateEngine.replaceTokens(new String(rawConfig.getContents()));
rawConfig.setContents(contents);
-
+
structuredConfig.addRawConfiguration(rawConfig);
facet.mergeStructuredConfiguration(rawConfig, configuration);
}
}
}
-
private void prepareConfigForMergeIntoStructured(Configuration config, Configuration latestStructured) {
config.getAllProperties().clear();
for (Property property : latestStructured.getProperties()) {
@@ -217,12 +217,14 @@ public class ConfigurationManager extends AgentService implements ContainerServi
prepareConfigForMergeIntoRaws(configuration, rawConfigs);
Queue<RawConfiguration> queue = new LinkedList<RawConfiguration>(rawConfigs);
+ TemplateEngine templateEngine = SystemInfoFactory.fetchTemplateEngine();
while (!queue.isEmpty()) {
RawConfiguration originalRaw = queue.poll();
RawConfiguration mergedRaw = facet.mergeRawConfiguration(configuration, originalRaw);
-
if (mergedRaw != null) {
+ //TODO bypass validation of structured config for template values
+ mergedRaw.setContents(templateEngine.replaceTokens(mergedRaw.getContents()));
updateRawConfig(configuration, originalRaw, mergedRaw);
}
}
@@ -364,7 +366,7 @@ public class ConfigurationManager extends AgentService implements ContainerServi
}
public void validate(Configuration configuration, int resourceId, boolean isStructured)
- throws PluginContainerException {
+ throws PluginContainerException {
boolean daemonOnly = true;
boolean onlyIfStarted = true;
ResourceConfigurationFacet facet = componentService.getComponent(resourceId, ResourceConfigurationFacet.class,
@@ -372,26 +374,27 @@ public class ConfigurationManager extends AgentService implements ContainerServi
if (isStructured) {
return;
} else {
- StringBuilder errorMessage = null;
+ StringBuilder errorMessage = null;
- try{
+ try {
for (RawConfiguration rawConfiguration : configuration.getRawConfigurations()) {
try {
facet.validateRawConfiguration(rawConfiguration);
} catch (IllegalArgumentException e) {
- if (null == errorMessage){
+ if (null == errorMessage) {
errorMessage = new StringBuilder();
}
- errorMessage.append("file " + rawConfiguration.getPath() +" failed validation with " + e.getMessage()+"." );
+ errorMessage.append("file " + rawConfiguration.getPath() + " failed validation with "
+ + e.getMessage() + ".");
}
}
- }catch(Throwable t){
+ } catch (Throwable t) {
errorMessage = new StringBuilder();
- errorMessage.append("configuation validation failed with" + t.getMessage()+".");
- }
- if (null != errorMessage){
- throw new PluginContainerException(errorMessage.toString());
- }
- }
+ errorMessage.append("configuation validation failed with" + t.getMessage() + ".");
+ }
+ if (null != errorMessage) {
+ throw new PluginContainerException(errorMessage.toString());
+ }
+ }
}
}
commit 93681f0a83acd915eec2aad84b17304f9545a04b
Author: Adam Young <ayoung(a)redhat.com>
Date: Wed Jan 27 21:16:56 2010 -0500
Modified the key for template replacement.
diff --git a/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java b/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java
index 3a29fff..2558b44 100644
--- a/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java
+++ b/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java
@@ -43,6 +43,8 @@ import org.rhq.core.util.exception.ThrowableUtil;
* @author John Mazzitelli
*/
public class SystemInfoFactory {
+ private static final String TOKEN_PREFIX = "rhq.system.";
+
private static final Log LOG = LogFactory.getLog(SystemInfoFactory.class);
private static final String NATIVE_LIBRARY_CLASS_NAME = "org.hyperic.sigar.Sigar";
@@ -344,15 +346,15 @@ public class SystemInfoFactory {
SystemInfo systemInfo = createSystemInfo();
Map<String, String> tokens = new HashMap<String, String>();
- tokens.put("rhq.hostname", systemInfo.getHostname());
- tokens.put("rhq.os.name", systemInfo.getOperatingSystemName());
- tokens.put("rhq.os.version", systemInfo.getOperatingSystemVersion());
- tokens.put("rhq.os.type", systemInfo.getOperatingSystemType().toString());
- tokens.put("rhq.cpu.count", Integer.toString(systemInfo.getNumberOfCpus()));
- tokens.put("rhq.architecture", systemInfo.getSystemArchitecture());
+ tokens.put(TOKEN_PREFIX+"hostname", systemInfo.getHostname());
+ tokens.put(TOKEN_PREFIX+"os.name", systemInfo.getOperatingSystemName());
+ tokens.put(TOKEN_PREFIX+"os.version", systemInfo.getOperatingSystemVersion());
+ tokens.put(TOKEN_PREFIX+"os.type", systemInfo.getOperatingSystemType().toString());
+ tokens.put(TOKEN_PREFIX+"cpu.count", Integer.toString(systemInfo.getNumberOfCpus()));
+ tokens.put(TOKEN_PREFIX+"architecture", systemInfo.getSystemArchitecture());
for (NetworkAdapterInfo networkAdapter : systemInfo.getAllNetworkAdapters()) {
- String key = "rhq.interfaces." + networkAdapter.getName();
+ String key = TOKEN_PREFIX+"interfaces." + networkAdapter.getName();
tokens.put(key + ".mac", networkAdapter.getMacAddressString());
tokens.put(key + ".type", networkAdapter.getType());
tokens.put(key + ".flags", networkAdapter.getAllFlags());
commit dd4632701533ece8302da44595ef1dc6c2a1fdd4
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Mon Mar 1 17:12:54 2010 -0500
start parsing replacement variables
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java
index 029222b..26d1b82 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java
@@ -26,6 +26,10 @@ package org.rhq.bundle.filetemplate.recipe;
import gnu.getopt.Getopt;
import gnu.getopt.LongOpt;
+/**
+ * @deprecated I think this command will not be used - probably should delete it
+ * @author mazz
+ */
public class ConfigdefRecipeCommand implements RecipeCommand {
public String getName() {
@@ -67,7 +71,8 @@ public class ConfigdefRecipeCommand implements RecipeCommand {
throw new IllegalArgumentException("Missing the -f argument to indicate what the config def filename is");
}
- context.setConfigurationDefinitionFilename(filename);
+ // TODO: what to do? can I delete this command entirely?
+
return;
}
}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
index 92c204e..c895107 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
@@ -24,7 +24,9 @@
package org.rhq.bundle.filetemplate.recipe;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
/**
* Contains information that is gleened from a recipe after it is parsed.
@@ -34,13 +36,13 @@ import java.util.Map;
public class RecipeContext {
private final String recipe;
- private String configurationDefinitionFilename;
- private Map<String, String> deployFiles;
+ private final Map<String, String> deployFiles;
+ private final Set<String> replacementVariables;
public RecipeContext(String recipe) {
this.recipe = recipe;
- this.configurationDefinitionFilename = null;
this.deployFiles = new HashMap<String, String>();
+ this.replacementVariables = new HashSet<String>();
}
/**
@@ -49,21 +51,7 @@ public class RecipeContext {
* @return the actual recipe text
*/
public String getRecipe() {
- return recipe;
- }
-
- /**
- * A recipe can have an optional configuration definition file associated with it.
- * If this returns non-<code>null</code>, it refers to this configuration definition file.
- *
- * @return config def filename
- */
- public String getConfigurationDefinitionFilename() {
- return configurationDefinitionFilename;
- }
-
- public void setConfigurationDefinitionFilename(String filename) {
- this.configurationDefinitionFilename = filename;
+ return this.recipe;
}
/**
@@ -79,4 +67,18 @@ public class RecipeContext {
public void addDeployFile(String filename, String directory) {
this.deployFiles.put(filename, directory);
}
+
+ /**
+ * The names of all replacement variables that are found in the recipe.
+ *
+ * @return the replacement variables
+ */
+ public Set<String> getReplacementVariables() {
+ return this.replacementVariables;
+ }
+
+ public void addReplacementVariables(Set<String> replacementVariables) {
+ this.replacementVariables.addAll(replacementVariables);
+ }
+
}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
index b52e807..df797f4 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
@@ -30,8 +30,12 @@ import java.io.StreamTokenizer;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* Parses the file template recipe.
@@ -42,6 +46,12 @@ import java.util.Map;
public class RecipeParser {
private Map<String, RecipeCommand> recipeCommands;
+ // note that we use the same as the core util's template engine
+ // the native system replacement variable prefix is used by the agent-side fact variable names
+ private final Pattern replacementVariableDeclarationPattern = Pattern.compile("<%\\s*(\\w+\\.?)+\\s*%>");
+ private final Pattern replacementVariableNamePattern = Pattern.compile("(\\w+\\.?)+");
+ private final String systemReplacementVariablePrefix = "rhq.system.";
+
public RecipeParser() {
setupRecipeCommands();
}
@@ -74,7 +84,13 @@ public class RecipeParser {
throw new Exception("Unknown command in recipe: " + commandName);
}
+ Set<String> replacementVars = getReplacementVariables(line);
+ if (replacementVars != null) {
+ context.addReplacementVariables(replacementVars);
+ }
+
recipeCommand.parse(context, arguments);
+
return;
}
@@ -90,6 +106,27 @@ public class RecipeParser {
}
}
+ private Set<String> getReplacementVariables(String cmdLine) {
+ Set<String> replacementVariables = null;
+ Matcher matcher = this.replacementVariableDeclarationPattern.matcher(cmdLine);
+ while (matcher.find()) {
+ String replacementDeclaration = matcher.group();
+ Matcher matcherInner = this.replacementVariableNamePattern.matcher(replacementDeclaration);
+ if (!matcherInner.find()) {
+ throw new IllegalArgumentException("Bad replacement declaration [" + replacementDeclaration + "]");
+ }
+ String replacementVariable = matcherInner.group();
+ if (!replacementVariable.startsWith(this.systemReplacementVariablePrefix)) {
+ if (replacementVariables == null) {
+ replacementVariables = new HashSet<String>(1);
+ }
+ replacementVariables.add(replacementVariable);
+ }
+ }
+
+ return replacementVariables;
+ }
+
private String[] splitCommandLine(String cmdLine) {
ByteArrayInputStream in = new ByteArrayInputStream(cmdLine.getBytes());
StreamTokenizer strtok = new StreamTokenizer(new InputStreamReader(in));
diff --git a/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
index d573072..7d58b88 100644
--- a/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
+++ b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
@@ -23,6 +23,8 @@
package org.rhq.bundle.filetemplate.recipe;
+import java.util.Map;
+
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@@ -35,14 +37,49 @@ public class RecipeParserTest {
cleanRecipe();
}
+ public void testSimpleRecipeReplacementVariables() throws Exception {
+ addRecipeCommand("# <% ignored.inside.comment %>");
+ addRecipeCommand("deploy -f jboss.tar -d \"<% opt.dir %>/jboss\"");
+ addRecipeCommand("deploy -f tomcat.tar -d <%opt.dir%>/tomcat");
+ addRecipeCommand("deploy -f jboss.zip -d <%rhq.system.hostname%>/opt/tomcat"); // this is ignored, its an agent fact variable
+ RecipeParser parser = new RecipeParser();
+ RecipeContext context = parser.parseRecipe(getRecipe());
+ Map<String, String> files = context.getDeployFiles();
+ assert files.containsKey("jboss.tar") : files;
+ assert files.get("jboss.tar").equals("<% opt.dir %>/jboss") : files;
+ assert files.containsKey("tomcat.tar") : files;
+ assert files.get("tomcat.tar").equals("<%opt.dir%>/tomcat") : files;
+ assert files.containsKey("jboss.zip") : files;
+ assert files.get("jboss.zip").equals("<%rhq.system.hostname%>/opt/tomcat") : files;
+ assert context.getReplacementVariables().contains("opt.dir") : context.getReplacementVariables();
+ assert context.getReplacementVariables().size() == 1 : context.getReplacementVariables();
+ }
+
public void testSimpleRecipe() throws Exception {
addRecipeCommand("deploy -f jboss.tar -d /opt/jboss");
- addRecipeCommand("configdef -f config.xml");
+ addRecipeCommand("deploy -f tomcat.tar -d /opt/tomcat");
+ RecipeParser parser = new RecipeParser();
+ RecipeContext context = parser.parseRecipe(getRecipe());
+ Map<String, String> files = context.getDeployFiles();
+ assert files.containsKey("jboss.tar") : files;
+ assert files.get("jboss.tar").equals("/opt/jboss") : files;
+ assert files.containsKey("tomcat.tar") : files;
+ assert files.get("tomcat.tar").equals("/opt/tomcat") : files;
+ }
+
+ public void testSimpleRecipeWithQuotes() throws Exception {
+ addRecipeCommand("deploy -f jboss1.zip -d \"/opt/jboss1\"");
+ addRecipeCommand("deploy -f jboss.tar --directory='/opt/jboss'");
+ addRecipeCommand("deploy -f tomcat.tar \"--directory=/opt/tomcat\"");
RecipeParser parser = new RecipeParser();
RecipeContext context = parser.parseRecipe(getRecipe());
- assert context.getConfigurationDefinitionFilename().equals("config.xml");
- assert context.getDeployFiles().containsKey("jboss.tar");
- assert context.getDeployFiles().get("jboss.tar").equals("/opt/jboss");
+ Map<String, String> files = context.getDeployFiles();
+ assert files.containsKey("jboss1.zip") : files;
+ assert files.get("jboss1.zip").equals("/opt/jboss1") : files;
+ assert files.containsKey("jboss.tar") : files;
+ assert files.get("jboss.tar").equals("'/opt/jboss'") : files;
+ assert files.containsKey("tomcat.tar") : files;
+ assert files.get("tomcat.tar").equals("/opt/tomcat") : files;
}
public void testSimpleRecipeError() throws Exception {
@@ -57,11 +94,11 @@ public class RecipeParserTest {
}
cleanRecipe();
- addRecipeCommand("configdef");
+ addRecipeCommand("deploy -d /opt/jboss");
try {
parser.parseRecipe(getRecipe());
- assert false : "This should have failed - need to provide a -f to the configdef command";
+ assert false : "This should have failed - need to provide a -f to the deploy command";
} catch (Exception ok) {
// to be expected
}
@@ -75,16 +112,18 @@ public class RecipeParserTest {
addRecipeCommand("");
addRecipeCommand("#");
addRecipeCommand("### comment here");
- addRecipeCommand("configdef -f config.xml");
+ addRecipeCommand("deploy -f tomcat.tar -d /opt/tomcat");
addRecipeCommand("");
addRecipeCommand("#");
addRecipeCommand("### comment here");
addRecipeCommand("");
RecipeParser parser = new RecipeParser();
RecipeContext context = parser.parseRecipe(getRecipe());
- assert context.getConfigurationDefinitionFilename().equals("config.xml");
- assert context.getDeployFiles().containsKey("jboss.tar");
- assert context.getDeployFiles().get("jboss.tar").equals("/opt/jboss");
+ Map<String, String> files = context.getDeployFiles();
+ assert files.containsKey("jboss.tar") : files;
+ assert files.get("jboss.tar").equals("/opt/jboss") : files;
+ assert files.containsKey("tomcat.tar") : files;
+ assert files.get("tomcat.tar").equals("/opt/tomcat") : files;
}
private void cleanRecipe() {
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 a67fc1a..147f2a5 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,8 @@
package org.rhq.enterprise.server.plugins.filetemplate;
+import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
@@ -29,6 +31,8 @@ import org.rhq.bundle.filetemplate.recipe.RecipeParser;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
+import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
+import org.rhq.core.domain.configuration.definition.PropertySimpleType;
import org.rhq.enterprise.server.bundle.RecipeParseResults;
import org.rhq.enterprise.server.plugin.pc.ControlFacet;
import org.rhq.enterprise.server.plugin.pc.ControlResults;
@@ -68,9 +72,19 @@ public class BundleServerPluginComponent implements ServerPluginComponent, Bundl
RecipeParser parser = new RecipeParser();
RecipeContext parserContext = parser.parseRecipe(recipe);
- // TODO convert the context into the proper data that the parse results wants
+ Set<String> bundleFileNames = new HashSet<String>();
+ Map<String, String> deployFiles = deployFiles = parserContext.getDeployFiles();
+ bundleFileNames.addAll(deployFiles.keySet());
+
ConfigurationDefinition configDef = null;
- Set<String> bundleFileNames = null;
+ if (parserContext.getReplacementVariables() != null) {
+ configDef = new ConfigurationDefinition("replacementVariables", null);
+ for (String replacementVar : parserContext.getReplacementVariables()) {
+ PropertyDefinitionSimple prop = new PropertyDefinitionSimple(replacementVar, null, false,
+ PropertySimpleType.STRING);
+ configDef.put(prop);
+ }
+ }
RecipeParseResults results = new RecipeParseResults(configDef, bundleFileNames);
return results;
commit c0c6ae1ec0cfe537d9980b9015b5b757de7ac4d6
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Mon Mar 1 15:10:29 2010 -0500
get configdef and deploy to parse - create unit test - support blank/comment lines
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java
index 057d474..029222b 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java
@@ -45,11 +45,11 @@ public class ConfigdefRecipeCommand implements RecipeCommand {
switch (code) {
case ':':
case '?': {
- throw new IllegalArgumentException("Bad recipe command [" + getName() + "]: " + args);
+ throw new IllegalArgumentException("Bad recipe argument.");
}
case 1: {
- throw new IllegalArgumentException("Bad recipe command [" + getName() + "]: " + args);
+ throw new IllegalArgumentException("Bad recipe argument!");
}
case 'f': {
@@ -58,12 +58,16 @@ public class ConfigdefRecipeCommand implements RecipeCommand {
}
default: {
- throw new IllegalArgumentException("Unexpected error in recipe command [" + getName() + "]: " + args);
+ throw new IllegalArgumentException("Unexpected error in recipe command");
}
-
}
}
- // TODO : do something with filename
+ if (filename == null) {
+ throw new IllegalArgumentException("Missing the -f argument to indicate what the config def filename is");
+ }
+
+ context.setConfigurationDefinitionFilename(filename);
+ return;
}
}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java
index 145398c..5f14f2f 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java
@@ -47,11 +47,11 @@ public class DeployRecipeCommand implements RecipeCommand {
switch (code) {
case ':':
case '?': {
- throw new IllegalArgumentException("Bad recipe command [" + getName() + "]: " + args);
+ throw new IllegalArgumentException("Bad recipe command.");
}
case 1: {
- throw new IllegalArgumentException("Bad recipe command [" + getName() + "]: " + args);
+ throw new IllegalArgumentException("Bad recipe command!");
}
case 'f': {
@@ -65,12 +65,21 @@ public class DeployRecipeCommand implements RecipeCommand {
}
default: {
- throw new IllegalArgumentException("Unexpected error in recipe command [" + getName() + "]: " + args);
+ throw new IllegalArgumentException("Unexpected error in recipe command");
}
}
}
- // TODO : do something with filename and directory
+ if (filename == null) {
+ throw new IllegalArgumentException("Did not specify the name of the file to deploy");
+ }
+
+ if (directory == null) {
+ throw new IllegalArgumentException("Did not specify the directory where the file should be deployed");
+ }
+
+ context.addDeployFile(filename, directory);
+ return;
}
}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
index da96ceb..92c204e 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
@@ -23,15 +23,24 @@
package org.rhq.bundle.filetemplate.recipe;
+import java.util.HashMap;
+import java.util.Map;
+
/**
+ * Contains information that is gleened from a recipe after it is parsed.
+ *
* @author John Mazzitelli
*/
public class RecipeContext {
private final String recipe;
+ private String configurationDefinitionFilename;
+ private Map<String, String> deployFiles;
public RecipeContext(String recipe) {
this.recipe = recipe;
+ this.configurationDefinitionFilename = null;
+ this.deployFiles = new HashMap<String, String>();
}
/**
@@ -42,4 +51,32 @@ public class RecipeContext {
public String getRecipe() {
return recipe;
}
+
+ /**
+ * A recipe can have an optional configuration definition file associated with it.
+ * If this returns non-<code>null</code>, it refers to this configuration definition file.
+ *
+ * @return config def filename
+ */
+ public String getConfigurationDefinitionFilename() {
+ return configurationDefinitionFilename;
+ }
+
+ public void setConfigurationDefinitionFilename(String filename) {
+ this.configurationDefinitionFilename = filename;
+ }
+
+ /**
+ * Returns all the files that are to be deployed. The key is the bundle file's name, the
+ * value is the directory where the bundle is to be deployed to.
+ *
+ * @return map of all files to be deployed and the location where they are to be deployed
+ */
+ public Map<String, String> getDeployFiles() {
+ return this.deployFiles;
+ }
+
+ public void addDeployFile(String filename, String directory) {
+ this.deployFiles.put(filename, directory);
+ }
}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
index ff9b91f..b52e807 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
@@ -52,21 +52,30 @@ public class RecipeParser {
BufferedReader recipeReader = new BufferedReader(new StringReader(recipe));
String line = recipeReader.readLine();
while (line != null) {
- String[] commandLineArray = splitCommandLine(line);
- String commandName = commandLineArray[0];
- String[] arguments = extractArguments(commandLineArray);
+ parseRecipeCommandLine(context, line);
+ line = recipeReader.readLine();
+ }
- RecipeCommand recipeCommand = recipeCommands.get(commandName);
- if (recipeCommand == null) {
- throw new Exception("Unknown command in recipe: " + commandName);
- }
+ return context;
+ }
- recipeCommand.parse(context, arguments);
+ public void parseRecipeCommandLine(RecipeContext context, String line) throws Exception {
+ // ignore blank lines or comment lines that start with #
+ if (line == null || line.trim().length() == 0 || line.startsWith("#")) {
+ return;
+ }
- line = recipeReader.readLine();
+ String[] commandLineArray = splitCommandLine(line);
+ String commandName = commandLineArray[0];
+ String[] arguments = extractArguments(commandLineArray);
+
+ RecipeCommand recipeCommand = recipeCommands.get(commandName);
+ if (recipeCommand == null) {
+ throw new Exception("Unknown command in recipe: " + commandName);
}
- return context;
+ recipeCommand.parse(context, arguments);
+ return;
}
private void setupRecipeCommands() {
diff --git a/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
new file mode 100644
index 0000000..d573072
--- /dev/null
+++ b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
@@ -0,0 +1,101 @@
+/*
+ * 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, 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.bundle.filetemplate.recipe;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+@Test
+public class RecipeParserTest {
+ private StringBuilder recipe;
+
+ @BeforeMethod
+ public void cleanRecipeBeforeMethod() {
+ cleanRecipe();
+ }
+
+ public void testSimpleRecipe() throws Exception {
+ addRecipeCommand("deploy -f jboss.tar -d /opt/jboss");
+ addRecipeCommand("configdef -f config.xml");
+ RecipeParser parser = new RecipeParser();
+ RecipeContext context = parser.parseRecipe(getRecipe());
+ assert context.getConfigurationDefinitionFilename().equals("config.xml");
+ assert context.getDeployFiles().containsKey("jboss.tar");
+ assert context.getDeployFiles().get("jboss.tar").equals("/opt/jboss");
+ }
+
+ public void testSimpleRecipeError() throws Exception {
+ addRecipeCommand("deploy -f jboss.tar");
+ RecipeParser parser = new RecipeParser();
+
+ try {
+ parser.parseRecipe(getRecipe());
+ assert false : "This should have failed - need to provide a -d to the deploy command";
+ } catch (Exception ok) {
+ // to be expected
+ }
+
+ cleanRecipe();
+ addRecipeCommand("configdef");
+
+ try {
+ parser.parseRecipe(getRecipe());
+ assert false : "This should have failed - need to provide a -f to the configdef command";
+ } catch (Exception ok) {
+ // to be expected
+ }
+ }
+
+ public void testSimpleRecipeComments() throws Exception {
+ addRecipeCommand("");
+ addRecipeCommand("#");
+ addRecipeCommand("### comment here");
+ addRecipeCommand("deploy -f jboss.tar -d /opt/jboss");
+ addRecipeCommand("");
+ addRecipeCommand("#");
+ addRecipeCommand("### comment here");
+ addRecipeCommand("configdef -f config.xml");
+ addRecipeCommand("");
+ addRecipeCommand("#");
+ addRecipeCommand("### comment here");
+ addRecipeCommand("");
+ RecipeParser parser = new RecipeParser();
+ RecipeContext context = parser.parseRecipe(getRecipe());
+ assert context.getConfigurationDefinitionFilename().equals("config.xml");
+ assert context.getDeployFiles().containsKey("jboss.tar");
+ assert context.getDeployFiles().get("jboss.tar").equals("/opt/jboss");
+ }
+
+ private void cleanRecipe() {
+ this.recipe = new StringBuilder();
+ }
+
+ private void addRecipeCommand(String commandLine) {
+ this.recipe.append(commandLine).append("\n");
+ }
+
+ private String getRecipe() {
+ return this.recipe.toString();
+ }
+}
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 96f7070..a67fc1a 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
@@ -68,7 +68,7 @@ public class BundleServerPluginComponent implements ServerPluginComponent, Bundl
RecipeParser parser = new RecipeParser();
RecipeContext parserContext = parser.parseRecipe(recipe);
- // TODO convert the context to the results object
+ // TODO convert the context into the proper data that the parse results wants
ConfigurationDefinition configDef = null;
Set<String> bundleFileNames = null;
commit f2f559b7cdb5055bf572804b82db5f1322913582
Merge: 84ebcfc... 7f70926...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Mar 1 14:50:20 2010 -0500
Merge branch 'bundle' into bundle-jay
commit 84ebcfc94992d0d7f0d6cb1a0a441ece7131d69e
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Mar 1 14:50:13 2010 -0500
local intermittent check-in for merge purposes
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 ce559bf..6d67e56 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
@@ -35,7 +35,6 @@ import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleDeployment;
-import org.rhq.core.domain.bundle.BundleFile;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.content.Repo;
@@ -49,6 +48,7 @@ import org.rhq.core.domain.util.PersistenceUtility;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.authz.AuthorizationManagerLocal;
import org.rhq.enterprise.server.authz.PermissionException;
+import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginFacet;
import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal;
import org.rhq.enterprise.server.util.CriteriaQueryGenerator;
import org.rhq.enterprise.server.util.CriteriaQueryRunner;
@@ -72,15 +72,10 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
@EJB
private ResourceTypeManagerLocal resourceTypeManager;
- @SuppressWarnings("unchecked")
- public List<BundleFile> findBundleFilesForBundleVersion(int bundleVersionId) throws Exception {
- Query q = entityManager.createNamedQuery(BundleFile.QUERY_FIND_BY_BUNDLE_VERSION_ID);
- q.setParameter("id", bundleVersionId);
- List<BundleFile> bundleFiles = (List<BundleFile>) q.getResultList();
- return bundleFiles;
- }
-
public Bundle createBundle(Subject subject, Bundle bundle) {
+ if (null == bundle || null == bundle.getName())
+ throw new IllegalArgumentException("Missing one or more of: bundle, name");
+
// add the implicit bundle repo, if necessary
if (null == bundle.getRepo()) {
Repo repo = new Repo(bundle.getName());
@@ -95,12 +90,25 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
return bundle;
}
- public BundleType createBundleType(Subject subject, BundleType bundleType) {
+ public BundleType createBundleType(Subject subject, BundleType bundleType) throws Exception {
+ if (null == bundleType || null == bundleType.getName())
+ throw new IllegalArgumentException("Missing one or more of: bundleType, name");
+
entityManager.persist(bundleType);
return bundleType;
}
- public BundleVersion createBundleVersion(Subject subject, BundleVersion bundleVersion) {
+ public BundleVersion createBundleVersion(Subject subject, int bundleId, BundleVersion bundleVersion)
+ throws Exception {
+ Bundle bundle = entityManager.find(Bundle.class, bundleId);
+
+ if (null == bundleVersion || null == bundle || null == bundleVersion.getRecipe())
+ throw new IllegalArgumentException("Missing one or more of: bundle, bundleVersion, recipe");
+
+ // parse the recipe and get the config def and list of files
+ BundleServerPluginFacet bp;
+ // bp.parseRecipe;
+
entityManager.persist(bundleVersion);
return bundleVersion;
}
@@ -186,10 +194,16 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
public BundleType createMockBundleType(Subject subject) {
- ResourceType linuxPlatformResourceType = this.resourceTypeManager.getResourceTypeByNameAndPlugin("Linux",
- "Platforms");
- BundleType bundleType = new BundleType(UUID.randomUUID().toString(), linuxPlatformResourceType);
- return createBundleType(subject, bundleType);
+
+ try {
+ ResourceType linuxPlatformResourceType = this.resourceTypeManager.getResourceTypeByNameAndPlugin("Linux",
+ "Platforms");
+ BundleType bundleType = new BundleType(UUID.randomUUID().toString(), linuxPlatformResourceType);
+ return createBundleType(subject, bundleType);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
}
public Bundle createMockBundle(Subject subject, List<BundleType> bundleTypes) {
commit 74b491f9cc626a1fa2f603fb0a0dbb22343b0605
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Mar 1 14:42:07 2010 -0500
Add bundleFiles field to BundleVersion and update the criteria object.
Eliminate the getBundleFilesForBundleVersion convenience routine in favor
of a standard criteria fetch.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java
index 125baa7..b70c53d 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java
@@ -94,6 +94,9 @@ public class BundleVersion implements Serializable {
@OneToMany(mappedBy = "bundleVersion", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<BundleDeployDefinition> bundleDeployDefinitions = new ArrayList<BundleDeployDefinition>();
+ @OneToMany(mappedBy = "bundleVersion", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
+ private List<BundleFile> bundleFiles = new ArrayList<BundleFile>();
+
public BundleVersion() {
// for JPA use
}
@@ -182,6 +185,19 @@ public class BundleVersion implements Serializable {
this.bundleDeployDefinitions = bundleDeployDefinitions;
}
+ public List<BundleFile> getBundleFiles() {
+ return bundleFiles;
+ }
+
+ public void addBundleFile(BundleFile bundleFile) {
+ this.bundleFiles.add(bundleFile);
+ bundleFile.setBundleVersion(this);
+ }
+
+ public void setBundleFiles(List<BundleFile> bundleFiles) {
+ this.bundleFiles = bundleFiles;
+ }
+
@Override
public String toString() {
return "BundleVersion[id=" + id + ",name=" + name + ",version=" + version + ",bundle=" + bundle + "]";
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleVersionCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleVersionCriteria.java
index 72c07ed..5264a76 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleVersionCriteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleVersionCriteria.java
@@ -41,6 +41,7 @@ public class BundleVersionCriteria extends Criteria {
private boolean fetchBundle;
private boolean fetchBundleDeployDefinitions;
+ private boolean fetchBundleFiles;
private boolean fetchDistribution;
private boolean fetchConfigurationDefinition;
@@ -70,12 +71,16 @@ public class BundleVersionCriteria extends Criteria {
this.fetchBundle = fetchBundle;
}
- public void fetchDistribution(boolean fetchDistribution) {
- this.fetchDistribution = fetchDistribution;
- }
-
public void fetchBundleDeployDefinitions(boolean fetchBundleDeployDefinitions) {
this.fetchBundleDeployDefinitions = fetchBundleDeployDefinitions;
}
+ public void fetchBundleFiles(boolean fetchBundleFiles) {
+ this.fetchBundleFiles = fetchBundleFiles;
+ }
+
+ public void fetchDistribution(boolean fetchDistribution) {
+ this.fetchDistribution = fetchDistribution;
+ }
+
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
index 9266530..42f573d 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
@@ -26,7 +26,6 @@ import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleDeployment;
-import org.rhq.core.domain.bundle.BundleFile;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.criteria.BundleCriteria;
@@ -42,13 +41,28 @@ import org.rhq.core.domain.util.PageList;
*/
@Local
public interface BundleManagerLocal {
- Bundle createBundle(Subject subject, Bundle b);
- BundleType createBundleType(Subject subject, BundleType bundleType);
+ /**
+ * @param subject must be InventoryManager
+ * @param bundle required fields: name
+ * @return the persisted Bundle (id is assigned)
+ */
+ Bundle createBundle(Subject subject, Bundle bundle) throws Exception;
- BundleVersion createBundleVersion(Subject subject, BundleVersion bundleVersion);
+ /**
+ * @param subject must be InventoryManager
+ * @param bundleType required fields: name
+ * @return the persisted BundleType (id is assigned)
+ */
+ BundleType createBundleType(Subject subject, BundleType bundleType) throws Exception;
- List<BundleFile> findBundleFilesForBundleVersion(int bundleVersionId) throws Exception;
+ /**
+ * @param subject must be InventoryManager
+ * @param int bundleId the bundle for which this will be the next version
+ * @param bundleVersion required fields: recipe (the full recipe as a String)
+ * @return the persisted BundleVersion (id is assigned)
+ */
+ BundleVersion createBundleVersion(Subject subject, int bundleId, BundleVersion bundleVersion) throws Exception;
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java
index 09f4669..71d038c 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java
@@ -27,8 +27,11 @@ import org.apache.commons.logging.LogFactory;
import org.rhq.core.clientapi.server.bundle.BundleServerService;
import org.rhq.core.clientapi.server.bundle.BundleStatusUpdate;
+import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.BundleFile;
+import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.content.PackageVersion;
+import org.rhq.core.domain.criteria.BundleVersionCriteria;
import org.rhq.core.util.exception.WrappedRemotingException;
import org.rhq.enterprise.server.content.ContentSourceManagerLocal;
import org.rhq.enterprise.server.util.LookupUtil;
@@ -49,7 +52,12 @@ public class BundleServerServiceImpl implements BundleServerService {
public List<PackageVersion> getAllBundleVersionPackageVersions(int bundleVersionId) {
try {
BundleManagerLocal bm = LookupUtil.getBundleManager();
- List<BundleFile> bundleFiles = bm.findBundleFilesForBundleVersion(bundleVersionId);
+ BundleVersionCriteria c = new BundleVersionCriteria();
+ Subject subject = LookupUtil.getSubjectManager().getOverlord();
+ c.addFilterId(bundleVersionId);
+ c.fetchBundleFiles(true);
+ List<BundleVersion> bundleVersions = bm.findBundleVersionsByCriteria(subject, c);
+ List<BundleFile> bundleFiles = bundleVersions.get(0).getBundleFiles();
List<PackageVersion> packageVersions = new ArrayList<PackageVersion>(bundleFiles.size());
for (BundleFile bundleFile : bundleFiles) {
packageVersions.add(bundleFile.getPackageVersion());
commit 7f70926f340987e7808652cce688769dca1eac0e
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Mon Mar 1 14:27:00 2010 -0500
stub the useage of parse results
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java
index c810a97..ba53759 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java
@@ -40,13 +40,15 @@ public class RecipeParseResults {
/** The set of bundle files that make up the bundle (version) as specified in the recipe commands */
private Set<String> bundleFileNames;
- private RecipeParseResults(ConfigurationDefinition configDef, Set<String> bundleFileNames) {
+ public RecipeParseResults(ConfigurationDefinition configDef, Set<String> bundleFileNames) {
this.configDef = configDef;
this.bundleFileNames = bundleFileNames;
}
public ConfigurationDefinition getConfigDef() {
+
// stub out a test ConfigDef here until we actual parse the recipe
+ System.out.println("!!!!!! REMOVE THIS TEST CODE !!!!!!!!");
configDef = new ConfigurationDefinition("SampleBundle", "Stubbed ConfigDef for Sample Bundle");
configDef.put(new PropertyDefinitionSimple("sample.bundle.deploy.directory",
"Stubbed Property for deploy directory (must already exist on target platform)", true,
@@ -62,6 +64,7 @@ public class RecipeParseResults {
public Set<String> getBundleFileNames() {
// stub out a test set of BundleFiles here until we actual parse the recipe. For now lets just deploy
// a war file into an existing app server dir.
+ System.out.println("!!!!!! REMOVE THIS TEST CODE !!!!!!!!");
bundleFileNames = new HashSet<String>();
bundleFileNames.add("sample-bundle.war");
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 2bf4719..a2d6b96 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,12 +19,13 @@
package org.rhq.enterprise.server.plugin.pc.bundle;
+import org.rhq.enterprise.server.bundle.RecipeParseResults;
+
/**
* All bundle server plugins must implement this facet.
*
* @author John Mazzitelli
*/
public interface BundleServerPluginFacet {
- // TODO return something the server/jar SLSB likes
- void parseRecipe(String recipe) throws Exception;
+ RecipeParseResults parseRecipe(String recipe) throws Exception;
}
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 a1f770e..96f7070 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,9 +19,17 @@
package org.rhq.enterprise.server.plugins.filetemplate;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.bundle.filetemplate.recipe.RecipeContext;
import org.rhq.bundle.filetemplate.recipe.RecipeParser;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
+import org.rhq.enterprise.server.bundle.RecipeParseResults;
import org.rhq.enterprise.server.plugin.pc.ControlFacet;
import org.rhq.enterprise.server.plugin.pc.ControlResults;
import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
@@ -35,28 +43,38 @@ import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginFacet;
*/
public class BundleServerPluginComponent implements ServerPluginComponent, BundleServerPluginFacet, ControlFacet {
+ private final Log log = LogFactory.getLog(BundleServerPluginComponent.class);
+
private ServerPluginContext context;
public void initialize(ServerPluginContext context) throws Exception {
this.context = context;
- System.out.println("The filetemplate bundle plugin has been initialized!!! : " + this);
+ log.debug("The filetemplate bundle plugin has been initialized!!! : " + this);
}
public void start() {
- System.out.println("The filetemplate bundle plugin has started!!! : " + this);
+ log.debug("The filetemplate bundle plugin has started!!! : " + this);
}
public void stop() {
- System.out.println("The filetemplate bundle plugin has stopped!!! : " + this);
+ log.debug("The filetemplate bundle plugin has stopped!!! : " + this);
}
public void shutdown() {
- System.out.println("The filetemplate bundle plugin has been shut down!!! : " + this);
+ log.debug("The filetemplate bundle plugin has been shut down!!! : " + this);
}
- public void parseRecipe(String recipe) throws Exception {
+ public RecipeParseResults parseRecipe(String recipe) throws Exception {
RecipeParser parser = new RecipeParser();
- parser.parseRecipe(recipe);
+ RecipeContext parserContext = parser.parseRecipe(recipe);
+
+ // TODO convert the context to the results object
+ ConfigurationDefinition configDef = null;
+ Set<String> bundleFileNames = null;
+
+ RecipeParseResults results = new RecipeParseResults(configDef, bundleFileNames);
+ return results;
+
}
public ControlResults invoke(String name, Configuration parameters) {
commit 7210b1f604f74ac9e384715a84f7ef0fc785fcfa
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Mon Mar 1 13:57:49 2010 -0500
first stubbed version of the commons filetemplate bundle commons lib
diff --git a/.classpath b/.classpath
index bb17f97..c6a1ed2 100644
--- a/.classpath
+++ b/.classpath
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="modules/common/jboss-as/src/main/java"/>
+ <classpathentry kind="src" path="modules/common/filetemplate-bundle/src/main/java"/>
+ <classpathentry kind="src" path="modules/common/filetemplate-bundle/src/test/java"/>
<classpathentry kind="src" path="modules/enterprise/gui/base-perspective-jar/src/main/java"/>
<classpathentry kind="src" path="modules/enterprise/server/plugins/jboss-software/src/test/java"/>
<classpathentry kind="src" path="modules/enterprise/server/plugins/jboss-software/src/main/java"/>
diff --git a/etc/eclipse-tools/maven/RHQ Maven Build and Test - Plugin Common Libraries.launch b/etc/eclipse-tools/maven/RHQ Maven Build and Test - Plugin Common Libraries.launch
new file mode 100644
index 0000000..34c8c3d
--- /dev/null
+++ b/etc/eclipse-tools/maven/RHQ Maven Build and Test - Plugin Common Libraries.launch
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.ui.externaltools.ProgramLaunchConfigurationType">
+<stringAttribute key="bad_container_name" value="\rhq\etc\eclipse-tools\maven"/>
+<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
+<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
+<listEntry value="org.eclipse.ui.externaltools.launchGroup"/>
+</listAttribute>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${env_var:M2_HOME}/bin/${MAVEN_EXE}"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="-o -Dmaven.test.skip=false install"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/rhq/modules/common}"/>
+</launchConfiguration>
diff --git a/modules/common/filetemplate-bundle/pom.xml b/modules/common/filetemplate-bundle/pom.xml
new file mode 100644
index 0000000..e6a3107
--- /dev/null
+++ b/modules/common/filetemplate-bundle/pom.xml
@@ -0,0 +1,37 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-common-parent</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-filetemplate-bundle-common</artifactId>
+ <packaging>jar</packaging>
+
+ <name>RHQ File Template Bundle Plugins Common Library</name>
+ <description>A library with the code common to the agent and server plugins for File Template Bundles</description>
+
+ <scm>
+ <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/common/filetemplat...</connection>
+ <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/common/filetemplat...</developerConnection>
+ </scm>
+
+ <properties>
+ <scm.module.path>modules/common/filetemplate-bundle/</scm.module.path>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>gnu-getopt</groupId>
+ <artifactId>getopt</artifactId>
+ <!-- NOTE: The version is defined in the root POM's dependencyManagement section. -->
+ </dependency>
+
+ </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java
new file mode 100644
index 0000000..057d474
--- /dev/null
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java
@@ -0,0 +1,69 @@
+/*
+ * 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, 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.bundle.filetemplate.recipe;
+
+import gnu.getopt.Getopt;
+import gnu.getopt.LongOpt;
+
+public class ConfigdefRecipeCommand implements RecipeCommand {
+
+ public String getName() {
+ return "configdef";
+ }
+
+ public void parse(RecipeContext context, String[] args) {
+ String sopts = ":f:";
+ LongOpt[] lopts = { new LongOpt("file", LongOpt.REQUIRED_ARGUMENT, null, 'f') };
+
+ String filename = null;
+
+ Getopt getopt = new Getopt(context.toString(), args, sopts, lopts);
+ int code;
+
+ while ((code = getopt.getopt()) != -1) {
+ switch (code) {
+ case ':':
+ case '?': {
+ throw new IllegalArgumentException("Bad recipe command [" + getName() + "]: " + args);
+ }
+
+ case 1: {
+ throw new IllegalArgumentException("Bad recipe command [" + getName() + "]: " + args);
+ }
+
+ case 'f': {
+ filename = getopt.getOptarg();
+ break;
+ }
+
+ default: {
+ throw new IllegalArgumentException("Unexpected error in recipe command [" + getName() + "]: " + args);
+ }
+
+ }
+ }
+
+ // TODO : do something with filename
+ }
+}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java
new file mode 100644
index 0000000..145398c
--- /dev/null
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java
@@ -0,0 +1,76 @@
+/*
+ * 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, 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.bundle.filetemplate.recipe;
+
+import gnu.getopt.Getopt;
+import gnu.getopt.LongOpt;
+
+public class DeployRecipeCommand implements RecipeCommand {
+
+ public String getName() {
+ return "deploy";
+ }
+
+ public void parse(RecipeContext context, String[] args) {
+ String sopts = ":f:d:";
+ LongOpt[] lopts = { new LongOpt("file", LongOpt.REQUIRED_ARGUMENT, null, 'f'),
+ new LongOpt("directory", LongOpt.REQUIRED_ARGUMENT, null, 'd') };
+
+ String filename = null;
+ String directory = null;
+
+ Getopt getopt = new Getopt(context.toString(), args, sopts, lopts);
+ int code;
+
+ while ((code = getopt.getopt()) != -1) {
+ switch (code) {
+ case ':':
+ case '?': {
+ throw new IllegalArgumentException("Bad recipe command [" + getName() + "]: " + args);
+ }
+
+ case 1: {
+ throw new IllegalArgumentException("Bad recipe command [" + getName() + "]: " + args);
+ }
+
+ case 'f': {
+ filename = getopt.getOptarg();
+ break;
+ }
+
+ case 'd': {
+ directory = getopt.getOptarg();
+ break;
+ }
+
+ default: {
+ throw new IllegalArgumentException("Unexpected error in recipe command [" + getName() + "]: " + args);
+ }
+
+ }
+ }
+
+ // TODO : do something with filename and directory
+ }
+}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeCommand.java
new file mode 100644
index 0000000..7cfa964
--- /dev/null
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeCommand.java
@@ -0,0 +1,42 @@
+/*
+ * 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, 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.bundle.filetemplate.recipe;
+
+public interface RecipeCommand {
+
+ /**
+ * The name of the recipe command. This must be the first word in the recipe line in order for this command to be triggered.
+ *
+ * @return name of the recipe command
+ */
+ String getName();
+
+ /**
+ * Parses this recipe command and optionally puts information in the context.
+ *
+ * @param context information where the parser can store information regarding the command that was processed
+ * @param args arguments passed to the command.
+ */
+ void parse(RecipeContext context, String[] args);
+}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
new file mode 100644
index 0000000..da96ceb
--- /dev/null
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
@@ -0,0 +1,45 @@
+/*
+ * 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, 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.bundle.filetemplate.recipe;
+
+/**
+ * @author John Mazzitelli
+ */
+public class RecipeContext {
+
+ private final String recipe;
+
+ public RecipeContext(String recipe) {
+ this.recipe = recipe;
+ }
+
+ /**
+ * The full recipe that this context represents.
+ *
+ * @return the actual recipe text
+ */
+ public String getRecipe() {
+ return recipe;
+ }
+}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
new file mode 100644
index 0000000..ff9b91f
--- /dev/null
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
@@ -0,0 +1,127 @@
+/*
+ * 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, 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.bundle.filetemplate.recipe;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.StreamTokenizer;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Parses the file template recipe.
+ *
+ * @author John Mazzitelli
+ *
+ */
+public class RecipeParser {
+ private Map<String, RecipeCommand> recipeCommands;
+
+ public RecipeParser() {
+ setupRecipeCommands();
+ }
+
+ public RecipeContext parseRecipe(String recipe) throws Exception {
+ RecipeContext context = new RecipeContext(recipe);
+
+ BufferedReader recipeReader = new BufferedReader(new StringReader(recipe));
+ String line = recipeReader.readLine();
+ while (line != null) {
+ String[] commandLineArray = splitCommandLine(line);
+ String commandName = commandLineArray[0];
+ String[] arguments = extractArguments(commandLineArray);
+
+ RecipeCommand recipeCommand = recipeCommands.get(commandName);
+ if (recipeCommand == null) {
+ throw new Exception("Unknown command in recipe: " + commandName);
+ }
+
+ recipeCommand.parse(context, arguments);
+
+ line = recipeReader.readLine();
+ }
+
+ return context;
+ }
+
+ private void setupRecipeCommands() {
+ recipeCommands = new HashMap<String, RecipeCommand>();
+
+ RecipeCommand[] knownCommands = new RecipeCommand[] { new ConfigdefRecipeCommand(), //
+ new DeployRecipeCommand() //
+ };
+
+ for (RecipeCommand recipeCommand : knownCommands) {
+ recipeCommands.put(recipeCommand.getName(), recipeCommand);
+ }
+ }
+
+ private String[] splitCommandLine(String cmdLine) {
+ ByteArrayInputStream in = new ByteArrayInputStream(cmdLine.getBytes());
+ StreamTokenizer strtok = new StreamTokenizer(new InputStreamReader(in));
+ List<String> args = new ArrayList<String>();
+ boolean keep_going = true;
+
+ // we don't want to parse numbers and we want ' to be a normal word character
+ strtok.ordinaryChars('0', '9');
+ strtok.ordinaryChar('.');
+ strtok.ordinaryChar('-');
+ strtok.ordinaryChar('\'');
+ strtok.wordChars(33, 127);
+ strtok.quoteChar('\"');
+
+ // parse the command line
+ while (keep_going) {
+ int nextToken;
+
+ try {
+ nextToken = strtok.nextToken();
+ } catch (IOException e) {
+ nextToken = StreamTokenizer.TT_EOF;
+ }
+
+ if (nextToken == java.io.StreamTokenizer.TT_WORD) {
+ args.add(strtok.sval);
+ } else if (nextToken == '\"') {
+ args.add(strtok.sval);
+ } else if ((nextToken == java.io.StreamTokenizer.TT_EOF) || (nextToken == java.io.StreamTokenizer.TT_EOL)) {
+ keep_going = false;
+ }
+ }
+
+ return args.toArray(new String[args.size()]);
+ }
+
+ private String[] extractArguments(String[] commandLine) {
+ // strip the first element (the command name) from the array, leaving only the arguments
+ int newLength = commandLine.length - 1;
+ String[] argsOnly = new String[newLength];
+ System.arraycopy(commandLine, 1, argsOnly, 0, newLength);
+ return argsOnly;
+ }
+}
diff --git a/modules/common/pom.xml b/modules/common/pom.xml
index e9f0385..8abfe11 100644
--- a/modules/common/pom.xml
+++ b/modules/common/pom.xml
@@ -66,5 +66,6 @@
<modules>
<module>jboss-as</module>
+ <module>filetemplate-bundle</module>
</modules>
</project>
\ No newline at end of file
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 0585a4b..2bf4719 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
@@ -25,5 +25,6 @@ package org.rhq.enterprise.server.plugin.pc.bundle;
* @author John Mazzitelli
*/
public interface BundleServerPluginFacet {
-
+ // TODO return something the server/jar SLSB likes
+ void parseRecipe(String recipe) throws Exception;
}
diff --git a/modules/enterprise/server/plugins/filetemplate-bundle/pom.xml b/modules/enterprise/server/plugins/filetemplate-bundle/pom.xml
index 7a19819..4a3536e 100644
--- a/modules/enterprise/server/plugins/filetemplate-bundle/pom.xml
+++ b/modules/enterprise/server/plugins/filetemplate-bundle/pom.xml
@@ -42,6 +42,12 @@
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-filetemplate-bundle-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
<!-- 3rd Party Deps -->
<!-- TODO: This is a fix for the Javac bug requiring annotations to be
@@ -71,11 +77,37 @@
<configuration>
<excludedGroups>${rhq.testng.excludedGroups}</excludedGroups>
<!--
- <argLine>-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y</argLine>
+ <argLine>-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y</argLine>
-->
</configuration>
</plugin>
+ <plugin>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.0</version>
+ <executions>
+ <execution>
+ <id>copy-rhq-plugins</id>
+ <phase>process-resources</phase>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-filetemplate-bundle-common</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ </artifactItems>
+ <outputDirectory>${project.build.outputDirectory}/lib</outputDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
</plugins>
</build>
@@ -141,7 +173,8 @@
<include name="META-INF/**" />
</patternset>
</unjar>
- <jar destfile="${deployment.file}" manifest="${project.build.outputDirectory}/META-INF/MANIFEST.MF" update="true">
+ <jar destfile="${deployment.file}" manifest="${project.build.outputDirectory}/META-INF/MANIFEST.MF"
+ update="true">
</jar>
</tasks>
</configuration>
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 58dd5b1..a1f770e 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 org.rhq.bundle.filetemplate.recipe.RecipeParser;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.enterprise.server.plugin.pc.ControlFacet;
@@ -53,6 +54,11 @@ public class BundleServerPluginComponent implements ServerPluginComponent, Bundl
System.out.println("The filetemplate bundle plugin has been shut down!!! : " + this);
}
+ public void parseRecipe(String recipe) throws Exception {
+ RecipeParser parser = new RecipeParser();
+ parser.parseRecipe(recipe);
+ }
+
public ControlResults invoke(String name, Configuration parameters) {
ControlResults controlResults = new ControlResults();
if (name.equals("testControl")) {
diff --git a/modules/plugins/filetemplate-bundle/pom.xml b/modules/plugins/filetemplate-bundle/pom.xml
index b1f18b5..93f1c4c 100644
--- a/modules/plugins/filetemplate-bundle/pom.xml
+++ b/modules/plugins/filetemplate-bundle/pom.xml
@@ -26,13 +26,17 @@
<dependencies>
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-filetemplate-bundle-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
</dependencies>
<build>
<plugins>
- <!--
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.0</version>
@@ -47,9 +51,9 @@
<artifactItems>
<artifactItem>
- <groupId>org.jboss</groupId>
- <artifactId>byteman</artifactId>
- <version>1.2.0</version>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-filetemplate-bundle-common</artifactId>
+ <version>${project.version}</version>
</artifactItem>
</artifactItems>
@@ -58,7 +62,6 @@
</execution>
</executions>
</plugin>
- -->
</plugins>
</build>
commit 47723277426d7e582828b2bc45316edbdd005195
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Mar 1 13:55:48 2010 -0500
initial version with some stubbed return values for testing
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java
new file mode 100644
index 0000000..c810a97
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java
@@ -0,0 +1,75 @@
+/*
+ * 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.util.HashSet;
+import java.util.Set;
+
+import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
+import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
+import org.rhq.core.domain.configuration.definition.PropertySimpleType;
+
+/**
+ * This class is general to all Bundle handling server side plugins. It is returned by the SSP when parsing
+ * a bundle's recipe and contains all of the information neded to create a bundle version.
+ *
+ * @author jay shaughnessy
+ */
+public class RecipeParseResults {
+
+ /** The configuration definition parsed out of, or expcitly provided by, the recipe */
+ private ConfigurationDefinition configDef;
+
+ /** The set of bundle files that make up the bundle (version) as specified in the recipe commands */
+ private Set<String> bundleFileNames;
+
+ private RecipeParseResults(ConfigurationDefinition configDef, Set<String> bundleFileNames) {
+ this.configDef = configDef;
+ this.bundleFileNames = bundleFileNames;
+ }
+
+ public ConfigurationDefinition getConfigDef() {
+ // stub out a test ConfigDef here until we actual parse the recipe
+ configDef = new ConfigurationDefinition("SampleBundle", "Stubbed ConfigDef for Sample Bundle");
+ configDef.put(new PropertyDefinitionSimple("sample.bundle.deploy.directory",
+ "Stubbed Property for deploy directory (must already exist on target platform)", true,
+ PropertySimpleType.STRING));
+
+ return configDef;
+ }
+
+ public void setConfigDef(ConfigurationDefinition configDef) {
+ this.configDef = configDef;
+ }
+
+ public Set<String> getBundleFileNames() {
+ // stub out a test set of BundleFiles here until we actual parse the recipe. For now lets just deploy
+ // a war file into an existing app server dir.
+ bundleFileNames = new HashSet<String>();
+ bundleFileNames.add("sample-bundle.war");
+
+ return bundleFileNames;
+ }
+
+ public void setBundleFiles(Set<String> bundleFileNames) {
+ this.bundleFileNames = bundleFileNames;
+ }
+
+}
commit 007fe3b4708ebeb2953b0dd8482b02d1f558993a
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Mon Mar 1 10:12:52 2010 -0500
remove circular dep - plugin api should never dep on pc module
introduct new bundle manager provider interface that plugins will use to callback into the PC bundle manager
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployRequest.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployRequest.java
index 40e663b..2dd6e6d 100644
--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployRequest.java
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployRequest.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2009 Red Hat, Inc.
+ * Copyright (C) 2005-2010 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -22,7 +22,6 @@ package org.rhq.core.pluginapi.bundle;
import java.io.Serializable;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
-import org.rhq.core.pc.bundle.BundleManager;
/**
* A request to deploy a bundle.
@@ -33,7 +32,7 @@ public class BundleDeployRequest implements Serializable {
private static final long serialVersionUID = 1L;
private BundleDeployDefinition bundleDeployDefinition;
- private BundleManager bundleManager;
+ private BundleManagerProvider bundleManager;
public BundleDeployDefinition getBundleDeployDefinition() {
return bundleDeployDefinition;
@@ -43,12 +42,12 @@ public class BundleDeployRequest implements Serializable {
this.bundleDeployDefinition = bundleDeployDefinition;
}
- public BundleManager getBundleManager() {
+ public BundleManagerProvider getBundleManagerProvider() {
return bundleManager;
}
- public void setBundleManager(BundleManager bundleManager) {
- this.bundleManager = bundleManager;
+ public void setBundleManagerProvider(BundleManagerProvider provider) {
+ this.bundleManager = provider;
}
}
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
new file mode 100644
index 0000000..d06561f
--- /dev/null
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleManagerProvider.java
@@ -0,0 +1,52 @@
+/*
+ * 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.core.pluginapi.bundle;
+
+import java.io.OutputStream;
+import java.util.List;
+
+import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.content.PackageVersion;
+
+/**
+ * Provides bundle functionality that plugin components will need in order to process bundles.
+ *
+ * @author John Mazzitelli
+ */
+public interface BundleManagerProvider {
+ /**
+ * Bndle plugins call back into this manager to obtain the bundle files that belong to a given bundle version.
+ *
+ * @param bundleVersion
+ * @return the bundle files that are associated with the given bundle
+ * @throws Exception
+ */
+ List<PackageVersion> getAllBundleVersionPackageVersions(BundleVersion bundleVersion) throws Exception;
+
+ /**
+ * Bundle plugins call back into this manager to obtain the bundle file content for the given package.
+ *
+ * @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
+ */
+ 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 6f6eed5..5db906f 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
@@ -50,6 +50,7 @@ import org.rhq.core.pc.util.FacetLockType;
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;
/**
* Manages the bundle subsystem, which allows bundles of content to be installed.
@@ -58,7 +59,7 @@ import org.rhq.core.pluginapi.bundle.BundleFacet;
*
* @author John Mazzitelli
*/
-public class BundleManager extends AgentService implements BundleAgentService, ContainerService {
+public class BundleManager extends AgentService implements BundleAgentService, BundleManagerProvider, ContainerService {
private final Log log = LogFactory.getLog(BundleManager.class);
private PluginContainerConfiguration configuration;
@@ -99,7 +100,7 @@ public class BundleManager extends AgentService implements BundleAgentService, C
// deploy the bundle utilizing the bundle facet object
BundleDeployRequest deployRequest = new BundleDeployRequest();
- deployRequest.setBundleManager(this);
+ deployRequest.setBundleManagerProvider(this);
deployRequest.setBundleDeployDefinition(request.getBundleDeployDefinition());
BundleDeployResult result = bundlePluginComponent.deployBundle(deployRequest);
if (!result.isSuccess()) {
@@ -113,29 +114,12 @@ public class BundleManager extends AgentService implements BundleAgentService, C
return response;
}
- /**
- * This is used by bundle plugins - bundle plugins call back into this manager to obtain the
- * bundle files that belong to a given bundle version.
- *
- * @param bundleVersion
- * @return the bundle files that are associated with the given bundle
- * @throws Exception
- */
public List<PackageVersion> getAllBundleVersionPackageVersions(BundleVersion bundleVersion) throws Exception {
int bvId = bundleVersion.getId();
List<PackageVersion> pvs = getBundleServerService().getAllBundleVersionPackageVersions(bvId);
return pvs;
}
- /**
- * This is used by bundle plugins - bundle plugins call back into this manager to obtain the
- * bundle file content for the given package.
- *
- * @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
- */
public long getFileContent(PackageVersion packageVersion, OutputStream outputStream) throws Exception {
long size = getBundleServerService().downloadPackageBits(packageVersion, outputStream);
return size;
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
index d8ac092..a1320ad 100644
--- a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
@@ -30,10 +30,10 @@ import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.measurement.AvailabilityType;
-import org.rhq.core.pc.bundle.BundleManager;
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.util.MessageDigestGenerator;
@@ -59,7 +59,6 @@ public class FileTemplateBundlePluginServerComponent implements ResourceComponen
return AvailabilityType.UP;
}
- @Override
public BundleDeployResult deployBundle(BundleDeployRequest request) {
BundleDeployResult result = new BundleDeployResult();
try {
@@ -68,7 +67,7 @@ public class FileTemplateBundlePluginServerComponent implements ResourceComponen
// download all the bundle files to our tmp directory
File tmpDir = new File(this.resourceContext.getTemporaryDirectory(), "" + bundleVersion.getId());
- BundleManager bundleManager = request.getBundleManager();
+ BundleManagerProvider bundleManager = request.getBundleManagerProvider();
List<PackageVersion> packageVersions = bundleManager.getAllBundleVersionPackageVersions(bundleVersion);
for (PackageVersion packageVersion : packageVersions) {
File packageFile = new File(tmpDir, packageVersion.getFileName());
commit fc813fe40f25db9ce1924d259923df095f51ff18
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 26 14:27:11 2010 -0500
file template bundle can download bundle files and verify them
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
index a7100ec..d8ac092 100644
--- a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
@@ -18,15 +18,25 @@
*/
package org.rhq.plugins.filetemplate;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.util.List;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.rhq.core.domain.bundle.BundleDeployDefinition;
+import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.pc.bundle.BundleManager;
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.inventory.ResourceComponent;
import org.rhq.core.pluginapi.inventory.ResourceContext;
+import org.rhq.core.util.MessageDigestGenerator;
/**
* @author John Mazzitelli
@@ -51,8 +61,62 @@ public class FileTemplateBundlePluginServerComponent implements ResourceComponen
@Override
public BundleDeployResult deployBundle(BundleDeployRequest request) {
- // TODO
BundleDeployResult result = new BundleDeployResult();
+ try {
+ BundleDeployDefinition bundleDeployDef = request.getBundleDeployDefinition();
+ BundleVersion bundleVersion = bundleDeployDef.getBundleVersion();
+
+ // download all the bundle files to our tmp directory
+ File tmpDir = new File(this.resourceContext.getTemporaryDirectory(), "" + bundleVersion.getId());
+ BundleManager bundleManager = request.getBundleManager();
+ List<PackageVersion> packageVersions = bundleManager.getAllBundleVersionPackageVersions(bundleVersion);
+ for (PackageVersion packageVersion : packageVersions) {
+ File packageFile = new File(tmpDir, packageVersion.getFileName());
+ packageFile.getParentFile().mkdirs();
+ FileOutputStream fos = new FileOutputStream(packageFile);
+ try {
+ long size = bundleManager.getFileContent(packageVersion, fos);
+ if (packageVersion.getFileSize() != null && size != packageVersion.getFileSize().longValue()) {
+ log.warn("Downloaded bundle file [" + packageVersion + "] but its size was [" + size
+ + "] when it was expected to be [" + packageVersion.getFileSize() + "].");
+ }
+ } finally {
+ fos.close();
+ }
+
+ // verify the content
+ if (packageVersion.getMD5() != null) {
+ String realMD5 = MessageDigestGenerator.getDigestString(packageFile);
+ if (!packageVersion.getMD5().equals(realMD5)) {
+ throw new Exception("Package version [" + packageVersion + "] failed MD5 check. expected=["
+ + packageVersion.getMD5() + "], actual=[" + realMD5 + "]");
+ }
+ } else if (packageVersion.getSHA256() != null) {
+ FileInputStream is = new FileInputStream(packageFile);
+ try {
+ MessageDigestGenerator gen = new MessageDigestGenerator("SHA256");
+ gen.add(is);
+ String realSHA256 = gen.getDigestString();
+ if (!packageVersion.getSHA256().equals(realSHA256)) {
+ throw new Exception("Package version [" + packageVersion
+ + "] failed SHA256 check. expected=[" + packageVersion.getSHA256() + "], actual=["
+ + realSHA256 + "]");
+ }
+ } finally {
+ is.close();
+ }
+
+ } else {
+ log.debug("Package version [" + packageVersion + "] has no MD5/SHA256 hash - not verifying it");
+ }
+ }
+
+ // TODO all bundle files are downloaded - now process the bundle
+
+ } catch (Throwable t) {
+ log.error("Failed to deploy bundle [" + request + "]", t);
+ result.setErrorMessage(t);
+ }
return result;
}
}
commit 0870cc72f3e8321e5e633fdb6221bad4cf92d2dd
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 26 12:50:20 2010 -0500
opps.. typo
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 abbef53..6f6eed5 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
@@ -137,7 +137,7 @@ public class BundleManager extends AgentService implements BundleAgentService, C
* @throws Exception
*/
public long getFileContent(PackageVersion packageVersion, OutputStream outputStream) throws Exception {
- long size = getBundleServerService().downloadPackageBitsGivenResource(packageVersion, outputStream);
+ long size = getBundleServerService().downloadPackageBits(packageVersion, outputStream);
return size;
}
commit 632be079062b309fe0f9e02b9553c6eb5a91304b
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 26 12:28:52 2010 -0500
API for agent plugin to ask for bundle file content
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleServerService.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleServerService.java
index eb09a4e..dbc0555 100644
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleServerService.java
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleServerService.java
@@ -22,10 +22,14 @@
*/
package org.rhq.core.clientapi.server.bundle;
+import java.io.OutputStream;
import java.util.List;
+import org.rhq.core.clientapi.server.content.ContentServerService;
import org.rhq.core.communications.command.annotation.Asynchronous;
-import org.rhq.core.domain.bundle.BundleFile;
+import org.rhq.core.communications.command.annotation.LimitedConcurrency;
+import org.rhq.core.communications.command.annotation.Timeout;
+import org.rhq.core.domain.content.PackageVersion;
/**
* Interface for agents to use when needing to inform the server about bundle tasks. Implementations of this interface, once registered with the
@@ -38,5 +42,21 @@ public interface BundleServerService {
@Asynchronous(guaranteedDelivery = true)
void updateStatus(BundleStatusUpdate update);
- List<BundleFile> getAllBundleFiles(int bundleVersionId);
+ List<PackageVersion> getAllBundleVersionPackageVersions(int bundleVersionId);
+
+ /**
+ * Requests that the server download and stream the bits for the specified package version.
+ * If the package cannot be found, an exception will be thrown.
+ *
+ * @param packageVersion identifies the package to download
+ * @param outputStream an output stream where the server should write the package contents. It is up to the
+ * caller to prepare this output stream in order to write the package content to an
+ * appropriate location.
+ *
+ * @return the number of bytes written to the output stream - this is the size of the package version that was
+ * downloaded
+ */
+ @Timeout(45 * 60 * 1000L)
+ @LimitedConcurrency(ContentServerService.CONCURRENCY_LIMIT_CONTENT_DOWNLOAD)
+ long downloadPackageBits(PackageVersion packageVersion, OutputStream outputStream);
}
\ No newline at end of file
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 4ab1c03..abbef53 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
@@ -22,6 +22,7 @@
*/
package org.rhq.core.pc.bundle;
+import java.io.OutputStream;
import java.util.List;
import java.util.Set;
@@ -34,9 +35,9 @@ import org.rhq.core.clientapi.agent.bundle.BundleScheduleRequest;
import org.rhq.core.clientapi.agent.bundle.BundleScheduleResponse;
import org.rhq.core.clientapi.server.bundle.BundleServerService;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
-import org.rhq.core.domain.bundle.BundleFile;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.pc.ContainerService;
@@ -120,9 +121,24 @@ public class BundleManager extends AgentService implements BundleAgentService, C
* @return the bundle files that are associated with the given bundle
* @throws Exception
*/
- public List<BundleFile> getAllBundleFiles(BundleVersion bundleVersion) throws Exception {
- List<BundleFile> bundleFiles = getBundleServerService().getAllBundleFiles(bundleVersion.getId());
- return bundleFiles;
+ public List<PackageVersion> getAllBundleVersionPackageVersions(BundleVersion bundleVersion) throws Exception {
+ int bvId = bundleVersion.getId();
+ List<PackageVersion> pvs = getBundleServerService().getAllBundleVersionPackageVersions(bvId);
+ return pvs;
+ }
+
+ /**
+ * This is used by bundle plugins - bundle plugins call back into this manager to obtain the
+ * bundle file content for the given package.
+ *
+ * @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
+ */
+ public long getFileContent(PackageVersion packageVersion, OutputStream outputStream) throws Exception {
+ long size = getBundleServerService().downloadPackageBitsGivenResource(packageVersion, outputStream);
+ return size;
}
/**
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 747b980..ce559bf 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
@@ -35,6 +35,7 @@ import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleDeployment;
+import org.rhq.core.domain.bundle.BundleFile;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.content.Repo;
@@ -71,6 +72,14 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
@EJB
private ResourceTypeManagerLocal resourceTypeManager;
+ @SuppressWarnings("unchecked")
+ public List<BundleFile> findBundleFilesForBundleVersion(int bundleVersionId) throws Exception {
+ Query q = entityManager.createNamedQuery(BundleFile.QUERY_FIND_BY_BUNDLE_VERSION_ID);
+ q.setParameter("id", bundleVersionId);
+ List<BundleFile> bundleFiles = (List<BundleFile>) q.getResultList();
+ return bundleFiles;
+ }
+
public Bundle createBundle(Subject subject, Bundle bundle) {
// add the implicit bundle repo, if necessary
if (null == bundle.getRepo()) {
@@ -80,6 +89,8 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
bundle.setRepo(repo);
}
+ log.info("Creating bundle: " + bundle);
+
entityManager.persist(bundle);
return bundle;
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
index 9cfc099..9266530 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
@@ -26,6 +26,7 @@ import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleDeployment;
+import org.rhq.core.domain.bundle.BundleFile;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.criteria.BundleCriteria;
@@ -47,6 +48,8 @@ public interface BundleManagerLocal {
BundleVersion createBundleVersion(Subject subject, BundleVersion bundleVersion);
+ List<BundleFile> findBundleFilesForBundleVersion(int bundleVersionId) throws Exception;
+
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
// The remaining methods are shared with the Remote Interface.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java
index fa84821..09f4669 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java
@@ -18,6 +18,8 @@
*/
package org.rhq.enterprise.server.bundle;
+import java.io.OutputStream;
+import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
@@ -26,6 +28,10 @@ import org.apache.commons.logging.LogFactory;
import org.rhq.core.clientapi.server.bundle.BundleServerService;
import org.rhq.core.clientapi.server.bundle.BundleStatusUpdate;
import org.rhq.core.domain.bundle.BundleFile;
+import org.rhq.core.domain.content.PackageVersion;
+import org.rhq.core.util.exception.WrappedRemotingException;
+import org.rhq.enterprise.server.content.ContentSourceManagerLocal;
+import org.rhq.enterprise.server.util.LookupUtil;
/**
* Server-side implementation of the <code>BundleServerService</code>. This implmentation simply forwards
@@ -40,7 +46,29 @@ public class BundleServerServiceImpl implements BundleServerService {
// TODO Auto-generated method stub
}
- public List<BundleFile> getAllBundleFiles(int bundleVersionId) {
- return null;
+ public List<PackageVersion> getAllBundleVersionPackageVersions(int bundleVersionId) {
+ try {
+ BundleManagerLocal bm = LookupUtil.getBundleManager();
+ List<BundleFile> bundleFiles = bm.findBundleFilesForBundleVersion(bundleVersionId);
+ List<PackageVersion> packageVersions = new ArrayList<PackageVersion>(bundleFiles.size());
+ for (BundleFile bundleFile : bundleFiles) {
+ packageVersions.add(bundleFile.getPackageVersion());
+ }
+ return packageVersions;
+ } catch (Exception e) {
+ log.error("Failed to obtain bundle files for bundle version id: " + bundleVersionId, e);
+ throw new WrappedRemotingException(e);
+ }
+ }
+
+ public long downloadPackageBits(PackageVersion packageVersion, OutputStream outputStream) {
+ try {
+ ContentSourceManagerLocal csm = LookupUtil.getContentSourceManager();
+ long size = csm.outputPackageVersionBits(packageVersion, outputStream);
+ return size;
+ } catch (Exception e) {
+ log.error("Failed to obtain package version bits for package version: " + packageVersion, e);
+ throw new WrappedRemotingException(e);
+ }
}
}
\ No newline at end of file
commit f96e2404b6596f030fdc1d4d54a6a4d0a6c8e36e
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 26 10:20:49 2010 -0500
starting agent side bundle deployment stuff - not even close to useful yet
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleAgentService.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleAgentService.java
index 2e0f2f2..345567f 100644
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleAgentService.java
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleAgentService.java
@@ -30,5 +30,10 @@ package org.rhq.core.clientapi.agent.bundle;
* @author John Mazzitelli
*/
public interface BundleAgentService {
- BundleUpdateResponse update(BundleUpdateRequest request);
+ /**
+ * Schedules the deployment of a bundle to occur immediately.
+ * @param request
+ * @return the results of the immediate scheduling
+ */
+ BundleScheduleResponse schedule(BundleScheduleRequest request);
}
\ No newline at end of file
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleScheduleRequest.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleScheduleRequest.java
new file mode 100644
index 0000000..0b49cd7
--- /dev/null
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleScheduleRequest.java
@@ -0,0 +1,56 @@
+/*
+ * 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, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.rhq.core.clientapi.agent.bundle;
+
+import java.io.Serializable;
+
+import org.rhq.core.domain.bundle.BundleDeployDefinition;
+
+/**
+ * @author John Mazzitelli
+ */
+public class BundleScheduleRequest implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private BundleDeployDefinition bundleDeployDefinition;
+
+ public BundleScheduleRequest(BundleDeployDefinition bundleDef) {
+ this.bundleDeployDefinition = bundleDef;
+ }
+
+ public BundleDeployDefinition getBundleDeployDefinition() {
+ return bundleDeployDefinition;
+ }
+
+ public void setBundleDeployDefinition(BundleDeployDefinition bundleDeployDefinition) {
+ this.bundleDeployDefinition = bundleDeployDefinition;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder str = new StringBuilder(this.getClass() + ": ");
+ str.append(bundleDeployDefinition.toString());
+ return str.toString();
+ }
+}
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleScheduleResponse.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleScheduleResponse.java
new file mode 100644
index 0000000..a82e866
--- /dev/null
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleScheduleResponse.java
@@ -0,0 +1,66 @@
+/*
+ * 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, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.rhq.core.clientapi.agent.bundle;
+
+import java.io.Serializable;
+
+import org.rhq.core.util.exception.ThrowableUtil;
+
+/**
+ * @author John Mazzitelli
+ */
+public class BundleScheduleResponse implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private String errorMessage;
+
+ public BundleScheduleResponse() {
+ }
+
+ public boolean isSuccess() {
+ return this.errorMessage == null;
+ }
+
+ public String getErrorMessage() {
+ return this.errorMessage;
+ }
+
+ public void setErrorMessage(String errorMessage) {
+ this.errorMessage = errorMessage;
+ }
+
+ public void setErrorMessage(Throwable t) {
+ this.errorMessage = ThrowableUtil.getAllMessages(t);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder str = new StringBuilder(this.getClass().getSimpleName());
+ if (getErrorMessage() != null) {
+ str.append(" error=[").append(getErrorMessage()).append("];");
+ }
+ str.append(" success=[").append(isSuccess()).append("]");
+ return str.toString();
+ }
+}
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleUpdateRequest.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleUpdateRequest.java
deleted file mode 100644
index ba0f7b1..0000000
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleUpdateRequest.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 Red Hat, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation, and/or the GNU Lesser
- * General Public License, version 2.1, also as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License and the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * and the GNU Lesser General Public License along with this program;
- * if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-package org.rhq.core.clientapi.agent.bundle;
-
-/**
- * @author John Mazzitelli
- */
-public class BundleUpdateRequest {
-
-}
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleUpdateResponse.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleUpdateResponse.java
deleted file mode 100644
index 9482fb5..0000000
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleUpdateResponse.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 Red Hat, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation, and/or the GNU Lesser
- * General Public License, version 2.1, also as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License and the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * and the GNU Lesser General Public License along with this program;
- * if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-package org.rhq.core.clientapi.agent.bundle;
-
-/**
- * @author John Mazzitelli
- */
-public class BundleUpdateResponse {
-
-}
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleServerService.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleServerService.java
index 2d71236..eb09a4e 100644
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleServerService.java
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleServerService.java
@@ -22,7 +22,10 @@
*/
package org.rhq.core.clientapi.server.bundle;
+import java.util.List;
+
import org.rhq.core.communications.command.annotation.Asynchronous;
+import org.rhq.core.domain.bundle.BundleFile;
/**
* Interface for agents to use when needing to inform the server about bundle tasks. Implementations of this interface, once registered with the
@@ -33,5 +36,7 @@ import org.rhq.core.communications.command.annotation.Asynchronous;
public interface BundleServerService {
@Asynchronous(guaranteedDelivery = true)
- void updateComplete(BundleUpdateComplete buc);
+ void updateStatus(BundleStatusUpdate update);
+
+ List<BundleFile> getAllBundleFiles(int bundleVersionId);
}
\ No newline at end of file
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleStatusUpdate.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleStatusUpdate.java
new file mode 100644
index 0000000..99bdda8
--- /dev/null
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleStatusUpdate.java
@@ -0,0 +1,33 @@
+/*
+ * 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, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.rhq.core.clientapi.server.bundle;
+
+/**
+ * Object that informs the server that a bundle deployment has a new status.
+ * This will be the way the bundle deployment process is tracked.
+ *
+ * @author John Mazzitelli
+ */
+public class BundleStatusUpdate {
+
+}
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleUpdateComplete.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleUpdateComplete.java
deleted file mode 100644
index 0314857..0000000
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleUpdateComplete.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 Red Hat, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation, and/or the GNU Lesser
- * General Public License, version 2.1, also as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License and the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * and the GNU Lesser General Public License along with this program;
- * if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.rhq.core.clientapi.server.bundle;
-
-/**
- *
- * @author John Mazzitelli
- */
-public class BundleUpdateComplete {
-
-}
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployRequest.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployRequest.java
new file mode 100644
index 0000000..40e663b
--- /dev/null
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployRequest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.core.pluginapi.bundle;
+
+import java.io.Serializable;
+
+import org.rhq.core.domain.bundle.BundleDeployDefinition;
+import org.rhq.core.pc.bundle.BundleManager;
+
+/**
+ * A request to deploy a bundle.
+ *
+ * @author John Mazzitelli
+ */
+public class BundleDeployRequest implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private BundleDeployDefinition bundleDeployDefinition;
+ private BundleManager bundleManager;
+
+ public BundleDeployDefinition getBundleDeployDefinition() {
+ return bundleDeployDefinition;
+ }
+
+ public void setBundleDeployDefinition(BundleDeployDefinition bundleDeployDefinition) {
+ this.bundleDeployDefinition = bundleDeployDefinition;
+ }
+
+ public BundleManager getBundleManager() {
+ return bundleManager;
+ }
+
+ public void setBundleManager(BundleManager bundleManager) {
+ this.bundleManager = bundleManager;
+ }
+
+}
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployResult.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployResult.java
new file mode 100644
index 0000000..b2b3628
--- /dev/null
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployResult.java
@@ -0,0 +1,64 @@
+/*
+ * 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, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.rhq.core.pluginapi.bundle;
+
+import java.io.Serializable;
+
+import org.rhq.core.util.exception.ThrowableUtil;
+
+/**
+ * The results after an attempt to deploy a bundle has been completed.
+ * @author John Mazzitelli
+ */
+public class BundleDeployResult implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private String errorMessage;
+
+ public boolean isSuccess() {
+ return this.errorMessage == null;
+ }
+
+ public String getErrorMessage() {
+ return this.errorMessage;
+ }
+
+ public void setErrorMessage(String errorMessage) {
+ this.errorMessage = errorMessage;
+ }
+
+ public void setErrorMessage(Throwable t) {
+ this.errorMessage = ThrowableUtil.getAllMessages(t);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder str = new StringBuilder(this.getClass().getSimpleName());
+ if (getErrorMessage() != null) {
+ str.append(" error=[").append(getErrorMessage()).append("];");
+ }
+ str.append(" success=[").append(isSuccess()).append("]");
+ return str.toString();
+ }
+
+}
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleFacet.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleFacet.java
index cb5ea35..2b76c0c 100644
--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleFacet.java
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleFacet.java
@@ -28,4 +28,5 @@ package org.rhq.core.pluginapi.bundle;
* @author John Mazzitelli
*/
public interface BundleFacet {
+ BundleDeployResult deployBundle(BundleDeployRequest request);
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/ServerServices.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/ServerServices.java
index e109755..33951b6 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/ServerServices.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/ServerServices.java
@@ -1,35 +1,36 @@
- /*
- * 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, 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.
- */
+/*
+ * 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, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
package org.rhq.core.pc;
+import org.rhq.core.clientapi.server.bundle.BundleServerService;
import org.rhq.core.clientapi.server.configuration.ConfigurationServerService;
import org.rhq.core.clientapi.server.content.ContentServerService;
import org.rhq.core.clientapi.server.core.CoreServerService;
import org.rhq.core.clientapi.server.discovery.DiscoveryServerService;
+import org.rhq.core.clientapi.server.event.EventServerService;
import org.rhq.core.clientapi.server.inventory.ResourceFactoryServerService;
import org.rhq.core.clientapi.server.measurement.MeasurementServerService;
import org.rhq.core.clientapi.server.operation.OperationServerService;
-import org.rhq.core.clientapi.server.event.EventServerService;
/**
* Provides access to remote pojo's representing the JON Server's client interfaces. These server service interfaces are
@@ -49,6 +50,7 @@ public class ServerServices {
private ResourceFactoryServerService resourceFactoryServerService;
private ContentServerService contentServerService;
private EventServerService eventServerService;
+ private BundleServerService bundleServerService;
public CoreServerService getCoreServerService() {
return coreServerService;
@@ -113,4 +115,13 @@ public class ServerServices {
public void setEventServerService(EventServerService eventServerService) {
this.eventServerService = eventServerService;
}
+
+ public BundleServerService getBundleServerService() {
+ return bundleServerService;
+ }
+
+ public void setBundleServerService(BundleServerService bundleServerService) {
+ this.bundleServerService = bundleServerService;
+ }
+
}
\ No newline at end of file
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 ff92d8c..4ab1c03 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
@@ -22,15 +22,32 @@
*/
package org.rhq.core.pc.bundle;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.agent.bundle.BundleAgentService;
-import org.rhq.core.clientapi.agent.bundle.BundleUpdateRequest;
-import org.rhq.core.clientapi.agent.bundle.BundleUpdateResponse;
+import org.rhq.core.clientapi.agent.bundle.BundleScheduleRequest;
+import org.rhq.core.clientapi.agent.bundle.BundleScheduleResponse;
+import org.rhq.core.clientapi.server.bundle.BundleServerService;
+import org.rhq.core.domain.bundle.BundleDeployDefinition;
+import org.rhq.core.domain.bundle.BundleFile;
+import org.rhq.core.domain.bundle.BundleType;
+import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.pc.ContainerService;
+import org.rhq.core.pc.PluginContainer;
import org.rhq.core.pc.PluginContainerConfiguration;
import org.rhq.core.pc.agent.AgentService;
+import org.rhq.core.pc.inventory.InventoryManager;
import org.rhq.core.pc.util.ComponentUtil;
import org.rhq.core.pc.util.FacetLockType;
+import org.rhq.core.pluginapi.bundle.BundleDeployRequest;
+import org.rhq.core.pluginapi.bundle.BundleDeployResult;
import org.rhq.core.pluginapi.bundle.BundleFacet;
/**
@@ -41,12 +58,16 @@ import org.rhq.core.pluginapi.bundle.BundleFacet;
* @author John Mazzitelli
*/
public class BundleManager extends AgentService implements BundleAgentService, ContainerService {
+ private final Log log = LogFactory.getLog(BundleManager.class);
+
+ private PluginContainerConfiguration configuration;
public BundleManager() {
super(BundleAgentService.class);
}
public void setConfiguration(PluginContainerConfiguration configuration) {
+ this.configuration = configuration;
}
public void initialize() {
@@ -55,9 +76,66 @@ public class BundleManager extends AgentService implements BundleAgentService, C
public void shutdown() {
}
- public BundleUpdateResponse update(BundleUpdateRequest request) {
- // TODO Auto-generated method stub
- return null;
+ public BundleScheduleResponse schedule(BundleScheduleRequest request) {
+ BundleScheduleResponse response = new BundleScheduleResponse();
+
+ try {
+ BundleDeployDefinition bundleDef = request.getBundleDeployDefinition();
+
+ // find the resource that will handle the bundle processing
+ InventoryManager im = PluginContainer.getInstance().getInventoryManager();
+ BundleType bundleType = bundleDef.getBundleVersion().getBundle().getBundleType();
+ ResourceType resourceType = bundleType.getResourceType();
+ Set<Resource> resources = im.getResourcesWithType(resourceType);
+ if (resources.isEmpty()) {
+ throw new Exception("No bundle plugin supports bundle type [" + bundleType + "]");
+ }
+ int bundleHandlerResourceId = resources.iterator().next().getId();
+
+ // get the bundle facet object that will process the bundle
+ int facetMethodTimeout = 4 * 60 * 60 * 1000; // 4 hours is given to the bundle plugin to do its thing
+ BundleFacet bundlePluginComponent = getBundleFacet(bundleHandlerResourceId, facetMethodTimeout);
+
+ // deploy the bundle utilizing the bundle facet object
+ BundleDeployRequest deployRequest = new BundleDeployRequest();
+ deployRequest.setBundleManager(this);
+ deployRequest.setBundleDeployDefinition(request.getBundleDeployDefinition());
+ BundleDeployResult result = bundlePluginComponent.deployBundle(deployRequest);
+ if (!result.isSuccess()) {
+ response.setErrorMessage(result.getErrorMessage());
+ }
+ } catch (Throwable t) {
+ log.error("Failed to schedule bundle request: " + request, t);
+ response.setErrorMessage(t);
+ }
+
+ return response;
+ }
+
+ /**
+ * This is used by bundle plugins - bundle plugins call back into this manager to obtain the
+ * bundle files that belong to a given bundle version.
+ *
+ * @param bundleVersion
+ * @return the bundle files that are associated with the given bundle
+ * @throws Exception
+ */
+ public List<BundleFile> getAllBundleFiles(BundleVersion bundleVersion) throws Exception {
+ List<BundleFile> bundleFiles = getBundleServerService().getAllBundleFiles(bundleVersion.getId());
+ return bundleFiles;
+ }
+
+ /**
+ * If this manager can talk to a server-side {@link BundleServerService}, a proxy to that service is returned.
+ *
+ * @return the server-side proxy; <code>null</code> if this manager doesn't have a server to talk to
+ */
+ private BundleServerService getBundleServerService() {
+ if (configuration.getServerServices() != null) {
+ return configuration.getServerServices().getBundleServerService();
+ }
+
+ throw new IllegalStateException("There is no bundle server service available to obtain bundle files");
}
/**
@@ -66,13 +144,14 @@ public class BundleManager extends AgentService implements BundleAgentService, C
* The resource must be in the STARTED (i.e. connected) state.
*
* @param resourceId identifies the resource that is to perform the bundle activities
+ * @param timeout if any facet method invocation thread has not completed after this many milliseconds, interrupt
+ * it; value must be positive
*
* @return the resource's bundle facet interface
*
* @throws PluginContainerException on error
*/
- protected BundleFacet getBundleFacet(int resourceId, long facetMethodTimeout) throws PluginContainerException {
- return ComponentUtil.getComponent(resourceId, BundleFacet.class, FacetLockType.READ, facetMethodTimeout, false,
- true);
+ private BundleFacet getBundleFacet(int resourceId, long timeout) throws PluginContainerException {
+ return ComponentUtil.getComponent(resourceId, BundleFacet.class, FacetLockType.READ, timeout, false, true);
}
}
diff --git a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
index 94513d0..19624fa 100644
--- a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
+++ b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
@@ -68,6 +68,7 @@ import org.jboss.remoting.security.SSLSocketBuilder;
import org.jboss.remoting.transport.http.ssl.HTTPSClientInvoker;
import org.jboss.util.StringPropertyReplacer;
+import org.rhq.core.clientapi.server.bundle.BundleServerService;
import org.rhq.core.clientapi.server.configuration.ConfigurationServerService;
import org.rhq.core.clientapi.server.content.ContentServerService;
import org.rhq.core.clientapi.server.core.AgentNotSupportedException;
@@ -1648,6 +1649,7 @@ public class AgentMain {
.getRemotePojo(ResourceFactoryServerService.class);
ContentServerService contentServerService = factory.getRemotePojo(ContentServerService.class);
EventServerService eventServerService = factory.getRemotePojo(EventServerService.class);
+ BundleServerService bundleServerService = factory.getRemotePojo(BundleServerService.class);
ServerServices serverServices = new ServerServices();
serverServices.setCoreServerService(coreServerService);
@@ -1658,6 +1660,7 @@ public class AgentMain {
serverServices.setResourceFactoryServerService(resourceFactoryServerSerfice);
serverServices.setContentServerService(contentServerService);
serverServices.setEventServerService(eventServerService);
+ serverServices.setBundleServerService(bundleServerService);
pc_config.setServerServices(serverServices);
} catch (Exception e) {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java
index a676704..fa84821 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java
@@ -18,11 +18,14 @@
*/
package org.rhq.enterprise.server.bundle;
+import java.util.List;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rhq.core.clientapi.server.bundle.BundleServerService;
-import org.rhq.core.clientapi.server.bundle.BundleUpdateComplete;
+import org.rhq.core.clientapi.server.bundle.BundleStatusUpdate;
+import org.rhq.core.domain.bundle.BundleFile;
/**
* Server-side implementation of the <code>BundleServerService</code>. This implmentation simply forwards
@@ -33,7 +36,11 @@ import org.rhq.core.clientapi.server.bundle.BundleUpdateComplete;
public class BundleServerServiceImpl implements BundleServerService {
private final Log log = LogFactory.getLog(this.getClass());
- public void updateComplete(BundleUpdateComplete buc) {
+ public void updateStatus(BundleStatusUpdate update) {
// TODO Auto-generated method stub
}
+
+ public List<BundleFile> getAllBundleFiles(int bundleVersionId) {
+ return null;
+ }
}
\ No newline at end of file
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
index 08eb7b4..a7100ec 100644
--- a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
@@ -22,6 +22,8 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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.inventory.ResourceComponent;
import org.rhq.core.pluginapi.inventory.ResourceContext;
@@ -46,4 +48,11 @@ public class FileTemplateBundlePluginServerComponent implements ResourceComponen
public AvailabilityType getAvailability() {
return AvailabilityType.UP;
}
+
+ @Override
+ public BundleDeployResult deployBundle(BundleDeployRequest request) {
+ // TODO
+ BundleDeployResult result = new BundleDeployResult();
+ return result;
+ }
}
commit 04bf57471b1df335789d03a77b348728db8ab9f8
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Wed Feb 24 12:21:24 2010 -0500
don't bother looping/logging if debug not enabled.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java
index ef27906..dd943e0 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java
@@ -125,8 +125,11 @@ public abstract class Criteria implements Serializable {
results.put(getCleansedFieldName(filterField, 6), filterFieldValue);
}
}
- for (Map.Entry<String, Object> entries : results.entrySet()) {
- LOG.debug("Filter: (" + entries.getKey() + ", " + entries.getValue() + ")");
+
+ if (LOG.isDebugEnabled()) {
+ for (Map.Entry<String, Object> entries : results.entrySet()) {
+ LOG.debug("Filter: (" + entries.getKey() + ", " + entries.getValue() + ")");
+ }
}
return results;
}
@@ -160,8 +163,10 @@ public abstract class Criteria implements Serializable {
}
}
}
- for (String entry : results) {
- LOG.debug("Fetch: (" + entry + ")");
+ if (LOG.isDebugEnabled()) {
+ for (String entry : results) {
+ LOG.debug("Fetch: (" + entry + ")");
+ }
}
return results;
}
@@ -283,7 +288,9 @@ public abstract class Criteria implements Serializable {
}
}
}
- LOG.debug("Page Control: " + pc);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Page Control: " + pc);
+ }
return pc;
}
commit 27317cceaaffe3c97a9c6c22318fa36ce748b5db
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Feb 23 13:31:57 2010 -0500
given a bundle type name, you can now get a plugin component from the bundle plugin that supports that type.
BundleServerPluginFacet will be the interface of the bundle server plugin to the outside world (the SLSBs for example)
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java
index 768162f..5f75e96 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java
@@ -486,7 +486,6 @@ public class ServerPluginManager {
*
* The new object will be loaded in the plugin's specific classloader.
*
- * @param pluginName the name of the plugin whose main component is to be retrieved
* @param environment the environment in which the plugin will execute
*
* @return a new object loaded in the proper plugin classloader that can initialize/shutdown the plugin,
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/bundle/BundleServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/bundle/BundleServerPluginContainer.java
index 59eb94c..6814b2b 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/bundle/BundleServerPluginContainer.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/bundle/BundleServerPluginContainer.java
@@ -44,4 +44,9 @@ public class BundleServerPluginContainer extends AbstractTypeServerPluginContain
protected ServerPluginManager createPluginManager() {
return new BundleServerPluginManager(this);
}
+
+ public BundleServerPluginManager getBundleServerPluginManager() {
+ return (BundleServerPluginManager) getPluginManager();
+ }
+
}
\ No newline at end of file
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
new file mode 100644
index 0000000..0585a4b
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/bundle/BundleServerPluginFacet.java
@@ -0,0 +1,29 @@
+/*
+ * 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.server.plugin.pc.bundle;
+
+/**
+ * All bundle server plugins must implement this facet.
+ *
+ * @author John Mazzitelli
+ */
+public interface BundleServerPluginFacet {
+
+}
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 c1b542d..68f8a0f 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,8 +18,11 @@
*/
package org.rhq.enterprise.server.plugin.pc.bundle;
+import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment;
import org.rhq.enterprise.server.plugin.pc.ServerPluginManager;
+import org.rhq.enterprise.server.xmlschema.generated.serverplugin.bundle.BundlePluginDescriptorType;
+import org.rhq.enterprise.server.xmlschema.generated.serverplugin.bundle.BundleType;
/**
* This loads in all bundle server plugins that can be found. You can obtain a loaded plugin's
@@ -38,4 +41,55 @@ public class BundleServerPluginManager extends ServerPluginManager {
public void initialize() throws Exception {
super.initialize();
}
+
+ @Override
+ protected void loadPlugin(ServerPluginEnvironment env, boolean enabled) throws Exception {
+ if (enabled) {
+ // validate some things about this plugin that are specific for bundle functionality
+
+ BundlePluginDescriptorType descriptor = (BundlePluginDescriptorType) env.getPluginDescriptor();
+ BundleType bt = descriptor.getBundle();
+ if (bt == null || bt.getType() == null || bt.getType().length() == 0) {
+ // if the xml parser did its job, this will probably never happen, but just in case, make sure there is
+ // a non-null, valid bundle type name - we have other code that expects this to be true
+ throw new Exception("The bundle plugin [" + env.getPluginKey().getPluginName()
+ + "] did not specify a valid bundle type in its descriptor");
+ }
+
+ ServerPluginComponent component = createServerPluginComponent(env);
+ if (!(component instanceof BundleServerPluginFacet)) {
+ throw new Exception("The bundle plugin [" + env.getPluginKey().getPluginName()
+ + "] has an invalid component [" + component + "]. It does not implement ["
+ + BundleServerPluginFacet.class + "]");
+ }
+ }
+
+ super.loadPlugin(env, enabled);
+ }
+
+ /**
+ * Given the {@link BundleType#getName() name of a bundle type}, this will return the stateful plugin component
+ * that manages bundles of that type.
+ *
+ * @param bundleTypeName
+ *
+ * @return the plugin component object that will manage bundles of the named bundle type; <code>null</code> if there is no plugin
+ * that can support the given bundle type
+ */
+ public BundleServerPluginFacet getBundleServerPluginFacet(String bundleTypeName) {
+ if (bundleTypeName == null) {
+ throw new IllegalArgumentException("bundleTypeName == null");
+ }
+
+ for (ServerPluginEnvironment env : getPluginEnvironments()) {
+ BundlePluginDescriptorType descriptor = (BundlePluginDescriptorType) env.getPluginDescriptor();
+ if (bundleTypeName.equals(descriptor.getBundle().getType())) {
+ ServerPluginComponent component = getServerPluginComponent(env.getPluginKey().getPluginName());
+ // we know this cast will work because our loadPlugin ensured that this component implements this interface
+ return (BundleServerPluginFacet) component;
+ }
+ }
+
+ return null;
+ }
}
\ No newline at end of file
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 0e8659e..58dd5b1 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
@@ -25,13 +25,14 @@ import org.rhq.enterprise.server.plugin.pc.ControlFacet;
import org.rhq.enterprise.server.plugin.pc.ControlResults;
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;
/**
* A bundle server-side plugin component that the server uses to process file template bundles.
*
* @author John Mazzitelli
*/
-public class BundleServerPluginComponent implements ServerPluginComponent, ControlFacet {
+public class BundleServerPluginComponent implements ServerPluginComponent, BundleServerPluginFacet, ControlFacet {
private ServerPluginContext context;
commit 76b177feed88fd1706a93e75f7453f67bc5be890
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 22 12:14:28 2010 -0500
Add OneToOne Bundle-Repo relation to db upgrade, domain, criteria and test
code. Change to CascadeType all such that the repo is added and removed
implicitly (i.e. owned by the bundle).
diff --git a/modules/core/dbutils/pom.xml b/modules/core/dbutils/pom.xml
index 1cc3eee..ca2d943 100644
--- a/modules/core/dbutils/pom.xml
+++ b/modules/core/dbutils/pom.xml
@@ -22,7 +22,7 @@
<properties>
<scm.module.path>modules/core/dbutils/</scm.module.path>
- <db.schema.version>2.78</db.schema.version>
+ <db.schema.version>2.78.1</db.schema.version>
</properties>
<dependencies>
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
index 565b0f1..8169695 100644
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@ -3166,9 +3166,21 @@
<schema-addColumn table="RHQ_BUNDLE_DEPLOY_HIST" column="AUDIT_MESSAGE" columnType="LONGVARCHAR" />
<!-- Changes to RHQ_BUNDLE_FILE -->
- <schema-alterColumn table="RHQ_BUNDLE_FILE" column="PACKAGE_VERSION_ID" nullable="FALSE" />
-
- </schemaSpec>
+ <schema-alterColumn table="RHQ_BUNDLE_FILE" column="PACKAGE_VERSION_ID" nullable="FALSE" />
+ </schemaSpec>
+
+ <schemaSpec version="2.78.1">
+ <schema-addColumn table="RHQ_BUNDLE" column="REPO_ID" columnType="INTEGER" />
+ <schema-directSQL>
+ <statement desc="Creating RHQ_BUNDLE foreign key relation to RHQ_REPO">
+ ALTER TABLE RHQ_BUNDLE
+ ADD CONSTRAINT RHQ_REPO_ID_FK
+ FOREIGN KEY (REPO_ID)
+ REFERENCES RHQ_REPO (ID)
+ </statement>
+ </schema-directSQL>
+ </schemaSpec>
+
</dbupgrade>
</target>
</project>
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
index 8109117..02f4a5f 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
@@ -83,7 +83,7 @@ public class Bundle implements Serializable {
private BundleType bundleType;
@JoinColumn(name = "REPO_ID", referencedColumnName = "ID", nullable = false)
- @OneToOne(fetch = FetchType.LAZY, optional = false, cascade = CascadeType.PERSIST)
+ @OneToOne(fetch = FetchType.LAZY, optional = false, cascade = CascadeType.ALL)
private Repo repo;
@OneToMany(mappedBy = "bundle", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@@ -96,6 +96,11 @@ public class Bundle implements Serializable {
public Bundle(String name, BundleType type) {
setName(name);
setBundleType(type);
+ // add implicit Repo
+ Repo repo = new Repo(name);
+ repo.setCandidate(false);
+ repo.setSyncSchedule(null);
+ setRepo(repo);
}
public int getId() {
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java
index 5c40cd0..aed446a 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java
@@ -40,6 +40,7 @@ public class BundleCriteria extends Criteria {
private String filterName;
private boolean fetchBundleVersions;
+ private boolean fetchRepo;
public BundleCriteria() {
super(Bundle.class);
@@ -67,4 +68,9 @@ public class BundleCriteria extends Criteria {
public void fetchBundleVersions(boolean fetchBundleVersions) {
this.fetchBundleVersions = fetchBundleVersions;
}
+
+ public void fetchRepo(boolean fetchRepo) {
+ this.fetchRepo = fetchRepo;
+ }
+
}
diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/bundle/test/BundleTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/bundle/test/BundleTest.java
index 83b9f9f..5b95575 100644
--- a/modules/core/domain/src/test/java/org/rhq/core/domain/bundle/test/BundleTest.java
+++ b/modules/core/domain/src/test/java/org/rhq/core/domain/bundle/test/BundleTest.java
@@ -240,7 +240,9 @@ public class BundleTest extends AbstractEJB3Test {
em.persist(b);
id = b.getId();
assert id > 0;
- assert b.getBundleType().getId() != 0 : "bundleType should have been cascade persisted too";
+ assert b.getBundleType().getId() != 0 : "bundleType should have been persisted independently";
+ assert b.getRepo().getId() != 0 : "bundle's repo should have been cascade persisted with the bundle";
+ assert name.equals(b.getRepo().getName()) : "bundle's repo should have same name as bundle";
q = em.createNamedQuery(Bundle.QUERY_FIND_BY_NAME);
q.setParameter("name", name);
@@ -283,6 +285,15 @@ public class BundleTest extends AbstractEJB3Test {
em.close();
getTransactionManager().commit();
+ // make sure we did cascade delete the repo
+ getTransactionManager().begin();
+ em = getEntityManager();
+ q = em.createNamedQuery(Repo.QUERY_FIND_BY_NAME);
+ q.setParameter("name", bFind.getRepo().getName());
+ assert q.getResultList().size() == 0 : "didn't clean up test repo";
+ em.close();
+ getTransactionManager().commit();
+
done = true;
} catch (Throwable t) {
t.printStackTrace();
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 2d9fd9d..747b980 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
@@ -72,11 +72,13 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
private ResourceTypeManagerLocal resourceTypeManager;
public Bundle createBundle(Subject subject, Bundle bundle) {
- // add the implicit bundle repo
- Repo repo = new Repo(bundle.getName());
- repo.setCandidate(false);
- repo.setSyncSchedule(null);
- bundle.setRepo(repo);
+ // add the implicit bundle repo, if necessary
+ if (null == bundle.getRepo()) {
+ Repo repo = new Repo(bundle.getName());
+ repo.setCandidate(false);
+ repo.setSyncSchedule(null);
+ bundle.setRepo(repo);
+ }
entityManager.persist(bundle);
return bundle;
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
index 4003c40..e381dd4 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
@@ -35,6 +35,7 @@ import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.content.Repo;
import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleVersionCriteria;
import org.rhq.core.domain.resource.ResourceCategory;
@@ -86,6 +87,12 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
em.remove(em.getReference(Bundle.class, ((Bundle) removeMe).getId()));
}
+ q = em.createQuery("SELECT r FROM Repo r WHERE r.name LIKE '" + TEST_PREFIX + "%'");
+ doomed = q.getResultList();
+ for (Object removeMe : doomed) {
+ em.remove(em.getReference(Repo.class, ((Repo) removeMe).getId()));
+ }
+
q = em.createQuery("SELECT bt FROM BundleType bt WHERE bt.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
for (Object removeMe : doomed) {
@@ -170,6 +177,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
c.addFilterName(b.getName());
c.addFilterBundleTypeName(b.getName());
c.fetchBundleVersions(true);
+ c.fetchRepo(true);
bundles = bundleManagerBean.findBundlesByCriteria(getOverlord(), c);
assertNotNull(bundles);
assertEquals(1, bundles.size());
@@ -181,6 +189,9 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
BundleVersion bv = b.getBundleVersions().get(0);
assertEquals(bv2, bv);
assertEquals(b, bv.getBundle());
+ Repo r = b.getRepo();
+ assertNotNull(r);
+ assertEquals(b.getName(), r.getName());
}
@Test(enabled = ENABLED)
commit 9bf4056f5e52ed6d28b6e1b376413ade0645d37e
Merge: ebdfffd... 828a173...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 22 10:50:23 2010 -0500
Merge branch 'bundle' into bundle-jay
Conflicts:
.classpath
diff --cc modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
index 1882586,1882586..0817125
--- a/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
@@@ -499,6 -499,6 +499,7 @@@
<column name="ID" default="sequence-only" initial="10001" primarykey="true" required="true" type="INTEGER"/>
<column name="NAME" size="200" type="VARCHAR2" required="true"/>
<column name="BUNDLE_TYPE_ID" type="INTEGER" required="true" references="RHQ_BUNDLE_TYPE"/>
++ <column name="REPO_ID" type="INTEGER" required="true" references="RHQ_REPO"/>
</table>
<!-- BUNDLE_VERSION represents an actual piece of content that needs to be installed somewhere -->
commit ebdfffdb1241ec829af2c3bb7b47ee9cb12e0240
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 22 10:44:50 2010 -0500
update .classpath to reflect the latest change in base perspective war (not
bundle related)
diff --git a/.classpath b/.classpath
index e9a098f..bb17f97 100644
--- a/.classpath
+++ b/.classpath
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="modules/common/jboss-as/src/main/java"/>
- <classpathentry kind="src" path="etc/modules/base-perspective-war/src/main/java"/>
+ <classpathentry kind="src" path="modules/enterprise/gui/base-perspective-jar/src/main/java"/>
<classpathentry kind="src" path="modules/enterprise/server/plugins/jboss-software/src/test/java"/>
<classpathentry kind="src" path="modules/enterprise/server/plugins/jboss-software/src/main/java"/>
<classpathentry kind="src" path="modules/enterprise/remoting/client-api/src/main/java"/>
commit 2f2a2721301232f9d06c52a6a022ab45397f9c4b
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 22 10:44:15 2010 -0500
- Add 1 to 1 relation between Bundle and its implicit Repo.
- Remove bundleType from the natural key of a Bundle. The NK
is now just the bundle name, which is then used as the name of the
implicit Repo.
- SLSB createBundle() now creates the bundle's implicit repo under the
covers. The repo is named after the bundle, has no sync sched and is
isCandidate is set to false.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
index 783b707..8109117 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
@@ -38,11 +38,14 @@ import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
+import org.rhq.core.domain.content.Repo;
+
/**
* Defines a bundle of content that can be versioned.
*
@@ -79,6 +82,10 @@ public class Bundle implements Serializable {
@ManyToOne(fetch = FetchType.EAGER)
private BundleType bundleType;
+ @JoinColumn(name = "REPO_ID", referencedColumnName = "ID", nullable = false)
+ @OneToOne(fetch = FetchType.LAZY, optional = false, cascade = CascadeType.PERSIST)
+ private Repo repo;
+
@OneToMany(mappedBy = "bundle", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<BundleVersion> bundleVersions = new ArrayList<BundleVersion>();
@@ -115,6 +122,14 @@ public class Bundle implements Serializable {
this.bundleType = bundleType;
}
+ public Repo getRepo() {
+ return repo;
+ }
+
+ public void setRepo(Repo repo) {
+ this.repo = repo;
+ }
+
public List<BundleVersion> getBundleVersions() {
return bundleVersions;
}
@@ -138,7 +153,6 @@ public class Bundle implements Serializable {
final int prime = 31;
int result = 1;
result = (prime * result) + ((name == null) ? 0 : name.hashCode());
- result = (prime * result) + ((bundleType == null) ? 0 : bundleType.hashCode());
return result;
}
@@ -162,14 +176,6 @@ public class Bundle implements Serializable {
return false;
}
- if (bundleType == null) {
- if (other.bundleType != null) {
- return false;
- }
- } else if (!bundleType.equals(other.bundleType)) {
- return false;
- }
-
return true;
}
}
\ No newline at end of file
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 3045872..2d9fd9d 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
@@ -37,6 +37,7 @@ import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleDeployment;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.content.Repo;
import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleDeployDefinitionCriteria;
import org.rhq.core.domain.criteria.BundleDeploymentCriteria;
@@ -71,6 +72,12 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
private ResourceTypeManagerLocal resourceTypeManager;
public Bundle createBundle(Subject subject, Bundle bundle) {
+ // add the implicit bundle repo
+ Repo repo = new Repo(bundle.getName());
+ repo.setCandidate(false);
+ repo.setSyncSchedule(null);
+ bundle.setRepo(repo);
+
entityManager.persist(bundle);
return bundle;
}
@@ -189,14 +196,13 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
int bundleVersionCount = random.nextInt(5) + 1;
for (int i = 0; i < bundleVersionCount; i++) {
String bundleVersionName = UUID.randomUUID().toString();
- final String RECIPE = "repo rhel-x86_64-5\n" +
- "package foo-1.25.rpm\n" +
- "package bar-1.25.rpm\n" +
- "script foo.bash -c some parameter\n" +
- "deploy jboss.tar %{jboss.home.directory}\n" +
- "realize %{jboss.home.directory}/server/default/setting.xml\n" +
- "file example.setting /etc/some/setting.ini\n" +
- "service example restart\n";
+ final String RECIPE = "repo rhel-x86_64-5\n" //
+ + "package foo-1.25.rpm\n" //
+ + "package bar-1.25.rpm\n" //
+ + "script foo.bash -c some parameter\n" //
+ + "deploy jboss.tar %{jboss.home.directory}\n" //
+ + "realize %{jboss.home.directory}/server/default/setting.xml\n" //
+ + "file example.setting /etc/some/setting.ini\n" + "service example restart\n";
BundleVersion bundleVersion = new BundleVersion(bundleVersionName, String.valueOf(i + 1), null, RECIPE);
bundle.addBundleVersion(bundleVersion);
}
commit b6e1eba41e09a48e21eef602f7b281a48d03db74
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 22 10:35:54 2010 -0500
tweak to improve debug logging in rt log handling. (not bundle related)
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/util/ResponseTimeLogParser.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/util/ResponseTimeLogParser.java
index 6f825b2..a3efb74 100644
--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/util/ResponseTimeLogParser.java
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/util/ResponseTimeLogParser.java
@@ -218,12 +218,13 @@ public class ResponseTimeLogParser {
}
private void truncateLog(File logFile) throws IOException {
- log.debug("Truncating response-time log file '" + logFile + "'...");
+ log.debug("Truncating response-time log file: '" + logFile + "'...");
RandomAccessFile randomAccessFile = null;
try {
String mode = "rws";
randomAccessFile = new RandomAccessFile(logFile, mode);
+ log.debug("Truncating response-time log file: setting length to 0.");
randomAccessFile.setLength(0);
} catch (SecurityException e) {
/* User doesn't have permission to change the length, so
@@ -238,6 +239,7 @@ public class ResponseTimeLogParser {
} finally {
if (null != randomAccessFile) {
try {
+ log.debug("Truncating response-time log file: closing file.");
randomAccessFile.close();
} catch (Exception e) {
log.error("Unable to close response-time log file.", e);
commit 828a1738713978ea9ec163cc3852aad3db17efab
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 19 17:51:53 2010 -0500
i think this should report an error always on lock acq failure. we'll leave the flag alone - don't set it to true - let the next call take care of whether or not the init callback should be invoked or not
diff --git a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
index 8c37b50..cd3b479 100644
--- a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
+++ b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
@@ -588,11 +588,9 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
writeLock.unlock();
}
} else {
- if (m_needToCallInitializeCallback) {
- Throwable t = new Throwable("Initialize callback lock could not be acquired");
- LOG.error(CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, t.getMessage());
- return new GenericCommandResponse(command, false, null, t);
- }
+ Throwable t = new Throwable("Initialize callback lock could not be acquired");
+ LOG.error(CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, t.getMessage());
+ return new GenericCommandResponse(command, false, null, t);
}
}
return null;
commit aa5d97b46edc37ebd619f4ee4ef0a28486ad4c8e
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 19 17:44:11 2010 -0500
should not worry about the lock failure if the init callback doesn't need to be invoked anyway
diff --git a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
index 762b9b4..8c37b50 100644
--- a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
+++ b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
@@ -588,10 +588,11 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
writeLock.unlock();
}
} else {
- m_needToCallInitializeCallback = true; // can't invoke callback, we'll want to still call it later
- Throwable t = new Throwable("Initialize callback lock could not be acquired");
- LOG.error(CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, t.getMessage());
- return new GenericCommandResponse(command, false, null, t);
+ if (m_needToCallInitializeCallback) {
+ Throwable t = new Throwable("Initialize callback lock could not be acquired");
+ LOG.error(CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, t.getMessage());
+ return new GenericCommandResponse(command, false, null, t);
+ }
}
}
return null;
commit 9b464808786abd46f1197ebe2a790e52ac312025
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 19 17:38:16 2010 -0500
BZ 537396 - to not block indefinitely if a lock cannot be acquired before attempting to invoke the initialize callback
diff --git a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
index 3775212..762b9b4 100644
--- a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
+++ b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
@@ -21,6 +21,9 @@ package org.rhq.enterprise.communications.command.client;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
import mazz.i18n.Logger;
@@ -95,10 +98,22 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
private InitializeCallback m_initializeCallback;
/**
- * When the first element is <code>true</code>, the initialize callback will need to be called prior
- * to sending any commands. This is an array because the array itself is used for its lock.
+ * When <code>true</code>, the initialize callback will need to be called prior
+ * to sending any commands. Used in conjunection with its associated RW lock.
*/
- private final boolean[] m_needToCallInitializeCallback;
+ private boolean m_needToCallInitializeCallback;
+
+ /**
+ * RW lock when needing to access its associated atomic boolean flag.
+ */
+ private final ReentrantReadWriteLock m_needToCallInitializeCallbackLock;
+
+ /**
+ * Number of minutes to wait while attempting to aquire a lock before attempting
+ * to invoke the initialize callback. If this amount of minutes expires before the lock
+ * is acquired, an error will occur and the initialize callback will have to be attempted later.
+ */
+ private final long m_initializeCallbackLockAcquisitionTimeoutMins;
/**
* Constructor for {@link JBossRemotingRemoteCommunicator} that initializes the client with no invoker locator
@@ -200,7 +215,17 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
m_clientConfiguration.putAll(client_config);
}
- m_needToCallInitializeCallback = new boolean[] { false };
+ m_needToCallInitializeCallback = false;
+ m_needToCallInitializeCallbackLock = new ReentrantReadWriteLock();
+
+ long mins;
+ try {
+ String minsStr = System.getProperty("rhq.communications.initial-callback-lock-wait-mins", "60");
+ mins = Long.parseLong(minsStr);
+ } catch (Throwable t) {
+ mins = 60L;
+ }
+ m_initializeCallbackLockAcquisitionTimeoutMins = mins;
return;
}
@@ -319,7 +344,7 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
if (m_remotingClient != null) {
m_remotingClient.disconnect();
m_remotingClient = null;
- m_needToCallInitializeCallback[0] = (getInitializeCallback() != null); // specifically do not synchronize, just set it
+ m_needToCallInitializeCallback = (getInitializeCallback() != null); // specifically do not synchrononize by using lock, just set it
}
LOG.info(CommI18NResourceKeys.COMMUNICATOR_CHANGING_ENDPOINT, m_invokerLocator, locator);
@@ -377,7 +402,7 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
public void setInitializeCallback(InitializeCallback callback) {
m_initializeCallback = callback;
- m_needToCallInitializeCallback[0] = (callback != null); // specifically do not synchronize, just set it
+ m_needToCallInitializeCallback = (callback != null); // specifically do not synchrononize by using lock, just set it
}
public String getRemoteEndpoint() {
@@ -403,7 +428,7 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
public void connect() throws Exception {
if ((m_remotingClient != null) && !m_remotingClient.isConnected()) {
m_remotingClient.connect();
- m_needToCallInitializeCallback[0] = (getInitializeCallback() != null); // specifically do not synchronize, just set it
+ m_needToCallInitializeCallback = (getInitializeCallback() != null); // specifically do not synchrononize by using lock, just set it
}
return;
@@ -412,7 +437,7 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
public void disconnect() {
if (m_remotingClient != null) {
m_remotingClient.disconnect();
- m_needToCallInitializeCallback[0] = (getInitializeCallback() != null); // specifically do not synchronize, just set it
+ m_needToCallInitializeCallback = (getInitializeCallback() != null); // specifically do not synchrononize by using lock, just set it
}
return;
@@ -535,18 +560,38 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
private CommandResponse invokeInitializeCallbackIfNeeded(Command command) {
InitializeCallback callback = getInitializeCallback();
if (callback != null) {
- // block here - in effect, this will stop all commands from going out until the callback is done
- synchronized (m_needToCallInitializeCallback) {
- if (m_needToCallInitializeCallback[0]) {
- try {
- m_needToCallInitializeCallback[0] = !callback.sendingInitialCommand(this, command);
- LOG.debug(CommI18NResourceKeys.INITIALIZE_CALLBACK_DONE, m_needToCallInitializeCallback[0]);
- } catch (Throwable t) {
- m_needToCallInitializeCallback[0] = true; // callback failed, we'll want to call it again
- LOG.error(t, CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, ThrowableUtil.getAllMessages(t));
- return new GenericCommandResponse(command, false, null, t);
+ // block here - in effect, this will stop all commands from going out until the callback is done
+ // to avoid infinite blocking, we'll only wait for a set time (though long).
+
+ WriteLock writeLock = m_needToCallInitializeCallbackLock.writeLock();
+ boolean locked;
+ try {
+ locked = writeLock.tryLock(m_initializeCallbackLockAcquisitionTimeoutMins, TimeUnit.MINUTES);
+ } catch (InterruptedException ie) {
+ locked = false;
+ }
+
+ if (locked) {
+ try {
+ if (m_needToCallInitializeCallback) {
+ try {
+ m_needToCallInitializeCallback = (!callback.sendingInitialCommand(this, command));
+ LOG.debug(CommI18NResourceKeys.INITIALIZE_CALLBACK_DONE, m_needToCallInitializeCallback);
+ } catch (Throwable t) {
+ m_needToCallInitializeCallback = true; // callback failed, we'll want to call it again
+ LOG.error(t, CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, ThrowableUtil
+ .getAllMessages(t));
+ return new GenericCommandResponse(command, false, null, t);
+ }
}
+ } finally {
+ writeLock.unlock();
}
+ } else {
+ m_needToCallInitializeCallback = true; // can't invoke callback, we'll want to still call it later
+ Throwable t = new Throwable("Initialize callback lock could not be acquired");
+ LOG.error(CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, t.getMessage());
+ return new GenericCommandResponse(command, false, null, t);
}
}
return null;
commit a8f8356472ef662fdef16ca6b8db2d1c2b64469e
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 19 02:53:49 2010 -0500
create a peer package type for all bundle types during metadata updates
fix the plugin validator - it wasn't flagging failures when it should have been
fix the virt plugin due to the plugin validation failure that was now correctly detected
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/PluginMetadataParser.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/PluginMetadataParser.java
index 5d38963..26bf354 100644
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/PluginMetadataParser.java
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/PluginMetadataParser.java
@@ -50,6 +50,7 @@ import org.rhq.core.clientapi.descriptor.plugin.ServerDescriptor;
import org.rhq.core.clientapi.descriptor.plugin.ServiceDescriptor;
import org.rhq.core.clientapi.descriptor.plugin.SubCategoryDescriptor;
import org.rhq.core.domain.bundle.BundleType;
+import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.event.EventDefinition;
import org.rhq.core.domain.measurement.MeasurementDefinition;
import org.rhq.core.domain.resource.ClassLoaderType;
@@ -59,6 +60,7 @@ import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceCreationDataType;
import org.rhq.core.domain.resource.ResourceSubCategory;
import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.util.StringUtils;
/**
* This is a stateful class intended to hold the related metadata for a single plugin descriptor. It is designed to be
@@ -165,6 +167,8 @@ public class PluginMetadataParser {
+ "The <runs-inside> information will be ignored in resource type: " + platformResourceType);
}
+ platformResourceType.setCreateDeletePolicy(CreateDeletePolicy.NEITHER);
+
return platformResourceType;
}
@@ -523,6 +527,18 @@ public class PluginMetadataParser {
if (bundle != null) {
String typeName = bundle.getType();
resourceType.setBundleType(new BundleType(typeName, resourceType));
+
+ // create the peer package type for the bundle type
+ PackageType bundlePackageType = new PackageType();
+ bundlePackageType.setName(typeName);
+ bundlePackageType.setDescription("Package type for content of bundles of type " + typeName);
+ bundlePackageType.setCategory(null);
+ bundlePackageType.setSupportsArchitecture(false);
+ bundlePackageType.setDisplayName(StringUtils.deCamelCase(typeName));
+ bundlePackageType.setDiscoveryInterval(-1L);
+ bundlePackageType.setCreationData(false);
+ bundlePackageType.setDeploymentConfigurationDefinition(null);
+ resourceType.addPackageType(bundlePackageType);
}
} catch (InvalidPluginDescriptorException e) {
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/content/ContentManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/content/ContentManager.java
index 90f0cd6..673ba1a 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/content/ContentManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/content/ContentManager.java
@@ -354,10 +354,22 @@ public class ContentManager extends AgentService implements ContainerService, Co
discoveryInfo.getResourceId());
if (resourceContainer != null) {
- log.debug("Rescheduling [" + discoveryInfo + "]...");
- discoveryInfo.setNextDiscovery(System.currentTimeMillis() + discoveryInfo.getInterval());
- addToQueue(discoveryInfo);
- log.debug("Finished rescheduling: " + discoveryInfo);
+ boolean debugEnabled = log.isDebugEnabled();
+
+ if (discoveryInfo.getInterval() > 0) {
+ if (debugEnabled) {
+ log.debug("Rescheduling [" + discoveryInfo + "]...");
+ }
+ discoveryInfo.setNextDiscovery(System.currentTimeMillis() + discoveryInfo.getInterval());
+ addToQueue(discoveryInfo);
+ if (debugEnabled) {
+ log.debug("Finished rescheduling: " + discoveryInfo);
+ }
+ } else {
+ if (debugEnabled) {
+ log.debug("Will not reschedule content discovery: " + discoveryInfo);
+ }
+ }
}
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginValidator.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginValidator.java
index deb6341..a38fb51 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginValidator.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginValidator.java
@@ -34,6 +34,7 @@ import org.apache.commons.logging.LogFactory;
import org.rhq.core.clientapi.agent.metadata.PluginMetadataManager;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.pc.PluginContainerConfiguration;
+import org.rhq.core.pluginapi.bundle.BundleFacet;
import org.rhq.core.pluginapi.configuration.ConfigurationFacet;
import org.rhq.core.pluginapi.content.ContentFacet;
import org.rhq.core.pluginapi.inventory.CreateChildResourceFacet;
@@ -126,9 +127,11 @@ public class PluginValidator {
success = success && validateResourceComponentClass(metadataManager, resourceType, pluginEnvironment);
// if the optional discovery class was specified, make sure it can be loaded by the plugin classloader
- success = success && validateResourceDiscoveryComponentClass(metadataManager, resourceType, pluginEnvironment);
+ success = success
+ && validateResourceDiscoveryComponentClass(metadataManager, resourceType, pluginEnvironment);
- success = success && validatePluginLifecycleListenerClass(metadataManager, resourceType, pluginEnvironment);
+ success = success
+ && validatePluginLifecycleListenerClass(metadataManager, resourceType, pluginEnvironment);
}
} finally {
manager.shutdown();
@@ -138,8 +141,7 @@ public class PluginValidator {
}
private static boolean validateResourceComponentClass(PluginMetadataManager metadataManager,
- ResourceType resourceType,
- PluginEnvironment pluginEnvironment) {
+ ResourceType resourceType, PluginEnvironment pluginEnvironment) {
boolean success = true;
String componentClass = metadataManager.getComponentClass(resourceType);
if (componentClass == null) {
@@ -148,41 +150,50 @@ public class PluginValidator {
+ resourceType.getPlugin() + "]");
} else {
try {
- Class componentClazz = Class.forName(componentClass, false, pluginEnvironment
- .getPluginClassLoader());
+ Class componentClazz = Class.forName(componentClass, false, pluginEnvironment.getPluginClassLoader());
if (!ResourceComponent.class.isAssignableFrom(componentClazz)) {
success = false;
- LOG.error("Component class [" + componentClass + "] for resource type ["
- + resourceType.getName() + "] from plugin [" + resourceType.getPlugin()
- + "] does not implement " + ResourceComponent.class);
+ LOG.error("Component class [" + componentClass + "] for resource type [" + resourceType.getName()
+ + "] from plugin [" + resourceType.getPlugin() + "] does not implement "
+ + ResourceComponent.class);
}
if (!resourceType.getMetricDefinitions().isEmpty()
&& !MeasurementFacet.class.isAssignableFrom(componentClazz)) {
success = false;
- LOG.error("Component class [" + componentClass + "] for resource type ["
- + resourceType.getName() + "] from plugin [" + resourceType.getPlugin()
- + "] does not support measurement collection.");
+ LOG.error("Component class [" + componentClass + "] for resource type [" + resourceType.getName()
+ + "] from plugin [" + resourceType.getPlugin()
+ + "] does not support the measurement collection facet but defines metrics.");
}
if (!resourceType.getOperationDefinitions().isEmpty()
&& !OperationFacet.class.isAssignableFrom(componentClazz)) {
success = false;
- LOG.error("Component class [" + componentClass + "] for resource type ["
- + resourceType.getName() + "] from plugin [" + resourceType.getPlugin()
- + "] does not support operations.");
+ LOG.error("Component class [" + componentClass + "] for resource type [" + resourceType.getName()
+ + "] from plugin [" + resourceType.getPlugin()
+ + "] does not support the operations facet but defines operations.");
}
- if (!resourceType.getPackageTypes().isEmpty()
- && !ContentFacet.class.isAssignableFrom(componentClazz)) {
+ if (resourceType.getBundleType() != null && !BundleFacet.class.isAssignableFrom(componentClazz)) {
success = false;
- LOG.error("Component class [" + componentClass + "] for resource type ["
- + resourceType.getName() + "] from plugin [" + resourceType.getPlugin()
- + "] does not support content management.");
+ LOG.error("Component class [" + componentClass + "] for resource type [" + resourceType.getName()
+ + "] from plugin [" + resourceType.getPlugin()
+ + "] does not support the bundle facet but defines a bundle type.");
+ }
+ if (!resourceType.getPackageTypes().isEmpty() && !ContentFacet.class.isAssignableFrom(componentClazz)) {
+ // this might be OK - there is a package type implicit if a bundle type is also defined
+ // if there is one package type, and there is a bundle type, they should have the same name
+ if (!(resourceType.getBundleType() != null && resourceType.getPackageTypes().size() == 1 && resourceType
+ .getBundleType().getName().equals(resourceType.getPackageTypes().iterator().next().getName()))) {
+ success = false;
+ LOG.error("Component class [" + componentClass + "] for resource type ["
+ + resourceType.getName() + "] from plugin [" + resourceType.getPlugin()
+ + "] does not support the content management facet but defines package types.");
+ }
}
if (resourceType.getResourceConfigurationDefinition() != null
&& !ConfigurationFacet.class.isAssignableFrom(componentClazz)) {
success = false;
- LOG.error("Component class [" + componentClass + "] for resource type ["
- + resourceType.getName() + "] from plugin [" + resourceType.getPlugin()
- + "] does not support configuration.");
+ LOG.error("Component class [" + componentClass + "] for resource type [" + resourceType.getName()
+ + "] from plugin [" + resourceType.getPlugin()
+ + "] does not support the configuration facet but defines resource configuration.");
}
boolean hasCreatableChild = false;
for (ResourceType childResourceType : resourceType.getChildResourceTypes()) {
@@ -192,14 +203,16 @@ public class PluginValidator {
}
}
if (hasCreatableChild && !CreateChildResourceFacet.class.isAssignableFrom(componentClazz)) {
- LOG.error("Component class [" + componentClass + "] for resource type ["
- + resourceType.getName() + "] from plugin [" + resourceType.getPlugin()
- + "] does not support creation of child resources.");
+ success = false;
+ LOG.error("Component class [" + componentClass + "] for resource type [" + resourceType.getName()
+ + "] from plugin [" + resourceType.getPlugin()
+ + "] does not support the child creation facet but has metadata saying it can.");
}
if (resourceType.isDeletable() && !DeleteResourceFacet.class.isAssignableFrom(componentClazz)) {
- LOG.error("Component class [" + componentClass + "] for resource type ["
- + resourceType.getName() + "] from plugin [" + resourceType.getPlugin()
- + "] does not support deletion.");
+ success = false;
+ LOG.error("Component class [" + componentClass + "] for resource type [" + resourceType.getName()
+ + "] from plugin [" + resourceType.getPlugin()
+ + "] does not support delete resource facet but has metadata saying it can delete children.");
}
} catch (Exception e) {
success = false;
@@ -211,24 +224,21 @@ public class PluginValidator {
}
private static boolean validateResourceDiscoveryComponentClass(PluginMetadataManager metadataManager,
- ResourceType resourceType,
- PluginEnvironment pluginEnvironment) {
+ ResourceType resourceType, PluginEnvironment pluginEnvironment) {
boolean success = true;
String discoveryClass = metadataManager.getDiscoveryClass(resourceType);
if (discoveryClass != null) {
try {
- Class discoveryClazz = Class.forName(discoveryClass, false, pluginEnvironment
- .getPluginClassLoader());
+ Class discoveryClazz = Class.forName(discoveryClass, false, pluginEnvironment.getPluginClassLoader());
if (!ResourceDiscoveryComponent.class.isAssignableFrom(discoveryClazz)) {
success = false;
- LOG.error("Discovery class [" + discoveryClass + "] for resource type ["
- + resourceType.getName() + "] from plugin [" + resourceType.getPlugin()
- + "] does not implement " + ResourceDiscoveryComponent.class);
+ LOG.error("Discovery class [" + discoveryClass + "] for resource type [" + resourceType.getName()
+ + "] from plugin [" + resourceType.getPlugin() + "] does not implement "
+ + ResourceDiscoveryComponent.class);
}
if (resourceType.isSupportsManualAdd() && !ManualAddFacet.class.isAssignableFrom(discoveryClazz)) {
- LOG.warn("Discovery class [" + discoveryClass + "] for resource type ["
- + resourceType.getName() + "] from plugin [" + resourceType.getPlugin()
- + "] does not implement " + ManualAddFacet.class
+ LOG.warn("Discovery class [" + discoveryClass + "] for resource type [" + resourceType.getName()
+ + "] from plugin [" + resourceType.getPlugin() + "] does not implement " + ManualAddFacet.class
+ " - implementing manual-add in discoverResources() is deprecated.");
}
} catch (Exception e) {
@@ -241,8 +251,7 @@ public class PluginValidator {
}
private static boolean validatePluginLifecycleListenerClass(PluginMetadataManager metadataManager,
- ResourceType resourceType,
- PluginEnvironment pluginEnvironment) {
+ ResourceType resourceType, PluginEnvironment pluginEnvironment) {
boolean success = true;
String overseerClass = metadataManager.getPluginLifecycleListenerClass(resourceType.getPlugin());
if (overseerClass != null) {
@@ -251,8 +260,7 @@ public class PluginValidator {
if (!PluginLifecycleListener.class.isAssignableFrom(overseerClazz)) {
success = false;
LOG.error("Plugin Lifecycle Listener class [" + overseerClass + "] for plugin ["
- + resourceType.getPlugin() + "] does not implement "
- + PluginLifecycleListener.class);
+ + resourceType.getPlugin() + "] does not implement " + PluginLifecycleListener.class);
}
} catch (Exception e) {
success = false;
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java
index c1f46fc..9e69de6 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java
@@ -54,6 +54,7 @@ import org.rhq.core.clientapi.descriptor.AgentPluginDescriptorUtil;
import org.rhq.core.clientapi.descriptor.plugin.PluginDescriptor;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.authz.Permission;
+import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.event.EventDefinition;
@@ -587,8 +588,6 @@ public class ResourceMetadataManagerBean implements ResourceMetadataManagerLocal
existingType.setSubCategory(existingSubCat);
}
- existingType.setBundleType(resourceType.getBundleType());
-
existingType = entityManager.merge(existingType);
entityManager.flush();
} catch (NoResultException nre) {
@@ -921,6 +920,21 @@ public class ResourceMetadataManagerBean implements ResourceMetadataManagerLocal
* @param existingType old resource type with existing package definitions
*/
private void updateContentDefinitions(ResourceType newType, ResourceType existingType) {
+
+ // set the bundle type if one is defined
+ BundleType newBundleType = newType.getBundleType();
+ if (newBundleType != null) {
+ BundleType existingBundleType = existingType.getBundleType();
+ newBundleType.setResourceType(existingType);
+ if (existingBundleType != null) {
+ newBundleType.setId(existingBundleType.getId());
+ newBundleType = entityManager.merge(newBundleType);
+ }
+ existingType.setBundleType(newBundleType);
+ } else {
+ existingType.setBundleType(null);
+ }
+
// Easy case: If there are no package definitions in the new type, null out any in the existing and return
if ((newType.getPackageTypes() == null) || (newType.getPackageTypes().size() == 0)) {
existingType.setPackageTypes(null);
diff --git a/modules/enterprise/server/plugins/filetemplate-bundle/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/filetemplate-bundle/src/main/resources/META-INF/rhq-serverplugin.xml
index f60c92c..7cf19a4 100644
--- a/modules/enterprise/server/plugins/filetemplate-bundle/src/main/resources/META-INF/rhq-serverplugin.xml
+++ b/modules/enterprise/server/plugins/filetemplate-bundle/src/main/resources/META-INF/rhq-serverplugin.xml
@@ -23,6 +23,6 @@
description="A property my bundle plugin needs to be properly configured" />
</serverplugin:plugin-configuration>
- <bundle type="File Template"/>
+ <bundle type="File Template Bundle"/>
</bundle-plugin>
diff --git a/modules/plugins/filetemplate-bundle/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/filetemplate-bundle/src/main/resources/META-INF/rhq-plugin.xml
index 057335d..a07d411 100644
--- a/modules/plugins/filetemplate-bundle/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/filetemplate-bundle/src/main/resources/META-INF/rhq-plugin.xml
@@ -14,7 +14,7 @@
singleton="true"
description="This plugin is used to process File Template bundles">
- <bundle type="File Template" />
+ <bundle type="File Template Bundle" />
</server>
</plugin>
diff --git a/modules/plugins/virt/src/main/java/org/rhq/plugins/virt/VirtualizationNetworkComponent.java b/modules/plugins/virt/src/main/java/org/rhq/plugins/virt/VirtualizationNetworkComponent.java
index 9517074..0a0c82c 100644
--- a/modules/plugins/virt/src/main/java/org/rhq/plugins/virt/VirtualizationNetworkComponent.java
+++ b/modules/plugins/virt/src/main/java/org/rhq/plugins/virt/VirtualizationNetworkComponent.java
@@ -33,6 +33,7 @@ import org.rhq.core.pluginapi.configuration.ConfigurationFacet;
import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport;
import org.rhq.core.pluginapi.inventory.CreateChildResourceFacet;
import org.rhq.core.pluginapi.inventory.CreateResourceReport;
+import org.rhq.core.pluginapi.inventory.DeleteResourceFacet;
import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.inventory.ResourceContext;
@@ -45,7 +46,7 @@ import org.rhq.core.pluginapi.measurement.MeasurementFacet;
* @author Greg Hinkle
*/
public class VirtualizationNetworkComponent implements ResourceComponent<VirtualizationHostComponent>,
- MeasurementFacet, ConfigurationFacet, CreateChildResourceFacet {
+ MeasurementFacet, ConfigurationFacet, CreateChildResourceFacet, DeleteResourceFacet {
private Log log = LogFactory.getLog(VirtualizationDomainComponent.class);
private String networkName;
@@ -140,6 +141,10 @@ public class VirtualizationNetworkComponent implements ResourceComponent<Virtual
return report;
}
+ public void deleteResource() throws Exception {
+ // TODO Auto-generated method stub
+ }
+
public LibVirtConnection getConnection() throws LibvirtException {
return resourceContext.getParentResourceComponent().getConnection();
}
commit 232518450b4be54cc37903152040a010adee8f88
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Thu Feb 18 17:10:22 2010 -0500
remove extra parens from delete query
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/content/InstalledPackage.java b/modules/core/domain/src/main/java/org/rhq/core/domain/content/InstalledPackage.java
index 5889e09..b7550f4 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/content/InstalledPackage.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/content/InstalledPackage.java
@@ -69,7 +69,7 @@ import org.rhq.core.domain.resource.Resource;
+ "FROM InstalledPackage ip JOIN ip.resource res LEFT JOIN ip.packageVersion pv LEFT JOIN pv.generalPackage gp LEFT JOIN gp.packageType pt "
+ "WHERE res.id = :resourceId " + " AND gp.id = :generalPackageId"),
@NamedQuery(name = InstalledPackage.QUERY_DELETE_BY_RESOURCES, query = "DELETE FROM InstalledPackage ip "
- + " WHERE ip.resource.id IN ( :resourceIds ) )") })
+ + " WHERE ip.resource.id IN ( :resourceIds )") })
@SequenceGenerator(name = "SEQ", sequenceName = "RHQ_INSTALLED_PACKAGE_ID_SEQ")
@Table(name = "RHQ_INSTALLED_PACKAGE")
public class InstalledPackage implements Serializable {
commit 309ed71d68b779d2b1ca16702f12f3e6ccbff751
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Thu Feb 18 15:59:10 2010 -0500
add new base-perspective-jar to eclipse classpath
diff --git a/.classpath b/.classpath
index 2cb7235..92929a9 100644
--- a/.classpath
+++ b/.classpath
@@ -70,6 +70,7 @@
<classpathentry kind="src" path="modules/enterprise/gui/installer-war/src/main/java"/>
<classpathentry kind="src" path="modules/enterprise/gui/webdav-war/src/main/java"/>
<classpathentry kind="src" path="modules/enterprise/gui/content_http-war/src/main/java"/>
+ <classpathentry kind="src" path="modules/enterprise/gui/base-perspective-jar/src/main/java"/>
<classpathentry kind="src" path="modules/enterprise/remoting/cli/src/main/java"/>
<classpathentry kind="src" path="modules/enterprise/remoting/cli/src/test/java"/>
<classpathentry kind="src" path="modules/enterprise/remoting/webservices/src/main/java"/>
commit e31444b7f79cf6506abf96f2b6321fc68cc83225
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Thu Feb 18 15:56:21 2010 -0500
part of BZ 560803 - use distinct in having clause to speed up query
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementBaseline.java b/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementBaseline.java
index a1b3757..9b3e9ec 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementBaseline.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementBaseline.java
@@ -140,7 +140,7 @@ public class MeasurementBaseline implements Serializable {
+ " AND ( data1h.TIME_STAMP BETWEEN ? AND ? ) " // ?2=startTime, ?3=endTime
+ " GROUP BY data1h.SCHEDULE_ID " // baselines are aggregates per schedule
// but only calculate baselines for schedules where we have data that fills (startTime, endTime)
- + " HAVING data1h.SCHEDULE_ID in ( SELECT mdata.SCHEDULE_ID "
+ + " HAVING data1h.SCHEDULE_ID in ( SELECT distinct (mdata.SCHEDULE_ID) "
+ " FROM RHQ_MEASUREMENT_DATA_NUM_1H mdata " //
+ " WHERE mdata.TIME_STAMP <= ? ) " // ?4=startTime
+ " LIMIT 100000 "; // batch at most 100K inserts at a time to shrink the xtn size
@@ -167,7 +167,7 @@ public class MeasurementBaseline implements Serializable {
+ " AND ROWNUM < 100001 " // batch at most 100K inserts at a time to shrink the xtn size
+ " GROUP BY data1h.SCHEDULE_ID " // baselines are aggregates per schedule
// but only calculate baselines for schedules where we have data that fills (startTime, endTime)
- + " HAVING data1h.SCHEDULE_ID in ( SELECT mdata.SCHEDULE_ID " //
+ + " HAVING data1h.SCHEDULE_ID in ( SELECT distinct (mdata.SCHEDULE_ID) " //
+ " FROM RHQ_MEASUREMENT_DATA_NUM_1H mdata "
+ " WHERE mdata.TIME_STAMP <= ? ) ) "; // ?4=startTime
@@ -190,7 +190,7 @@ public class MeasurementBaseline implements Serializable {
+ " AND ( data1h.TIME_STAMP BETWEEN ? AND ? ) " // ?2=startTime, ?3=endTime
+ " GROUP BY data1h.SCHEDULE_ID " // baselines are aggregates per schedule
// but only calculate baselines for schedules where we have data that fills (startTime, endTime)
- + " HAVING data1h.SCHEDULE_ID in ( SELECT mdata.SCHEDULE_ID " //
+ + " HAVING data1h.SCHEDULE_ID in ( SELECT distinct (mdata.SCHEDULE_ID) " //
+ " FROM RHQ_MEASUREMENT_DATA_NUM_1H mdata "
+ " WHERE mdata.TIME_STAMP <= ? ) "; // ?4=startTime
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java
index 37412a4..10bdbc7 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java
@@ -157,6 +157,30 @@ public class MeasurementBaselineManagerBean implements MeasurementBaselineManage
* 3) the user tended to import all new resources / platforms at the same time of day, thus bypassing
* the implicit optimization of trying to stagger the calculations by resource commit time
*
+ * 2/18/2010 NOTE: Limits weren't / aren't actually achieving the affect we want. The baseline query
+ * follows the general form of "insert into...select from <big query> having <subquery> limit X".
+ * In this case, the limit was reducing the number of rows inserted, but it was still taking the full
+ * cost of calculating everything that should have been inserted. The limit was intended as a cheap
+ * method of chunking or partitioning the work, but wasn't properly chunking the expensive
+ * part - the "big query". What we actually want to do is come of with a strategy that lessens the
+ * amount of data we need to select, thereby reducing the amount of time it takes to calculate the
+ * insertion list.
+ *
+ * One proposed strategy for this would be to chunk on the scheduleId. So if there were, say,
+ * 5M scheduleIds in the systems, we might take 500K of them at a time and then execute the
+ * baseline insertion job 10 times against a much smaller set of data each time. But the
+ * complication here is how to calculate precise groups of 500K schedules at a time, and then
+ * walk that chunked list.
+ *
+ * Another strategy would be to divy things up by resource type. Since a measurementSchedule is
+ * linked to a measurementDefinition which is linked to a resourceType, we could very easily chunk
+ * the insertion based off the schedules that belong to each resourceType. This would create
+ * one insert statement for each type of resource in system. The complication here, however,
+ * is that you may have millions of resources of one type, but hardly any resources of another.
+ * So there's still a chance that some insertions proceed slowly (in the worst case).
+ *
+ * In any event, an appropriate chunking solution needs to be found, and that partitioning strategy
+ * needs to replace the limits in the query today.
*/
int inserted = measurementBaselineManager._calculateAutoBaselinesINSERT(amountOfData);
totalInserted += inserted;
commit fd4cc59dbc5d571672121dcf8c37814fa02c8d74
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Thu Feb 18 15:55:42 2010 -0500
there is no longer etc/modules
diff --git a/.classpath b/.classpath
index e9a098f..2cb7235 100644
--- a/.classpath
+++ b/.classpath
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="modules/common/jboss-as/src/main/java"/>
- <classpathentry kind="src" path="etc/modules/base-perspective-war/src/main/java"/>
<classpathentry kind="src" path="modules/enterprise/server/plugins/jboss-software/src/test/java"/>
<classpathentry kind="src" path="modules/enterprise/server/plugins/jboss-software/src/main/java"/>
<classpathentry kind="src" path="modules/enterprise/remoting/client-api/src/main/java"/>
commit 46f559f3cb7e675b51125a50ae2c155212524b71
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Thu Feb 18 10:44:32 2010 -0500
Ensure rt log file is closed appropriately on read and truncate.
(not related to bundle work, just ended up here, sorry)
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/util/ResponseTimeLogParser.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/util/ResponseTimeLogParser.java
index 50419e3..6f825b2 100644
--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/util/ResponseTimeLogParser.java
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/util/ResponseTimeLogParser.java
@@ -1,25 +1,25 @@
- /*
- * 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, 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.
- */
+/*
+ * 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, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
package org.rhq.core.pluginapi.util;
import java.io.BufferedReader;
@@ -86,53 +86,62 @@ public class ResponseTimeLogParser {
*/
public synchronized void parseLog(CallTimeData callTimeData) throws IOException {
log.debug("Parsing response-time log file " + this.logFile + "...");
- BufferedReader in;
+ BufferedReader in = null;
+
try {
in = new BufferedReader(new FileReader(this.logFile));
- } catch (FileNotFoundException e) {
- log.warn("Response-time log file '" + this.logFile + "' does not exist.");
- return;
- }
- in.skip(this.startingOffset);
- String currentLine;
- while ((currentLine = in.readLine()) != null) {
- LogEntry logEntry;
- try {
- logEntry = parseLine(currentLine);
- } catch (Exception e) {
- log.debug("Problem parsing line [" + currentLine + "] - cause: " + e);
- continue;
- }
+ in.skip(this.startingOffset);
- String url = logEntry.getUrl();
-
- // The URL should always begin with a slash. If it doesn't, log an error and skip the entry,
- // so we don't end up with bogus data in the DB.
- if (url.charAt(0) != '/') {
- String truncatedUrl = url.substring(0, Math.min(url.length(), 120));
- if (url.length() > 120)
- truncatedUrl += "...";
- log.error("URL ('" + truncatedUrl + "') parsed from response-time log file does not begin with '/'. "
- + "Line being parsed is [" + currentLine + "].");
- continue;
- }
+ String currentLine;
+ while ((currentLine = in.readLine()) != null) {
+ LogEntry logEntry;
+ try {
+ logEntry = parseLine(currentLine);
+ } catch (Exception e) {
+ log.debug("Problem parsing line [" + currentLine + "] - cause: " + e);
+ continue;
+ }
- if (isExcluded(url)) {
- continue;
- }
+ String url = logEntry.getUrl();
+
+ // The URL should always begin with a slash. If it doesn't, log an error and skip the entry,
+ // so we don't end up with bogus data in the DB.
+ if (url.charAt(0) != '/') {
+ String truncatedUrl = url.substring(0, Math.min(url.length(), 120));
+ if (url.length() > 120)
+ truncatedUrl += "...";
+ log.error("URL ('" + truncatedUrl
+ + "') parsed from response-time log file does not begin with '/'. " + "Line being parsed is ["
+ + currentLine + "].");
+ continue;
+ }
- // Only collect stats for successful (2xx or 3xx) requests...
- if ((logEntry.getStatusCode() != null)
- && ((logEntry.getStatusCode() < 200) || (logEntry.getStatusCode() >= 400))) {
- continue;
- }
+ if (isExcluded(url)) {
+ continue;
+ }
- String transformedUrl = applyTransforms(url);
- callTimeData.addCallData(transformedUrl, new Date(logEntry.getStartTime()), logEntry.getDuration());
- }
+ // Only collect stats for successful (2xx or 3xx) requests...
+ if ((logEntry.getStatusCode() != null)
+ && ((logEntry.getStatusCode() < 200) || (logEntry.getStatusCode() >= 400))) {
+ continue;
+ }
- in.close();
+ String transformedUrl = applyTransforms(url);
+ callTimeData.addCallData(transformedUrl, new Date(logEntry.getStartTime()), logEntry.getDuration());
+ }
+ } catch (FileNotFoundException e) {
+ log.warn("Response-time log file '" + this.logFile + "' does not exist.");
+ return;
+ } finally {
+ if (null != in) {
+ try {
+ in.close();
+ } catch (Exception e) {
+ log.error("Unable to close response-time log file.", e);
+ }
+ }
+ }
/*
* After we're done parsing the file, truncate it. This is kosher, assuming we own any file being parsed by this
@@ -210,11 +219,12 @@ public class ResponseTimeLogParser {
private void truncateLog(File logFile) throws IOException {
log.debug("Truncating response-time log file '" + logFile + "'...");
+ RandomAccessFile randomAccessFile = null;
+
try {
String mode = "rws";
- RandomAccessFile randomAccessFile = new RandomAccessFile(logFile, mode);
+ randomAccessFile = new RandomAccessFile(logFile, mode);
randomAccessFile.setLength(0);
- randomAccessFile.close();
} catch (SecurityException e) {
/* User doesn't have permission to change the length, so
* ignore this exception.
@@ -225,6 +235,14 @@ public class ResponseTimeLogParser {
* Could be a permission error. Log it.
*/
log.error("Unable to truncate response-time log file.", e);
+ } finally {
+ if (null != randomAccessFile) {
+ try {
+ randomAccessFile.close();
+ } catch (Exception e) {
+ log.error("Unable to close response-time log file.", e);
+ }
+ }
}
}
@@ -257,10 +275,8 @@ public class ResponseTimeLogParser {
}
public class LogEntry {
- public LogEntry(@NotNull
- String url, long startTime, long duration, @Nullable
- Integer statusCode, @Nullable
- String ipAddress) {
+ public LogEntry(@NotNull String url, long startTime, long duration, @Nullable Integer statusCode,
+ @Nullable String ipAddress) {
this.url = url;
this.startTime = startTime;
this.duration = duration;
commit 14c69192d35461bf0a4504290e4dfb410bd35879
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Wed Feb 17 09:53:12 2010 -0500
fix incorrect artifact name for dep
diff --git a/modules/enterprise/gui/base-perspective-war/pom.xml b/modules/enterprise/gui/base-perspective-war/pom.xml
index 1078a03..798a8ca 100644
--- a/modules/enterprise/gui/base-perspective-war/pom.xml
+++ b/modules/enterprise/gui/base-perspective-war/pom.xml
@@ -24,7 +24,7 @@
<dependency>
<groupId>org.rhq</groupId>
- <artifactId>rhq-enterprise-server-base-perspective-war-deps</artifactId>
+ <artifactId>rhq-enterprise-server-base-perspective-jar</artifactId>
<version>${project.version}</version>
<type>pom</type>
</dependency>
commit 037e333f07a2714ff48e4335b0c6612476e194ec
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Tue Feb 16 18:43:44 2010 -0500
create a new base-perspective-jar module, rather than using the warpath plugin, in order to pull the base perspective classes and libs into perspective WARs which extend the base perspective WAR
diff --git a/etc/samples/perspectives/sample-perspective/app/pom.xml b/etc/samples/perspectives/sample-perspective/app/pom.xml
index 7b4c684..eb531fc 100644
--- a/etc/samples/perspectives/sample-perspective/app/pom.xml
+++ b/etc/samples/perspectives/sample-perspective/app/pom.xml
@@ -28,7 +28,7 @@
<dependency>
<groupId>org.rhq</groupId>
<artifactId>rhq-enterprise-server-base-perspective-war</artifactId>
- <version>1.0.0-SNAPSHOT</version>
+ <version>3.0.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@@ -43,22 +43,24 @@
<dependency>
<groupId>org.rhq</groupId>
<artifactId>rhq-enterprise-server-base-perspective-war</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- <type>war</type>
+ <version>3.0.0-SNAPSHOT</version>
+ <type>war</type>
</dependency>
-
- <!-- This is used to pull in the war's classes and dependencies, which are not pulled in by the above dependency
- of type war (see http://jira.codehaus.org/browse/MNG-1991). -->
+
+ <!-- This is used to pull the base war's classes and dependencies into our
+ compile classpath, since they are not pulled in by the above war dependency
+ (see http://jira.codehaus.org/browse/MNG-1991). -->
<dependency>
<groupId>org.rhq</groupId>
- <artifactId>rhq-enterprise-server-base-perspective-war</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- <type>warpath</type>
+ <artifactId>rhq-enterprise-server-base-perspective-jar</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
</dependency>
+ <!-- Deps with provided scope are not transitive, so we need to specify
+ jsf-api.jar explicitly. -->
<dependency>
<groupId>javax.faces</groupId>
- <artifactId>jsf-api</artifactId>
+ <artifactId>jsf-api</artifactId>
<scope>provided</scope>
</dependency>
@@ -85,20 +87,6 @@
</configuration>
</plugin>
- <plugin>
- <groupId>org.appfuse</groupId>
- <artifactId>maven-warpath-plugin</artifactId>
- <version>2.0.2</version>
- <extensions>true</extensions>
- <executions>
- <execution>
- <goals>
- <goal>add-classes</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
-
</plugins>
</build>
diff --git a/modules/enterprise/gui/base-perspective-jar/pom.xml b/modules/enterprise/gui/base-perspective-jar/pom.xml
new file mode 100644
index 0000000..6514b7b
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-jar/pom.xml
@@ -0,0 +1,199 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-parent</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server-base-perspective-jar</artifactId>
+ <packaging>jar</packaging>
+
+ <name>RHQ Base Perspective Jar</name>
+ <description>the base perspective classes and dependencies</description>
+
+ <scm>
+ <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/gui/bas...</connection>
+ <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/gui/bas...</developerConnection>
+ </scm>
+
+ <properties>
+ <jsf.version>1.2_14</jsf.version>
+ <facelets.version>1.1.15.B1</facelets.version>
+ <!-- NOTE: Seam 2.1.2 and 2.2.0 can't be used in webapps deployed to the RHQ Server
+ due to https://jira.jboss.org/jira/browse/JBSEAM-4029. Seam 2.2.1 can be
+ used once it's released. -->
+ <seam.version>2.1.0.SP1</seam.version>
+ <jboss-el.version>1.0_02.CR5</jboss-el.version>
+ <richfaces.version>3.3.2.SR1</richfaces.version>
+ <rhq.version>3.0.0-SNAPSHOT</rhq.version>
+ </properties>
+
+ <dependencyManagement>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-remoting-client-api</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.sun.facelets</groupId>
+ <artifactId>jsf-facelets</artifactId>
+ <version>${facelets.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>jboss-seam</artifactId>
+ <version>${seam.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.el</groupId>
+ <artifactId>el-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>xml-apis</groupId>
+ <artifactId>xml-apis</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>jboss-seam-ui</artifactId>
+ <version>${seam.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.el</groupId>
+ <artifactId>jboss-el</artifactId>
+ <version>${jboss-el.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.el</groupId>
+ <artifactId>el-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.richfaces.framework</groupId>
+ <artifactId>richfaces-api</artifactId>
+ <version>${richfaces.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.richfaces.framework</groupId>
+ <artifactId>richfaces-impl</artifactId>
+ <version>${richfaces.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.richfaces.ui</groupId>
+ <artifactId>richfaces-ui</artifactId>
+ <version>${richfaces.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ <version>${jsf.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-gui</artifactId>
+ <version>${rhq.version}</version>
+ </dependency>
+
+ </dependencies>
+
+ </dependencyManagement>
+
+ <dependencies>
+
+ <!-- This will pull in all the jars we need for making remote calls to the RHQ Server. -->
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-remoting-client-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.sun.facelets</groupId>
+ <artifactId>jsf-facelets</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>jboss-seam</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>jboss-seam-ui</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>jboss-seam-debug</artifactId>
+ <version>${seam.version}</version>
+ <!-- we should be pulling this in directly ourselves, not relying
+ jboss-seam-debug to provide it -->
+ <exclusions>
+ <exclusion>
+ <groupId>com.sun.facelets</groupId>
+ <artifactId>jsf-facelets</artifactId>
+ </exclusion>
+ </exclusions>
+ <scope>runtime</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.el</groupId>
+ <artifactId>jboss-el</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.richfaces.framework</groupId>
+ <artifactId>richfaces-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.richfaces.framework</groupId>
+ <artifactId>richfaces-impl</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.richfaces.ui</groupId>
+ <artifactId>richfaces-ui</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-gui</artifactId>
+ </dependency>
+
+ </dependencies>
+
+ <repositories>
+ <repository>
+ <id>java.net-m1-releases</id>
+ <name>Java.net Maven1 Repository - for javax.faces, javax.el, com.sun.el, and com.sun.facelets releases</name>
+ <url>http://download.java.net/maven/1/</url>
+ <layout>legacy</layout>
+ </repository>
+ </repositories>
+
+</project>
diff --git a/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java b/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java
new file mode 100644
index 0000000..27629db
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java
@@ -0,0 +1,41 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2009-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.server.perspective;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.annotations.Create;
+import org.rhq.core.gui.table.bean.AbstractPagedDataUIBean;
+
+/**
+ * A base class for Seam components that utilize the RHQ remote API to retrieve a paged data set of objects, which are
+ * typically rendered using a dataTable component.
+ *
+ * @author Ian Springer
+ */
+public abstract class AbstractPerspectivePagedDataUIBean extends AbstractPagedDataUIBean {
+ protected PerspectiveClientUIBean perspectiveClient;
+
+ @Create
+ public void init() {
+ if (this.perspectiveClient == null) {
+ this.perspectiveClient = (PerspectiveClientUIBean) Component.getInstance(PerspectiveClientUIBean.class,
+ true);
+ }
+ }
+}
diff --git a/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java b/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java
new file mode 100644
index 0000000..b6ea66c
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java
@@ -0,0 +1,49 @@
+package org.rhq.enterprise.server.perspective;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.seam.annotations.web.RequestParameter;
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.criteria.ResourceCriteria;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.enterprise.client.RemoteClient;
+import org.rhq.enterprise.server.resource.ResourceManagerRemote;
+
+/**
+ * A base class for Seam components that utilize the RHQ remote API in the context of a specific Resource.
+ */
+public class AbstractPerspectiveResourceUIBean extends AbstractPerspectiveUIBean {
+ private final Log log = LogFactory.getLog(this.getClass());
+
+ @RequestParameter
+ private Integer rhqResourceId;
+
+ private Resource resource;
+
+ public Resource getResource() throws Exception {
+ if (this.resource == null) {
+ this.resource = loadResource();
+ log.debug("Retrieved current Resource " + this.resource);
+ }
+ return this.resource;
+ }
+
+ private Resource loadResource() throws Exception {
+ if (this.rhqResourceId == null) {
+ throw new IllegalStateException("The 'rhqResourceId' HTTP request parameter is required by this page.");
+ }
+ RemoteClient remoteClient = this.perspectiveClient.getRemoteClient();
+ Subject subject = this.perspectiveClient.getSubject();
+
+ // ***NOTE***: The javassist.NotFoundException stack traces that are logged by this call can be ignored.
+ ResourceManagerRemote resourceManager = remoteClient.getResourceManagerRemote();
+ ResourceCriteria resourceCriteria = new ResourceCriteria();
+ resourceCriteria.addFilterId(this.rhqResourceId);
+ PageList<Resource> resources = resourceManager.findResourcesByCriteria(subject, resourceCriteria);
+ if (resources.isEmpty()) {
+ throw new IllegalStateException("No Resource exists with the id " + this.rhqResourceId + ".");
+ }
+ return resources.get(0);
+ }
+}
diff --git a/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java b/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java
new file mode 100644
index 0000000..56034bb
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java
@@ -0,0 +1,41 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2009-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.server.perspective;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.annotations.Create;
+import org.jboss.seam.annotations.In;
+import org.jboss.seam.faces.FacesMessages;
+
+/**
+ * A base class for Seam components that utilize the RHQ remote API.
+ *
+ * @author Ian Springer
+ */
+public abstract class AbstractPerspectiveUIBean {
+ @In
+ protected FacesMessages facesMessages;
+
+ protected PerspectiveClientUIBean perspectiveClient;
+
+ @Create
+ public void init() {
+ this.perspectiveClient = (PerspectiveClientUIBean) Component.getInstance(PerspectiveClientUIBean.class, true);
+ }
+}
\ No newline at end of file
diff --git a/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java b/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java
new file mode 100644
index 0000000..59c9c63
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java
@@ -0,0 +1,161 @@
+package org.rhq.enterprise.server.perspective;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.AutoCreate;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.web.RequestParameter;
+import org.jboss.seam.core.Conversation;
+import org.jetbrains.annotations.NotNull;
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.enterprise.client.RemoteClient;
+import org.rhq.enterprise.server.auth.SubjectManagerRemote;
+
+/**
+ * @author Ian Springer
+ */
+(a)Name(PerspectiveClientUIBean.NAME)
+(a)Scope(ScopeType.CONVERSATION)
+@AutoCreate
+public class PerspectiveClientUIBean {
+ public static final String NAME = "PerspectiveClientUIBean";
+
+ private static final String DEFAULT_SERVER_HOST = "127.0.0.1";
+ private static final int DEFAULT_SERVER_PORT = 7080;
+ private static final String DEFAULT_USERNAME = "rhqadmin";
+ private static final String DEFAULT_PASSWORD = "rhqadmin";
+
+ private final Log log = LogFactory.getLog(this.getClass());
+
+ @RequestParameter
+ private String rhqServerHost;
+ private String serverHost;
+
+ @RequestParameter
+ private Integer rhqServerPort;
+ private Integer serverPort;
+
+ @RequestParameter
+ private String rhqUsername;
+ private String username;
+
+ @RequestParameter
+ private String rhqPassword;
+ private String password;
+
+ @RequestParameter
+ private Integer rhqSessionId;
+
+ private RemoteClient remoteClient;
+ private Subject subject;
+ private String coreGuiBaseUrl;
+
+ @NotNull
+ public RemoteClient getRemoteClient() throws Exception {
+ if (this.remoteClient == null) {
+ this.remoteClient = new RemoteClient(null, getServerHost(), getServerPort());
+ }
+ if (!this.remoteClient.isConnected()) {
+ try {
+ this.remoteClient.connect();
+ } catch (Exception e) {
+ this.remoteClient = null;
+ log.info("Ending perspective client Conversation with id " + Conversation.instance().getId() + "...");
+ Conversation.instance().end();
+ throw e;
+ }
+ Conversation.instance().begin();
+ log.info("Began perspective client Conversation with id " + Conversation.instance().getId() + ".");
+ }
+ return this.remoteClient;
+ }
+
+ /**
+ * Returns the currently logged in RHQ user.
+ *
+ * @return the currently logged in RHQ user
+ *
+ * @throws Exception if we are unable to obtain the Subject - hopefully this will encourage callers to set a
+ * FacesMessage and return null to give the user a friendlier error
+ */
+ @NotNull
+ public Subject getSubject() throws Exception {
+ if (subject == null) {
+ RemoteClient remoteClient = getRemoteClient();
+ // ***NOTE***: The javassist.NotFoundException stack traces that are logged by this call can be ignored.
+ SubjectManagerRemote subjectManager = remoteClient.getSubjectManagerRemote();
+ if (this.rhqSessionId != null) {
+ log.info("Retrieving subject for user [" + getUsername() + "] and sessionId [" + this.rhqSessionId + "]...");
+ this.subject = subjectManager.getSubjectByNameAndSessionId(getUsername(), this.rhqSessionId);
+ } else {
+ log.info("Logging in as user [" + getUsername() + "] with password [" + getPassword() + "]...");
+ this.subject = subjectManager.login(getUsername(), getPassword());
+ }
+ }
+ return this.subject;
+ }
+
+ @NotNull
+ public String getCoreGuiBaseUrl() throws Exception {
+ if (this.coreGuiBaseUrl == null) {
+ RemoteClient remoteClient = getRemoteClient();
+ Subject subject = getSubject();
+ PerspectiveManagerRemote perspectiveManager = remoteClient.getPerspectiveManagerRemote();
+ this.coreGuiBaseUrl = perspectiveManager.getRootUrl(subject, true, false);
+ }
+ return this.coreGuiBaseUrl;
+ }
+
+ @NotNull
+ private String getServerHost() {
+ if (this.serverHost == null) {
+ if (this.rhqServerHost != null) {
+ this.serverHost = this.rhqServerHost;
+ } else {
+ return DEFAULT_SERVER_HOST;
+ }
+ } else {
+ if (this.rhqServerHost != null && this.serverHost.equals(this.rhqServerHost)) {
+
+ }
+ }
+ return this.serverHost;
+ }
+
+ private int getServerPort() {
+ if (this.serverPort == null) {
+ if (this.rhqServerPort != null) {
+ this.serverPort = this.rhqServerPort;
+ } else {
+ return DEFAULT_SERVER_PORT;
+ }
+ }
+ return this.serverPort;
+ }
+
+ @NotNull
+ private String getUsername() {
+ if (this.username == null) {
+ if (this.rhqUsername != null) {
+ this.username = this.rhqUsername;
+ } else {
+ return DEFAULT_USERNAME;
+ }
+ }
+ return this.username;
+ }
+
+ @NotNull
+ private String getPassword() {
+ if (this.password == null) {
+ if (this.rhqPassword != null) {
+ this.password = this.rhqPassword;
+ } else {
+ return DEFAULT_PASSWORD;
+ }
+ }
+ return this.password;
+ }
+}
diff --git a/modules/enterprise/gui/base-perspective-jar/src/main/resources/seam.properties b/modules/enterprise/gui/base-perspective-jar/src/main/resources/seam.properties
new file mode 100644
index 0000000..b97c770
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-jar/src/main/resources/seam.properties
@@ -0,0 +1,3 @@
+# NOTE: The presence of this file tells Seam to scan this WAR for Seam
+# components (i.e. classes with Name annotations) and to deploy
+# any that it finds.
diff --git a/modules/enterprise/gui/base-perspective-war/pom.xml b/modules/enterprise/gui/base-perspective-war/pom.xml
index 1f2ed83..1078a03 100644
--- a/modules/enterprise/gui/base-perspective-war/pom.xml
+++ b/modules/enterprise/gui/base-perspective-war/pom.xml
@@ -20,169 +20,13 @@
<developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/gui/bas...</developerConnection>
</scm>
- <properties>
- <jsf.version>1.2_14</jsf.version>
- <facelets.version>1.1.15.B1</facelets.version>
- <!-- NOTE: Seam 2.1.2 and 2.2.0 can't be used in webapps deployed to the RHQ Server
- due to https://jira.jboss.org/jira/browse/JBSEAM-4029. Seam 2.2.1 can be
- used once it's released. -->
- <seam.version>2.1.0.SP1</seam.version>
- <jboss-el.version>1.0_02.CR5</jboss-el.version>
- <richfaces.version>3.3.2.SR1</richfaces.version>
- <rhq.version>3.0.0-SNAPSHOT</rhq.version>
- </properties>
-
- <dependencyManagement>
-
- <dependencies>
-
- <dependency>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-remoting-client-api</artifactId>
- <version>${project.parent.version}</version>
- </dependency>
-
- <dependency>
- <groupId>com.sun.facelets</groupId>
- <artifactId>jsf-facelets</artifactId>
- <version>${facelets.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.seam</groupId>
- <artifactId>jboss-seam</artifactId>
- <version>${seam.version}</version>
- <exclusions>
- <exclusion>
- <groupId>javax.el</groupId>
- <artifactId>el-api</artifactId>
- </exclusion>
- <exclusion>
- <groupId>xml-apis</groupId>
- <artifactId>xml-apis</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.seam</groupId>
- <artifactId>jboss-seam-ui</artifactId>
- <version>${seam.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.el</groupId>
- <artifactId>jboss-el</artifactId>
- <version>${jboss-el.version}</version>
- <exclusions>
- <exclusion>
- <groupId>javax.el</groupId>
- <artifactId>el-api</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.richfaces.framework</groupId>
- <artifactId>richfaces-api</artifactId>
- <version>${richfaces.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.richfaces.framework</groupId>
- <artifactId>richfaces-impl</artifactId>
- <version>${richfaces.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.richfaces.ui</groupId>
- <artifactId>richfaces-ui</artifactId>
- <version>${richfaces.version}</version>
- </dependency>
-
- <dependency>
- <groupId>javax.faces</groupId>
- <artifactId>jsf-api</artifactId>
- <version>${jsf.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-core-gui</artifactId>
- <version>${rhq.version}</version>
- </dependency>
-
- </dependencies>
-
- </dependencyManagement>
-
<dependencies>
- <!-- This will pull in all the jars we need for making remote calls to the RHQ Server. -->
- <dependency>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-remoting-client-api</artifactId>
- </dependency>
-
- <dependency>
- <groupId>com.sun.facelets</groupId>
- <artifactId>jsf-facelets</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.seam</groupId>
- <artifactId>jboss-seam</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.seam</groupId>
- <artifactId>jboss-seam-ui</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.seam</groupId>
- <artifactId>jboss-seam-debug</artifactId>
- <version>${seam.version}</version>
- <!-- we should be pulling this in directly ourselves, not relying
- jboss-seam-debug to provide it -->
- <exclusions>
- <exclusion>
- <groupId>com.sun.facelets</groupId>
- <artifactId>jsf-facelets</artifactId>
- </exclusion>
- </exclusions>
- <scope>runtime</scope>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.el</groupId>
- <artifactId>jboss-el</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.richfaces.framework</groupId>
- <artifactId>richfaces-api</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.richfaces.framework</groupId>
- <artifactId>richfaces-impl</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.richfaces.ui</groupId>
- <artifactId>richfaces-ui</artifactId>
- </dependency>
-
- <dependency>
- <groupId>javax.faces</groupId>
- <artifactId>jsf-api</artifactId>
- <scope>provided</scope>
- </dependency>
-
<dependency>
<groupId>org.rhq</groupId>
- <artifactId>rhq-core-gui</artifactId>
+ <artifactId>rhq-enterprise-server-base-perspective-war-deps</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
</dependency>
</dependencies>
@@ -219,14 +63,5 @@
</plugins>
</build>
-
- <repositories>
- <repository>
- <id>java.net-m1-releases</id>
- <name>Java.net Maven1 Repository - for javax.faces, javax.el, com.sun.el, and com.sun.facelets releases</name>
- <url>http://download.java.net/maven/1/</url>
- <layout>legacy</layout>
- </repository>
- </repositories>
</project>
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java b/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java
deleted file mode 100644
index 27629db..0000000
--- a/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2009-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.server.perspective;
-
-import org.jboss.seam.Component;
-import org.jboss.seam.annotations.Create;
-import org.rhq.core.gui.table.bean.AbstractPagedDataUIBean;
-
-/**
- * A base class for Seam components that utilize the RHQ remote API to retrieve a paged data set of objects, which are
- * typically rendered using a dataTable component.
- *
- * @author Ian Springer
- */
-public abstract class AbstractPerspectivePagedDataUIBean extends AbstractPagedDataUIBean {
- protected PerspectiveClientUIBean perspectiveClient;
-
- @Create
- public void init() {
- if (this.perspectiveClient == null) {
- this.perspectiveClient = (PerspectiveClientUIBean) Component.getInstance(PerspectiveClientUIBean.class,
- true);
- }
- }
-}
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java b/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java
deleted file mode 100644
index b6ea66c..0000000
--- a/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package org.rhq.enterprise.server.perspective;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jboss.seam.annotations.web.RequestParameter;
-import org.rhq.core.domain.auth.Subject;
-import org.rhq.core.domain.criteria.ResourceCriteria;
-import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.util.PageList;
-import org.rhq.enterprise.client.RemoteClient;
-import org.rhq.enterprise.server.resource.ResourceManagerRemote;
-
-/**
- * A base class for Seam components that utilize the RHQ remote API in the context of a specific Resource.
- */
-public class AbstractPerspectiveResourceUIBean extends AbstractPerspectiveUIBean {
- private final Log log = LogFactory.getLog(this.getClass());
-
- @RequestParameter
- private Integer rhqResourceId;
-
- private Resource resource;
-
- public Resource getResource() throws Exception {
- if (this.resource == null) {
- this.resource = loadResource();
- log.debug("Retrieved current Resource " + this.resource);
- }
- return this.resource;
- }
-
- private Resource loadResource() throws Exception {
- if (this.rhqResourceId == null) {
- throw new IllegalStateException("The 'rhqResourceId' HTTP request parameter is required by this page.");
- }
- RemoteClient remoteClient = this.perspectiveClient.getRemoteClient();
- Subject subject = this.perspectiveClient.getSubject();
-
- // ***NOTE***: The javassist.NotFoundException stack traces that are logged by this call can be ignored.
- ResourceManagerRemote resourceManager = remoteClient.getResourceManagerRemote();
- ResourceCriteria resourceCriteria = new ResourceCriteria();
- resourceCriteria.addFilterId(this.rhqResourceId);
- PageList<Resource> resources = resourceManager.findResourcesByCriteria(subject, resourceCriteria);
- if (resources.isEmpty()) {
- throw new IllegalStateException("No Resource exists with the id " + this.rhqResourceId + ".");
- }
- return resources.get(0);
- }
-}
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java b/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java
deleted file mode 100644
index 56034bb..0000000
--- a/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2009-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.server.perspective;
-
-import org.jboss.seam.Component;
-import org.jboss.seam.annotations.Create;
-import org.jboss.seam.annotations.In;
-import org.jboss.seam.faces.FacesMessages;
-
-/**
- * A base class for Seam components that utilize the RHQ remote API.
- *
- * @author Ian Springer
- */
-public abstract class AbstractPerspectiveUIBean {
- @In
- protected FacesMessages facesMessages;
-
- protected PerspectiveClientUIBean perspectiveClient;
-
- @Create
- public void init() {
- this.perspectiveClient = (PerspectiveClientUIBean) Component.getInstance(PerspectiveClientUIBean.class, true);
- }
-}
\ No newline at end of file
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java b/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java
deleted file mode 100644
index 59c9c63..0000000
--- a/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java
+++ /dev/null
@@ -1,161 +0,0 @@
-package org.rhq.enterprise.server.perspective;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jboss.seam.ScopeType;
-import org.jboss.seam.annotations.AutoCreate;
-import org.jboss.seam.annotations.Name;
-import org.jboss.seam.annotations.Scope;
-import org.jboss.seam.annotations.web.RequestParameter;
-import org.jboss.seam.core.Conversation;
-import org.jetbrains.annotations.NotNull;
-import org.rhq.core.domain.auth.Subject;
-import org.rhq.enterprise.client.RemoteClient;
-import org.rhq.enterprise.server.auth.SubjectManagerRemote;
-
-/**
- * @author Ian Springer
- */
-(a)Name(PerspectiveClientUIBean.NAME)
-(a)Scope(ScopeType.CONVERSATION)
-@AutoCreate
-public class PerspectiveClientUIBean {
- public static final String NAME = "PerspectiveClientUIBean";
-
- private static final String DEFAULT_SERVER_HOST = "127.0.0.1";
- private static final int DEFAULT_SERVER_PORT = 7080;
- private static final String DEFAULT_USERNAME = "rhqadmin";
- private static final String DEFAULT_PASSWORD = "rhqadmin";
-
- private final Log log = LogFactory.getLog(this.getClass());
-
- @RequestParameter
- private String rhqServerHost;
- private String serverHost;
-
- @RequestParameter
- private Integer rhqServerPort;
- private Integer serverPort;
-
- @RequestParameter
- private String rhqUsername;
- private String username;
-
- @RequestParameter
- private String rhqPassword;
- private String password;
-
- @RequestParameter
- private Integer rhqSessionId;
-
- private RemoteClient remoteClient;
- private Subject subject;
- private String coreGuiBaseUrl;
-
- @NotNull
- public RemoteClient getRemoteClient() throws Exception {
- if (this.remoteClient == null) {
- this.remoteClient = new RemoteClient(null, getServerHost(), getServerPort());
- }
- if (!this.remoteClient.isConnected()) {
- try {
- this.remoteClient.connect();
- } catch (Exception e) {
- this.remoteClient = null;
- log.info("Ending perspective client Conversation with id " + Conversation.instance().getId() + "...");
- Conversation.instance().end();
- throw e;
- }
- Conversation.instance().begin();
- log.info("Began perspective client Conversation with id " + Conversation.instance().getId() + ".");
- }
- return this.remoteClient;
- }
-
- /**
- * Returns the currently logged in RHQ user.
- *
- * @return the currently logged in RHQ user
- *
- * @throws Exception if we are unable to obtain the Subject - hopefully this will encourage callers to set a
- * FacesMessage and return null to give the user a friendlier error
- */
- @NotNull
- public Subject getSubject() throws Exception {
- if (subject == null) {
- RemoteClient remoteClient = getRemoteClient();
- // ***NOTE***: The javassist.NotFoundException stack traces that are logged by this call can be ignored.
- SubjectManagerRemote subjectManager = remoteClient.getSubjectManagerRemote();
- if (this.rhqSessionId != null) {
- log.info("Retrieving subject for user [" + getUsername() + "] and sessionId [" + this.rhqSessionId + "]...");
- this.subject = subjectManager.getSubjectByNameAndSessionId(getUsername(), this.rhqSessionId);
- } else {
- log.info("Logging in as user [" + getUsername() + "] with password [" + getPassword() + "]...");
- this.subject = subjectManager.login(getUsername(), getPassword());
- }
- }
- return this.subject;
- }
-
- @NotNull
- public String getCoreGuiBaseUrl() throws Exception {
- if (this.coreGuiBaseUrl == null) {
- RemoteClient remoteClient = getRemoteClient();
- Subject subject = getSubject();
- PerspectiveManagerRemote perspectiveManager = remoteClient.getPerspectiveManagerRemote();
- this.coreGuiBaseUrl = perspectiveManager.getRootUrl(subject, true, false);
- }
- return this.coreGuiBaseUrl;
- }
-
- @NotNull
- private String getServerHost() {
- if (this.serverHost == null) {
- if (this.rhqServerHost != null) {
- this.serverHost = this.rhqServerHost;
- } else {
- return DEFAULT_SERVER_HOST;
- }
- } else {
- if (this.rhqServerHost != null && this.serverHost.equals(this.rhqServerHost)) {
-
- }
- }
- return this.serverHost;
- }
-
- private int getServerPort() {
- if (this.serverPort == null) {
- if (this.rhqServerPort != null) {
- this.serverPort = this.rhqServerPort;
- } else {
- return DEFAULT_SERVER_PORT;
- }
- }
- return this.serverPort;
- }
-
- @NotNull
- private String getUsername() {
- if (this.username == null) {
- if (this.rhqUsername != null) {
- this.username = this.rhqUsername;
- } else {
- return DEFAULT_USERNAME;
- }
- }
- return this.username;
- }
-
- @NotNull
- private String getPassword() {
- if (this.password == null) {
- if (this.rhqPassword != null) {
- this.password = this.rhqPassword;
- } else {
- return DEFAULT_PASSWORD;
- }
- }
- return this.password;
- }
-}
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/resources/seam.properties b/modules/enterprise/gui/base-perspective-war/src/main/resources/seam.properties
deleted file mode 100644
index b97c770..0000000
--- a/modules/enterprise/gui/base-perspective-war/src/main/resources/seam.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-# NOTE: The presence of this file tells Seam to scan this WAR for Seam
-# components (i.e. classes with Name annotations) and to deploy
-# any that it finds.
diff --git a/modules/enterprise/gui/pom.xml b/modules/enterprise/gui/pom.xml
index 1e39958..223b230 100644
--- a/modules/enterprise/gui/pom.xml
+++ b/modules/enterprise/gui/pom.xml
@@ -34,6 +34,7 @@
<modules>
<module>portal-war</module>
<module>installer-war</module>
+ <module>base-perspective-jar</module>
<module>base-perspective-war</module>
<module>webdav-war</module>
<module>content_http-war</module>
@@ -44,3 +45,4 @@
</profiles>
</project>
+
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/pom.xml b/modules/enterprise/server/plugins/perspectives/policy/app/pom.xml
index 27aa634..19af416 100644
--- a/modules/enterprise/server/plugins/perspectives/policy/app/pom.xml
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/pom.xml
@@ -45,16 +45,18 @@
<version>${project.version}</version>
<type>war</type>
</dependency>
-
- <!-- This is used to pull in the war's classes and dependencies, which are not pulled in by the above dependency
- of type war (see http://jira.codehaus.org/browse/MNG-1991). -->
+
+ <!-- This is used to pull the base war's classes and dependencies into our
+ compile classpath, since they are not pulled in by the above war dependency
+ (see http://jira.codehaus.org/browse/MNG-1991). -->
<dependency>
<groupId>org.rhq</groupId>
- <artifactId>rhq-enterprise-server-base-perspective-war</artifactId>
- <version>${project.version}</version>
- <type>warpath</type>
+ <artifactId>rhq-enterprise-server-base-perspective-jar</artifactId>
+ <version>${project.version}</version>
</dependency>
-
+
+ <!-- Deps with provided scope are not transitive, so we need to specify
+ jsf-api.jar explicitly. -->
<dependency>
<groupId>javax.faces</groupId>
<artifactId>jsf-api</artifactId>
@@ -84,20 +86,6 @@
</configuration>
</plugin>
- <plugin>
- <groupId>org.appfuse</groupId>
- <artifactId>maven-warpath-plugin</artifactId>
- <version>2.0.2</version>
- <extensions>true</extensions>
- <executions>
- <execution>
- <goals>
- <goal>add-classes</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
-
</plugins>
</build>
commit 3a8393f5940b3702d1d48679a565e08bc7e7275d
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Tue Feb 16 17:04:46 2010 -0500
move base-perspective-war module from etc/modules/ to modules/enterprise/gui/; deploy policy perspective by default
diff --git a/modules/enterprise/gui/base-perspective-war/pom.xml b/modules/enterprise/gui/base-perspective-war/pom.xml
new file mode 100644
index 0000000..1f2ed83
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-war/pom.xml
@@ -0,0 +1,232 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-parent</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server-base-perspective-war</artifactId>
+ <packaging>war</packaging>
+
+ <name>RHQ Base Perspective War</name>
+ <description>an abstract WAR that can be used by the maven war plugin as an overlay (i.e. base) for a perspective WAR</description>
+
+ <scm>
+ <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/gui/bas...</connection>
+ <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/gui/bas...</developerConnection>
+ </scm>
+
+ <properties>
+ <jsf.version>1.2_14</jsf.version>
+ <facelets.version>1.1.15.B1</facelets.version>
+ <!-- NOTE: Seam 2.1.2 and 2.2.0 can't be used in webapps deployed to the RHQ Server
+ due to https://jira.jboss.org/jira/browse/JBSEAM-4029. Seam 2.2.1 can be
+ used once it's released. -->
+ <seam.version>2.1.0.SP1</seam.version>
+ <jboss-el.version>1.0_02.CR5</jboss-el.version>
+ <richfaces.version>3.3.2.SR1</richfaces.version>
+ <rhq.version>3.0.0-SNAPSHOT</rhq.version>
+ </properties>
+
+ <dependencyManagement>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-remoting-client-api</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.sun.facelets</groupId>
+ <artifactId>jsf-facelets</artifactId>
+ <version>${facelets.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>jboss-seam</artifactId>
+ <version>${seam.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.el</groupId>
+ <artifactId>el-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>xml-apis</groupId>
+ <artifactId>xml-apis</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>jboss-seam-ui</artifactId>
+ <version>${seam.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.el</groupId>
+ <artifactId>jboss-el</artifactId>
+ <version>${jboss-el.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.el</groupId>
+ <artifactId>el-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.richfaces.framework</groupId>
+ <artifactId>richfaces-api</artifactId>
+ <version>${richfaces.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.richfaces.framework</groupId>
+ <artifactId>richfaces-impl</artifactId>
+ <version>${richfaces.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.richfaces.ui</groupId>
+ <artifactId>richfaces-ui</artifactId>
+ <version>${richfaces.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ <version>${jsf.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-gui</artifactId>
+ <version>${rhq.version}</version>
+ </dependency>
+
+ </dependencies>
+
+ </dependencyManagement>
+
+ <dependencies>
+
+ <!-- This will pull in all the jars we need for making remote calls to the RHQ Server. -->
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-remoting-client-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.sun.facelets</groupId>
+ <artifactId>jsf-facelets</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>jboss-seam</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>jboss-seam-ui</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>jboss-seam-debug</artifactId>
+ <version>${seam.version}</version>
+ <!-- we should be pulling this in directly ourselves, not relying
+ jboss-seam-debug to provide it -->
+ <exclusions>
+ <exclusion>
+ <groupId>com.sun.facelets</groupId>
+ <artifactId>jsf-facelets</artifactId>
+ </exclusion>
+ </exclusions>
+ <scope>runtime</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.el</groupId>
+ <artifactId>jboss-el</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.richfaces.framework</groupId>
+ <artifactId>richfaces-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.richfaces.framework</groupId>
+ <artifactId>richfaces-impl</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.richfaces.ui</groupId>
+ <artifactId>richfaces-ui</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-gui</artifactId>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <finalName>rhq-base-perspective</finalName>
+
+ <plugins>
+
+ <plugin>
+ <artifactId>maven-war-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifest>
+ <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+ <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+ </manifest>
+ <manifestEntries>
+ <Build-Number>${buildNumber}</Build-Number>
+ </manifestEntries>
+ </archive>
+ <webResources>
+ <resource>
+ <filtering>true</filtering>
+ <directory>${basedir}/src/main/webapp</directory>
+ <includes>
+ <include>**/*.properties</include>
+ </includes>
+ </resource>
+ </webResources>
+ </configuration>
+ </plugin>
+
+ </plugins>
+
+ </build>
+
+ <repositories>
+ <repository>
+ <id>java.net-m1-releases</id>
+ <name>Java.net Maven1 Repository - for javax.faces, javax.el, com.sun.el, and com.sun.facelets releases</name>
+ <url>http://download.java.net/maven/1/</url>
+ <layout>legacy</layout>
+ </repository>
+ </repositories>
+
+</project>
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java b/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java
new file mode 100644
index 0000000..27629db
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java
@@ -0,0 +1,41 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2009-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.server.perspective;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.annotations.Create;
+import org.rhq.core.gui.table.bean.AbstractPagedDataUIBean;
+
+/**
+ * A base class for Seam components that utilize the RHQ remote API to retrieve a paged data set of objects, which are
+ * typically rendered using a dataTable component.
+ *
+ * @author Ian Springer
+ */
+public abstract class AbstractPerspectivePagedDataUIBean extends AbstractPagedDataUIBean {
+ protected PerspectiveClientUIBean perspectiveClient;
+
+ @Create
+ public void init() {
+ if (this.perspectiveClient == null) {
+ this.perspectiveClient = (PerspectiveClientUIBean) Component.getInstance(PerspectiveClientUIBean.class,
+ true);
+ }
+ }
+}
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java b/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java
new file mode 100644
index 0000000..b6ea66c
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java
@@ -0,0 +1,49 @@
+package org.rhq.enterprise.server.perspective;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.seam.annotations.web.RequestParameter;
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.criteria.ResourceCriteria;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.enterprise.client.RemoteClient;
+import org.rhq.enterprise.server.resource.ResourceManagerRemote;
+
+/**
+ * A base class for Seam components that utilize the RHQ remote API in the context of a specific Resource.
+ */
+public class AbstractPerspectiveResourceUIBean extends AbstractPerspectiveUIBean {
+ private final Log log = LogFactory.getLog(this.getClass());
+
+ @RequestParameter
+ private Integer rhqResourceId;
+
+ private Resource resource;
+
+ public Resource getResource() throws Exception {
+ if (this.resource == null) {
+ this.resource = loadResource();
+ log.debug("Retrieved current Resource " + this.resource);
+ }
+ return this.resource;
+ }
+
+ private Resource loadResource() throws Exception {
+ if (this.rhqResourceId == null) {
+ throw new IllegalStateException("The 'rhqResourceId' HTTP request parameter is required by this page.");
+ }
+ RemoteClient remoteClient = this.perspectiveClient.getRemoteClient();
+ Subject subject = this.perspectiveClient.getSubject();
+
+ // ***NOTE***: The javassist.NotFoundException stack traces that are logged by this call can be ignored.
+ ResourceManagerRemote resourceManager = remoteClient.getResourceManagerRemote();
+ ResourceCriteria resourceCriteria = new ResourceCriteria();
+ resourceCriteria.addFilterId(this.rhqResourceId);
+ PageList<Resource> resources = resourceManager.findResourcesByCriteria(subject, resourceCriteria);
+ if (resources.isEmpty()) {
+ throw new IllegalStateException("No Resource exists with the id " + this.rhqResourceId + ".");
+ }
+ return resources.get(0);
+ }
+}
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java b/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java
new file mode 100644
index 0000000..56034bb
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java
@@ -0,0 +1,41 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2009-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.server.perspective;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.annotations.Create;
+import org.jboss.seam.annotations.In;
+import org.jboss.seam.faces.FacesMessages;
+
+/**
+ * A base class for Seam components that utilize the RHQ remote API.
+ *
+ * @author Ian Springer
+ */
+public abstract class AbstractPerspectiveUIBean {
+ @In
+ protected FacesMessages facesMessages;
+
+ protected PerspectiveClientUIBean perspectiveClient;
+
+ @Create
+ public void init() {
+ this.perspectiveClient = (PerspectiveClientUIBean) Component.getInstance(PerspectiveClientUIBean.class, true);
+ }
+}
\ No newline at end of file
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java b/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java
new file mode 100644
index 0000000..59c9c63
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java
@@ -0,0 +1,161 @@
+package org.rhq.enterprise.server.perspective;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.AutoCreate;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.web.RequestParameter;
+import org.jboss.seam.core.Conversation;
+import org.jetbrains.annotations.NotNull;
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.enterprise.client.RemoteClient;
+import org.rhq.enterprise.server.auth.SubjectManagerRemote;
+
+/**
+ * @author Ian Springer
+ */
+(a)Name(PerspectiveClientUIBean.NAME)
+(a)Scope(ScopeType.CONVERSATION)
+@AutoCreate
+public class PerspectiveClientUIBean {
+ public static final String NAME = "PerspectiveClientUIBean";
+
+ private static final String DEFAULT_SERVER_HOST = "127.0.0.1";
+ private static final int DEFAULT_SERVER_PORT = 7080;
+ private static final String DEFAULT_USERNAME = "rhqadmin";
+ private static final String DEFAULT_PASSWORD = "rhqadmin";
+
+ private final Log log = LogFactory.getLog(this.getClass());
+
+ @RequestParameter
+ private String rhqServerHost;
+ private String serverHost;
+
+ @RequestParameter
+ private Integer rhqServerPort;
+ private Integer serverPort;
+
+ @RequestParameter
+ private String rhqUsername;
+ private String username;
+
+ @RequestParameter
+ private String rhqPassword;
+ private String password;
+
+ @RequestParameter
+ private Integer rhqSessionId;
+
+ private RemoteClient remoteClient;
+ private Subject subject;
+ private String coreGuiBaseUrl;
+
+ @NotNull
+ public RemoteClient getRemoteClient() throws Exception {
+ if (this.remoteClient == null) {
+ this.remoteClient = new RemoteClient(null, getServerHost(), getServerPort());
+ }
+ if (!this.remoteClient.isConnected()) {
+ try {
+ this.remoteClient.connect();
+ } catch (Exception e) {
+ this.remoteClient = null;
+ log.info("Ending perspective client Conversation with id " + Conversation.instance().getId() + "...");
+ Conversation.instance().end();
+ throw e;
+ }
+ Conversation.instance().begin();
+ log.info("Began perspective client Conversation with id " + Conversation.instance().getId() + ".");
+ }
+ return this.remoteClient;
+ }
+
+ /**
+ * Returns the currently logged in RHQ user.
+ *
+ * @return the currently logged in RHQ user
+ *
+ * @throws Exception if we are unable to obtain the Subject - hopefully this will encourage callers to set a
+ * FacesMessage and return null to give the user a friendlier error
+ */
+ @NotNull
+ public Subject getSubject() throws Exception {
+ if (subject == null) {
+ RemoteClient remoteClient = getRemoteClient();
+ // ***NOTE***: The javassist.NotFoundException stack traces that are logged by this call can be ignored.
+ SubjectManagerRemote subjectManager = remoteClient.getSubjectManagerRemote();
+ if (this.rhqSessionId != null) {
+ log.info("Retrieving subject for user [" + getUsername() + "] and sessionId [" + this.rhqSessionId + "]...");
+ this.subject = subjectManager.getSubjectByNameAndSessionId(getUsername(), this.rhqSessionId);
+ } else {
+ log.info("Logging in as user [" + getUsername() + "] with password [" + getPassword() + "]...");
+ this.subject = subjectManager.login(getUsername(), getPassword());
+ }
+ }
+ return this.subject;
+ }
+
+ @NotNull
+ public String getCoreGuiBaseUrl() throws Exception {
+ if (this.coreGuiBaseUrl == null) {
+ RemoteClient remoteClient = getRemoteClient();
+ Subject subject = getSubject();
+ PerspectiveManagerRemote perspectiveManager = remoteClient.getPerspectiveManagerRemote();
+ this.coreGuiBaseUrl = perspectiveManager.getRootUrl(subject, true, false);
+ }
+ return this.coreGuiBaseUrl;
+ }
+
+ @NotNull
+ private String getServerHost() {
+ if (this.serverHost == null) {
+ if (this.rhqServerHost != null) {
+ this.serverHost = this.rhqServerHost;
+ } else {
+ return DEFAULT_SERVER_HOST;
+ }
+ } else {
+ if (this.rhqServerHost != null && this.serverHost.equals(this.rhqServerHost)) {
+
+ }
+ }
+ return this.serverHost;
+ }
+
+ private int getServerPort() {
+ if (this.serverPort == null) {
+ if (this.rhqServerPort != null) {
+ this.serverPort = this.rhqServerPort;
+ } else {
+ return DEFAULT_SERVER_PORT;
+ }
+ }
+ return this.serverPort;
+ }
+
+ @NotNull
+ private String getUsername() {
+ if (this.username == null) {
+ if (this.rhqUsername != null) {
+ this.username = this.rhqUsername;
+ } else {
+ return DEFAULT_USERNAME;
+ }
+ }
+ return this.username;
+ }
+
+ @NotNull
+ private String getPassword() {
+ if (this.password == null) {
+ if (this.rhqPassword != null) {
+ this.password = this.rhqPassword;
+ } else {
+ return DEFAULT_PASSWORD;
+ }
+ }
+ return this.password;
+ }
+}
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/resources/seam.properties b/modules/enterprise/gui/base-perspective-war/src/main/resources/seam.properties
new file mode 100644
index 0000000..b97c770
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-war/src/main/resources/seam.properties
@@ -0,0 +1,3 @@
+# NOTE: The presence of this file tells Seam to scan this WAR for Seam
+# components (i.e. classes with Name annotations) and to deploy
+# any that it finds.
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/components.xml b/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/components.xml
new file mode 100644
index 0000000..4631d2e
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/components.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<components xmlns="http://jboss.com/products/seam/components"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:security="http://jboss.com/products/seam/security"
+ xsi:schemaLocation=
+ "http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.0.xsd
+ http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.0.xsd">
+
+ <component name="org.jboss.seam.core.init">
+ <property name="debug">false</property>
+ <!-- enable only when needed -->
+ <property name="transactionManagementEnabled">false</property>
+ </component>
+
+</components>
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/faces-config.xml b/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/faces-config.xml
new file mode 100644
index 0000000..f584c01
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/faces-config.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+
+<faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
+
+ <!-- If your perspective application utilizes JSF managed beans then copy
+ this file to your application and add declarations as needed.
+
+ <managed-bean>
+ <managed-bean-name>MyBeanName</managed-bean-name>
+ <managed-bean-class>my.package.MyBeanName</managed-bean-class>
+ <managed-bean-scope>session</managed-bean-scope>
+ </managed-bean>
+
+ -->
+
+ <!-- If youe perspective application utilizes JSF navigation rules then copy
+ this file to your application and add rules as needed.
+
+ <navigation-rule>
+ <from-tree-id></from-tree-id>
+ <navigation-case></navigation-case>
+ </navigation-rule>
+
+ -->
+
+</faces-config>
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/includes/pageControls.xhtml b/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/includes/pageControls.xhtml
new file mode 100644
index 0000000..2faad02
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/includes/pageControls.xhtml
@@ -0,0 +1,103 @@
+<?xml version="1.0"?>
+
+<ui:composition
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:fn="http://java.sun.com/jsp/jstl/functions"
+ xmlns:a4j="http://richfaces.org/a4j"
+ xmlns:rich="http://richfaces.org/rich"
+ xmlns:rhq="http://rhq-project.org/rhq"
+ xmlns:onc="http://jboss.org/on/component">
+
+ <ui:remove>
+ Usage: The following parameters must be set in the calling page:
+
+ pagedDataUIBean - an instance of AbstractPagedDataUIBean, which provides access to a data model, a page
+ control, and page control settings (valid page sizes, etc.)
+ dataTableName - name of the data table to be controlled
+ </ui:remove>
+
+ <h:panelGroup layout="block" style="float: right; margin-right: 30px">
+ <ui:param name="dataScrollerName" value="#{dataTableName}Scroller"/>
+ <ui:param name="dataModel" value="#{pagedDataUIBean.dataModel}"/>
+ <ui:param name="pageControl" value="#{pagedDataUIBean.pageControl}"/>
+
+ <table>
+ <tr>
+ <td nowrap="nowrap">
+
+ <h:outputText value="Total: #{dataModel.rowCount}"
+ style="margin-right: 2em; font-weight: bold; "/>
+
+ <h:panelGroup layout="block" rendered="#{dataModel.rowCount gt pagedDataUIBean.minimumPageSize
+ and pageControl.pageSize gt 0}">
+ <h:outputText value="Items Per Page: #{pageControl.pageSize}"
+ style="font-weight: bold; "
+ rendered="#{pagedDataUIBean.pageSizeCount le 1}"/>
+ <h:panelGroup layout="block" rendered="#{pagedDataUIBean.pageSizeCount gt 1}">
+ <h:outputText value="Items Per Page:"
+ style="margin-right: 1em; font-weight: bold; "/>
+ <h:selectOneListbox id="currentPageSize"
+ size="1"
+ value="#{pageControl.pageSize}">
+ <a4j:support event="onchange"
+ status="commonStatus"
+ reRender="#{dataTableName}, #{dataScrollerName}"/>
+ <f:selectItems value="#{pagedDataUIBean.pageSizeSelectItems}"/>
+ </h:selectOneListbox>
+ </h:panelGroup>
+ </h:panelGroup>
+
+ </td>
+
+ <td nowrap="nowrap">
+
+ <rich:datascroller id="#{dataScrollerName}"
+ for="#{dataTableName}"
+ status="commonStatus"
+ rendered="#{pageControl.pageSize gt 0}"
+ selectedStyle="font-weight: bold;"
+ inactiveStyle="font-weight: normal;"
+ stepControls="show"
+ fastControls="hide"
+ boundaryControls="hide"
+ maxPages="#{pagedDataUIBean.dataScrollerMaxPages}"
+ page="#{pagedDataUIBean.dataScrollerPage}">
+ <f:facet name="next">
+ <h:panelGroup>
+ <h:graphicImage value="http://127.0.0.1:7080/images/tbb_pageright.gif"
+ style="padding: 0px 5px 0px 7px;"/>
+ </h:panelGroup>
+ </f:facet>
+ <f:facet name="next_disabled">
+ <h:panelGroup>
+ <h:graphicImage value="http://127.0.0.1:7080/images/tbb_pageright_gray.gif"
+ style="padding: 0px 5px 0px 7px;"/>
+ </h:panelGroup>
+ </f:facet>
+ <f:facet name="previous">
+ <h:panelGroup>
+ <h:graphicImage value="http://127.0.0.1:7080/images/tbb_pageleft.gif"
+ style="padding: 0px 5px 0px 7px;"/>
+ </h:panelGroup>
+ </f:facet>
+ <f:facet name="previous_disabled">
+ <h:panelGroup>
+ <h:graphicImage value="http://127.0.0.1:7080/images/tbb_pageleft_gray.gif"
+ style="padding: 0px 5px 0px 7px;"/>
+ </h:panelGroup>
+ </f:facet>
+ </rich:datascroller>
+
+ </td>
+ </tr>
+ </table>
+
+ </h:panelGroup>
+
+ <div style="clear: both;"/>
+
+</ui:composition>
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/jboss-web.xml b/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/jboss-web.xml
new file mode 100644
index 0000000..d4b66f4
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/jboss-web.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE jboss-web PUBLIC
+ "-//JBoss//DTD Web Application 4.2//EN"
+ "http://www.jboss.org/j2ee/dtd/jboss-web_4_2.dtd">
+
+<!-- This is just a sample as needed by the Sample Perspective. Copy this file to your
+ application and modify the loader as needed.
+ -->
+
+<jboss-web>
+
+ <class-loading>
+ <loader-repository>
+ org.rhq:loader=sample-perspective
+ <loader-repository-config>java2ParentDelegation=false</loader-repository-config>
+ </loader-repository>
+ </class-loading>
+
+</jboss-web>
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/templates/mainTemplate.xhtml b/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/templates/mainTemplate.xhtml
new file mode 100644
index 0000000..21ec05f
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/templates/mainTemplate.xhtml
@@ -0,0 +1,70 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:fn="http://java.sun.com/jsp/jstl/functions"
+ xmlns:a4j="http://richfaces.org/a4j"
+ xmlns:rich="http://richfaces.org/rich"
+ xmlns:rhq="http://rhq-project.org/rhq"
+ xmlns:onc="http://jboss.org/on/component">
+
+<ui:remove>
+ <!-- Set the content type to "text/html" (overriding the default of "application/xhtml+xml") to force
+Firefox and other Gecko-based browsers to render the page in "Almost Standards" (i.e. transitional) mode. -->
+</ui:remove>
+<f:view contentType="text/html; charset=UTF-8">
+
+<head>
+ <title>${msg["product.shortName"]} - #{(!empty pageTitle) ? pageTitle : defaultPageTitle}</title>
+
+ <ui:insert name="metaHeaders"/>
+
+ <link rel="stylesheet" type="text/css" media="screen" href="#{PerspectiveClientUIBean.coreGuiBaseUrl}/css/win.css"/>
+ <link rel="stylesheet" type="text/css" media="screen" href="#{PerspectiveClientUIBean.coreGuiBaseUrl}/css/form-style.css"/>
+ <link rel="stylesheet" type="text/css" media="screen" href="#{PerspectiveClientUIBean.coreGuiBaseUrl}/css/menu.css"/>
+
+ <!-- Trims up the headers of RF toggle panel headers -->
+ <style type="text/css">
+ .BlockTitle {
+ padding-top: 3px;
+ padding-bottom: 3px;
+ }
+
+ HTML, BODY {
+ overflow: hidden;
+ }
+ </style>
+
+ <link rel="stylesheet" type="text/css" media="screen" href="#{PerspectiveClientUIBean.coreGuiBaseUrl}/css/tabular.css"/>
+ <link rel="stylesheet" type="text/css" media="screen" href="#{PerspectiveClientUIBean.coreGuiBaseUrl}/css/layout.css"/>
+
+ <script type="text/javascript">
+ var imagePath = "/images/";
+ </script>
+
+</head>
+
+<body bgcolor="#FFFFFF" style="height: 100%;">
+
+<h:panelGroup layout="block" style="font-weight: bold; margin-left: 15px; margin-bottom: 15px;">
+ <ui:insert name="breadcrumbs"/>
+</h:panelGroup>
+
+<rich:messages globalOnly="true"
+ infoClass="InfoBlock"
+ warnClass="WarnBlock"
+ errorClass="ErrorBlock"
+ fatalClass="FatalBlock" />
+
+<ui:insert name="body"/>
+
+</body>
+</f:view>
+</html>
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/web.xml b/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..fb66dca
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<web-app xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ version="2.5">
+
+ <display-name>RHQ Perspective Webapp</display-name>
+
+ <!--=== Seam ===-->
+
+ <listener>
+ <listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
+ </listener>
+
+ <!-- From Seam docs: The Seam master filter must be the first filter specified
+ in web.xml. This ensures it is run first. -->
+ <filter>
+ <filter-name>Seam Filter</filter-name>
+ <filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>
+ </filter>
+ <filter-mapping>
+ <filter-name>Seam Filter</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
+
+ <servlet>
+ <servlet-name>Seam Resource Servlet</servlet-name>
+ <servlet-class>org.jboss.seam.servlet.SeamResourceServlet</servlet-class>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>Seam Resource Servlet</servlet-name>
+ <url-pattern>/seam/resource/*</url-pattern>
+ </servlet-mapping>
+
+ <!-- flags for debugging during development -->
+ <context-param>
+ <param-name>com.sun.faces.validateXml</param-name>
+ <param-value>false</param-value>
+ </context-param>
+ <context-param>
+ <param-name>com.sun.faces.verifyObjects</param-name>
+ <param-value>false</param-value>
+ </context-param>
+
+ <!--=== JSF spec ===-->
+
+ <servlet>
+ <servlet-name>Faces Servlet</servlet-name>
+ <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <!-- serve Facelets pages (*.xhtml) via the JSF servlet -->
+ <servlet-mapping>
+ <servlet-name>Faces Servlet</servlet-name>
+ <url-pattern>*.seam</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name>Faces Servlet</servlet-name>
+ <url-pattern>*.xhtml</url-pattern>
+ </servlet-mapping>
+
+ <!-- the suffix for files containing JSF content (default is ".jsp") -->
+ <context-param>
+ <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
+ <param-value>.xhtml</param-value>
+ </context-param>
+
+ <!-- see http://www.jroller.com/page/mert?entry=state_saving_method_client_side for an explanation of the below param -->
+ <context-param>
+ <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
+ <param-value>server</param-value>
+ </context-param>
+
+ <!--=== Facelets ===-->
+
+ <!-- enable special debug output for development -->
+ <context-param>
+ <param-name>facelets.DEVELOPMENT</param-name>
+ <param-value>true</param-value>
+ </context-param>
+
+ <!--=== RichFaces ===-->
+
+ <!-- From Seam docs: If RichFaces is used in your project, Seam will install
+ the RichFaces Ajax filter for you, making sure to install it before all
+ other built-in filters. You don't need to install the RichFaces Ajax
+ filter in web.xml yourself. -->
+
+ <context-param>
+ <param-name>org.ajax4jsf.VIEW_HANDLERS</param-name>
+ <param-value>com.sun.facelets.FaceletViewHandler</param-value>
+ </context-param>
+
+ <!-- Temporarily uncomment the below context-param to disable compression of JavaScript files associated with
+ RichFaces components in order to debug those script files. -->
+ <context-param>
+ <param-name>org.ajax4jsf.COMPRESS_SCRIPT</param-name>
+ <param-value>false</param-value>
+ </context-param>
+
+ <welcome-file-list>
+ <welcome-file>index.xhtml</welcome-file>
+ </welcome-file-list>
+
+</web-app>
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/webapp/index.xhtml b/modules/enterprise/gui/base-perspective-war/src/main/webapp/index.xhtml
new file mode 100644
index 0000000..a461356
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-war/src/main/webapp/index.xhtml
@@ -0,0 +1,36 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:s="http://jboss.com/products/seam/taglib"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:a4j="http://richfaces.org/a4j"
+ xmlns:rich="http://richfaces.org/rich">
+
+ <head>
+ <title>
+ Perspective Web Application
+ </title>
+ </head>
+
+ <body style="background-color: #FF66CC">
+
+ <ui:remove>
+ <!-- Set the content type to "text/html" to ensure "application/xhtml+xml", which would put Firefox and
+ other Gecko-based browsers into XML mode (which requires pages to be well-formed XML), is not used.
+ We also specify the charset/encoding here, since we cannot specify it via the xml prolog, since
+ including an xml prolog causes IE6 to go into the undesirable "quirks mode".
+ (see https://jira.jboss.org/jira/browse/EMBJOPR-19) -->
+ </ui:remove>
+
+ <f:view contentType="text/html; charset=UTF-8">
+
+ <h1>YOUR CONTENT GOES HERE.</h1>
+
+ </f:view>
+
+ </body>
+
+</html>
+
diff --git a/modules/enterprise/server/ear/pom.xml b/modules/enterprise/server/ear/pom.xml
index 175420d..26b0ab5 100644
--- a/modules/enterprise/server/ear/pom.xml
+++ b/modules/enterprise/server/ear/pom.xml
@@ -219,7 +219,7 @@
<executions>
<execution>
- <id>copy-core-plugins</id>
+ <id>copy-core-agent-plugins</id>
<phase>process-resources</phase>
<goals>
<goal>copy</goal>
@@ -252,7 +252,7 @@
</execution>
<execution>
- <id>copy-rhq-serverplugins</id>
+ <id>copy-core-server-plugins</id>
<phase>process-resources</phase>
<goals>
<goal>copy</goal>
@@ -284,6 +284,12 @@
<version>${project.version}</version>
</artifactItem>
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server-policy-perspective</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
</artifactItems>
<outputDirectory>${earDirectory}/rhq-serverplugins</outputDirectory>
</configuration>
commit 7406c901785c89068720da295aebfd83968a7f33
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Tue Feb 16 17:03:02 2010 -0500
move base-perspective-war module from etc/modules/ to modules/enterprise/gui/; deploy policy perspective by default
diff --git a/etc/modules/base-perspective-war/pom.xml b/etc/modules/base-perspective-war/pom.xml
deleted file mode 100644
index fa64c2f..0000000
--- a/etc/modules/base-perspective-war/pom.xml
+++ /dev/null
@@ -1,233 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-parent</artifactId>
- <version>3.0.0-SNAPSHOT</version>
- </parent>
-
- <groupId>org.rhq</groupId>
- <artifactId>rhq-enterprise-server-base-perspective-war</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- <packaging>war</packaging>
-
- <name>RHQ Base Perspective War</name>
- <description>an abstract WAR that can be used by the maven war plugin as an overlay (i.e. base) for a perspective WAR</description>
-
- <scm>
- <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/etc/modules/base-perspecti...</connection>
- <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/etc/modules/base-perspecti...</developerConnection>
- </scm>
-
- <properties>
- <jsf.version>1.2_14</jsf.version>
- <facelets.version>1.1.15.B1</facelets.version>
- <!-- NOTE: Seam 2.1.2 and 2.2.0 can't be used in webapps deployed to the RHQ Server
- due to https://jira.jboss.org/jira/browse/JBSEAM-4029. Seam 2.2.1 can be
- used once it's released. -->
- <seam.version>2.1.0.SP1</seam.version>
- <jboss-el.version>1.0_02.CR5</jboss-el.version>
- <richfaces.version>3.3.2.SR1</richfaces.version>
- <rhq.version>3.0.0-SNAPSHOT</rhq.version>
- </properties>
-
- <dependencyManagement>
-
- <dependencies>
-
- <dependency>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-remoting-client-api</artifactId>
- <version>${project.parent.version}</version>
- </dependency>
-
- <dependency>
- <groupId>com.sun.facelets</groupId>
- <artifactId>jsf-facelets</artifactId>
- <version>${facelets.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.seam</groupId>
- <artifactId>jboss-seam</artifactId>
- <version>${seam.version}</version>
- <exclusions>
- <exclusion>
- <groupId>javax.el</groupId>
- <artifactId>el-api</artifactId>
- </exclusion>
- <exclusion>
- <groupId>xml-apis</groupId>
- <artifactId>xml-apis</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.seam</groupId>
- <artifactId>jboss-seam-ui</artifactId>
- <version>${seam.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.el</groupId>
- <artifactId>jboss-el</artifactId>
- <version>${jboss-el.version}</version>
- <exclusions>
- <exclusion>
- <groupId>javax.el</groupId>
- <artifactId>el-api</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.richfaces.framework</groupId>
- <artifactId>richfaces-api</artifactId>
- <version>${richfaces.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.richfaces.framework</groupId>
- <artifactId>richfaces-impl</artifactId>
- <version>${richfaces.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.richfaces.ui</groupId>
- <artifactId>richfaces-ui</artifactId>
- <version>${richfaces.version}</version>
- </dependency>
-
- <dependency>
- <groupId>javax.faces</groupId>
- <artifactId>jsf-api</artifactId>
- <version>${jsf.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-core-gui</artifactId>
- <version>${rhq.version}</version>
- </dependency>
-
- </dependencies>
-
- </dependencyManagement>
-
- <dependencies>
-
- <!-- This will pull in all the jars we need for making remote calls to the RHQ Server. -->
- <dependency>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-remoting-client-api</artifactId>
- </dependency>
-
- <dependency>
- <groupId>com.sun.facelets</groupId>
- <artifactId>jsf-facelets</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.seam</groupId>
- <artifactId>jboss-seam</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.seam</groupId>
- <artifactId>jboss-seam-ui</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.seam</groupId>
- <artifactId>jboss-seam-debug</artifactId>
- <version>${seam.version}</version>
- <!-- we should be pulling this in directly ourselves, not relying
- jboss-seam-debug to provide it -->
- <exclusions>
- <exclusion>
- <groupId>com.sun.facelets</groupId>
- <artifactId>jsf-facelets</artifactId>
- </exclusion>
- </exclusions>
- <scope>runtime</scope>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.el</groupId>
- <artifactId>jboss-el</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.richfaces.framework</groupId>
- <artifactId>richfaces-api</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.richfaces.framework</groupId>
- <artifactId>richfaces-impl</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.richfaces.ui</groupId>
- <artifactId>richfaces-ui</artifactId>
- </dependency>
-
- <dependency>
- <groupId>javax.faces</groupId>
- <artifactId>jsf-api</artifactId>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-core-gui</artifactId>
- </dependency>
-
- </dependencies>
-
- <build>
- <finalName>rhq-base-perspective</finalName>
-
- <plugins>
-
- <plugin>
- <artifactId>maven-war-plugin</artifactId>
- <configuration>
- <archive>
- <manifest>
- <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
- <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
- </manifest>
- <manifestEntries>
- <Build-Number>${buildNumber}</Build-Number>
- </manifestEntries>
- </archive>
- <webResources>
- <resource>
- <filtering>true</filtering>
- <directory>${basedir}/src/main/webapp</directory>
- <includes>
- <include>**/*.properties</include>
- </includes>
- </resource>
- </webResources>
- </configuration>
- </plugin>
-
- </plugins>
-
- </build>
-
- <repositories>
- <repository>
- <id>java.net-m1-releases</id>
- <name>Java.net Maven1 Repository - for javax.faces, javax.el, com.sun.el, and com.sun.facelets releases</name>
- <url>http://download.java.net/maven/1/</url>
- <layout>legacy</layout>
- </repository>
- </repositories>
-
-</project>
diff --git a/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java b/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java
deleted file mode 100644
index 27629db..0000000
--- a/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2009-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.server.perspective;
-
-import org.jboss.seam.Component;
-import org.jboss.seam.annotations.Create;
-import org.rhq.core.gui.table.bean.AbstractPagedDataUIBean;
-
-/**
- * A base class for Seam components that utilize the RHQ remote API to retrieve a paged data set of objects, which are
- * typically rendered using a dataTable component.
- *
- * @author Ian Springer
- */
-public abstract class AbstractPerspectivePagedDataUIBean extends AbstractPagedDataUIBean {
- protected PerspectiveClientUIBean perspectiveClient;
-
- @Create
- public void init() {
- if (this.perspectiveClient == null) {
- this.perspectiveClient = (PerspectiveClientUIBean) Component.getInstance(PerspectiveClientUIBean.class,
- true);
- }
- }
-}
diff --git a/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java b/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java
deleted file mode 100644
index b6ea66c..0000000
--- a/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package org.rhq.enterprise.server.perspective;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jboss.seam.annotations.web.RequestParameter;
-import org.rhq.core.domain.auth.Subject;
-import org.rhq.core.domain.criteria.ResourceCriteria;
-import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.util.PageList;
-import org.rhq.enterprise.client.RemoteClient;
-import org.rhq.enterprise.server.resource.ResourceManagerRemote;
-
-/**
- * A base class for Seam components that utilize the RHQ remote API in the context of a specific Resource.
- */
-public class AbstractPerspectiveResourceUIBean extends AbstractPerspectiveUIBean {
- private final Log log = LogFactory.getLog(this.getClass());
-
- @RequestParameter
- private Integer rhqResourceId;
-
- private Resource resource;
-
- public Resource getResource() throws Exception {
- if (this.resource == null) {
- this.resource = loadResource();
- log.debug("Retrieved current Resource " + this.resource);
- }
- return this.resource;
- }
-
- private Resource loadResource() throws Exception {
- if (this.rhqResourceId == null) {
- throw new IllegalStateException("The 'rhqResourceId' HTTP request parameter is required by this page.");
- }
- RemoteClient remoteClient = this.perspectiveClient.getRemoteClient();
- Subject subject = this.perspectiveClient.getSubject();
-
- // ***NOTE***: The javassist.NotFoundException stack traces that are logged by this call can be ignored.
- ResourceManagerRemote resourceManager = remoteClient.getResourceManagerRemote();
- ResourceCriteria resourceCriteria = new ResourceCriteria();
- resourceCriteria.addFilterId(this.rhqResourceId);
- PageList<Resource> resources = resourceManager.findResourcesByCriteria(subject, resourceCriteria);
- if (resources.isEmpty()) {
- throw new IllegalStateException("No Resource exists with the id " + this.rhqResourceId + ".");
- }
- return resources.get(0);
- }
-}
diff --git a/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java b/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java
deleted file mode 100644
index 56034bb..0000000
--- a/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2009-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.server.perspective;
-
-import org.jboss.seam.Component;
-import org.jboss.seam.annotations.Create;
-import org.jboss.seam.annotations.In;
-import org.jboss.seam.faces.FacesMessages;
-
-/**
- * A base class for Seam components that utilize the RHQ remote API.
- *
- * @author Ian Springer
- */
-public abstract class AbstractPerspectiveUIBean {
- @In
- protected FacesMessages facesMessages;
-
- protected PerspectiveClientUIBean perspectiveClient;
-
- @Create
- public void init() {
- this.perspectiveClient = (PerspectiveClientUIBean) Component.getInstance(PerspectiveClientUIBean.class, true);
- }
-}
\ No newline at end of file
diff --git a/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java b/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java
deleted file mode 100644
index 59c9c63..0000000
--- a/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java
+++ /dev/null
@@ -1,161 +0,0 @@
-package org.rhq.enterprise.server.perspective;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jboss.seam.ScopeType;
-import org.jboss.seam.annotations.AutoCreate;
-import org.jboss.seam.annotations.Name;
-import org.jboss.seam.annotations.Scope;
-import org.jboss.seam.annotations.web.RequestParameter;
-import org.jboss.seam.core.Conversation;
-import org.jetbrains.annotations.NotNull;
-import org.rhq.core.domain.auth.Subject;
-import org.rhq.enterprise.client.RemoteClient;
-import org.rhq.enterprise.server.auth.SubjectManagerRemote;
-
-/**
- * @author Ian Springer
- */
-(a)Name(PerspectiveClientUIBean.NAME)
-(a)Scope(ScopeType.CONVERSATION)
-@AutoCreate
-public class PerspectiveClientUIBean {
- public static final String NAME = "PerspectiveClientUIBean";
-
- private static final String DEFAULT_SERVER_HOST = "127.0.0.1";
- private static final int DEFAULT_SERVER_PORT = 7080;
- private static final String DEFAULT_USERNAME = "rhqadmin";
- private static final String DEFAULT_PASSWORD = "rhqadmin";
-
- private final Log log = LogFactory.getLog(this.getClass());
-
- @RequestParameter
- private String rhqServerHost;
- private String serverHost;
-
- @RequestParameter
- private Integer rhqServerPort;
- private Integer serverPort;
-
- @RequestParameter
- private String rhqUsername;
- private String username;
-
- @RequestParameter
- private String rhqPassword;
- private String password;
-
- @RequestParameter
- private Integer rhqSessionId;
-
- private RemoteClient remoteClient;
- private Subject subject;
- private String coreGuiBaseUrl;
-
- @NotNull
- public RemoteClient getRemoteClient() throws Exception {
- if (this.remoteClient == null) {
- this.remoteClient = new RemoteClient(null, getServerHost(), getServerPort());
- }
- if (!this.remoteClient.isConnected()) {
- try {
- this.remoteClient.connect();
- } catch (Exception e) {
- this.remoteClient = null;
- log.info("Ending perspective client Conversation with id " + Conversation.instance().getId() + "...");
- Conversation.instance().end();
- throw e;
- }
- Conversation.instance().begin();
- log.info("Began perspective client Conversation with id " + Conversation.instance().getId() + ".");
- }
- return this.remoteClient;
- }
-
- /**
- * Returns the currently logged in RHQ user.
- *
- * @return the currently logged in RHQ user
- *
- * @throws Exception if we are unable to obtain the Subject - hopefully this will encourage callers to set a
- * FacesMessage and return null to give the user a friendlier error
- */
- @NotNull
- public Subject getSubject() throws Exception {
- if (subject == null) {
- RemoteClient remoteClient = getRemoteClient();
- // ***NOTE***: The javassist.NotFoundException stack traces that are logged by this call can be ignored.
- SubjectManagerRemote subjectManager = remoteClient.getSubjectManagerRemote();
- if (this.rhqSessionId != null) {
- log.info("Retrieving subject for user [" + getUsername() + "] and sessionId [" + this.rhqSessionId + "]...");
- this.subject = subjectManager.getSubjectByNameAndSessionId(getUsername(), this.rhqSessionId);
- } else {
- log.info("Logging in as user [" + getUsername() + "] with password [" + getPassword() + "]...");
- this.subject = subjectManager.login(getUsername(), getPassword());
- }
- }
- return this.subject;
- }
-
- @NotNull
- public String getCoreGuiBaseUrl() throws Exception {
- if (this.coreGuiBaseUrl == null) {
- RemoteClient remoteClient = getRemoteClient();
- Subject subject = getSubject();
- PerspectiveManagerRemote perspectiveManager = remoteClient.getPerspectiveManagerRemote();
- this.coreGuiBaseUrl = perspectiveManager.getRootUrl(subject, true, false);
- }
- return this.coreGuiBaseUrl;
- }
-
- @NotNull
- private String getServerHost() {
- if (this.serverHost == null) {
- if (this.rhqServerHost != null) {
- this.serverHost = this.rhqServerHost;
- } else {
- return DEFAULT_SERVER_HOST;
- }
- } else {
- if (this.rhqServerHost != null && this.serverHost.equals(this.rhqServerHost)) {
-
- }
- }
- return this.serverHost;
- }
-
- private int getServerPort() {
- if (this.serverPort == null) {
- if (this.rhqServerPort != null) {
- this.serverPort = this.rhqServerPort;
- } else {
- return DEFAULT_SERVER_PORT;
- }
- }
- return this.serverPort;
- }
-
- @NotNull
- private String getUsername() {
- if (this.username == null) {
- if (this.rhqUsername != null) {
- this.username = this.rhqUsername;
- } else {
- return DEFAULT_USERNAME;
- }
- }
- return this.username;
- }
-
- @NotNull
- private String getPassword() {
- if (this.password == null) {
- if (this.rhqPassword != null) {
- this.password = this.rhqPassword;
- } else {
- return DEFAULT_PASSWORD;
- }
- }
- return this.password;
- }
-}
diff --git a/etc/modules/base-perspective-war/src/main/resources/seam.properties b/etc/modules/base-perspective-war/src/main/resources/seam.properties
deleted file mode 100644
index b97c770..0000000
--- a/etc/modules/base-perspective-war/src/main/resources/seam.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-# NOTE: The presence of this file tells Seam to scan this WAR for Seam
-# components (i.e. classes with Name annotations) and to deploy
-# any that it finds.
diff --git a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/components.xml b/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/components.xml
deleted file mode 100644
index 4631d2e..0000000
--- a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/components.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<components xmlns="http://jboss.com/products/seam/components"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:security="http://jboss.com/products/seam/security"
- xsi:schemaLocation=
- "http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.0.xsd
- http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.0.xsd">
-
- <component name="org.jboss.seam.core.init">
- <property name="debug">false</property>
- <!-- enable only when needed -->
- <property name="transactionManagementEnabled">false</property>
- </component>
-
-</components>
diff --git a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/faces-config.xml b/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/faces-config.xml
deleted file mode 100644
index f584c01..0000000
--- a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/faces-config.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0"?>
-
-<faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
-
- <!-- If your perspective application utilizes JSF managed beans then copy
- this file to your application and add declarations as needed.
-
- <managed-bean>
- <managed-bean-name>MyBeanName</managed-bean-name>
- <managed-bean-class>my.package.MyBeanName</managed-bean-class>
- <managed-bean-scope>session</managed-bean-scope>
- </managed-bean>
-
- -->
-
- <!-- If youe perspective application utilizes JSF navigation rules then copy
- this file to your application and add rules as needed.
-
- <navigation-rule>
- <from-tree-id></from-tree-id>
- <navigation-case></navigation-case>
- </navigation-rule>
-
- -->
-
-</faces-config>
diff --git a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/includes/pageControls.xhtml b/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/includes/pageControls.xhtml
deleted file mode 100644
index 2faad02..0000000
--- a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/includes/pageControls.xhtml
+++ /dev/null
@@ -1,103 +0,0 @@
-<?xml version="1.0"?>
-
-<ui:composition
- xmlns="http://www.w3.org/1999/xhtml"
- xmlns:f="http://java.sun.com/jsf/core"
- xmlns:h="http://java.sun.com/jsf/html"
- xmlns:ui="http://java.sun.com/jsf/facelets"
- xmlns:c="http://java.sun.com/jstl/core"
- xmlns:fn="http://java.sun.com/jsp/jstl/functions"
- xmlns:a4j="http://richfaces.org/a4j"
- xmlns:rich="http://richfaces.org/rich"
- xmlns:rhq="http://rhq-project.org/rhq"
- xmlns:onc="http://jboss.org/on/component">
-
- <ui:remove>
- Usage: The following parameters must be set in the calling page:
-
- pagedDataUIBean - an instance of AbstractPagedDataUIBean, which provides access to a data model, a page
- control, and page control settings (valid page sizes, etc.)
- dataTableName - name of the data table to be controlled
- </ui:remove>
-
- <h:panelGroup layout="block" style="float: right; margin-right: 30px">
- <ui:param name="dataScrollerName" value="#{dataTableName}Scroller"/>
- <ui:param name="dataModel" value="#{pagedDataUIBean.dataModel}"/>
- <ui:param name="pageControl" value="#{pagedDataUIBean.pageControl}"/>
-
- <table>
- <tr>
- <td nowrap="nowrap">
-
- <h:outputText value="Total: #{dataModel.rowCount}"
- style="margin-right: 2em; font-weight: bold; "/>
-
- <h:panelGroup layout="block" rendered="#{dataModel.rowCount gt pagedDataUIBean.minimumPageSize
- and pageControl.pageSize gt 0}">
- <h:outputText value="Items Per Page: #{pageControl.pageSize}"
- style="font-weight: bold; "
- rendered="#{pagedDataUIBean.pageSizeCount le 1}"/>
- <h:panelGroup layout="block" rendered="#{pagedDataUIBean.pageSizeCount gt 1}">
- <h:outputText value="Items Per Page:"
- style="margin-right: 1em; font-weight: bold; "/>
- <h:selectOneListbox id="currentPageSize"
- size="1"
- value="#{pageControl.pageSize}">
- <a4j:support event="onchange"
- status="commonStatus"
- reRender="#{dataTableName}, #{dataScrollerName}"/>
- <f:selectItems value="#{pagedDataUIBean.pageSizeSelectItems}"/>
- </h:selectOneListbox>
- </h:panelGroup>
- </h:panelGroup>
-
- </td>
-
- <td nowrap="nowrap">
-
- <rich:datascroller id="#{dataScrollerName}"
- for="#{dataTableName}"
- status="commonStatus"
- rendered="#{pageControl.pageSize gt 0}"
- selectedStyle="font-weight: bold;"
- inactiveStyle="font-weight: normal;"
- stepControls="show"
- fastControls="hide"
- boundaryControls="hide"
- maxPages="#{pagedDataUIBean.dataScrollerMaxPages}"
- page="#{pagedDataUIBean.dataScrollerPage}">
- <f:facet name="next">
- <h:panelGroup>
- <h:graphicImage value="http://127.0.0.1:7080/images/tbb_pageright.gif"
- style="padding: 0px 5px 0px 7px;"/>
- </h:panelGroup>
- </f:facet>
- <f:facet name="next_disabled">
- <h:panelGroup>
- <h:graphicImage value="http://127.0.0.1:7080/images/tbb_pageright_gray.gif"
- style="padding: 0px 5px 0px 7px;"/>
- </h:panelGroup>
- </f:facet>
- <f:facet name="previous">
- <h:panelGroup>
- <h:graphicImage value="http://127.0.0.1:7080/images/tbb_pageleft.gif"
- style="padding: 0px 5px 0px 7px;"/>
- </h:panelGroup>
- </f:facet>
- <f:facet name="previous_disabled">
- <h:panelGroup>
- <h:graphicImage value="http://127.0.0.1:7080/images/tbb_pageleft_gray.gif"
- style="padding: 0px 5px 0px 7px;"/>
- </h:panelGroup>
- </f:facet>
- </rich:datascroller>
-
- </td>
- </tr>
- </table>
-
- </h:panelGroup>
-
- <div style="clear: both;"/>
-
-</ui:composition>
diff --git a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/jboss-web.xml b/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/jboss-web.xml
deleted file mode 100644
index d4b66f4..0000000
--- a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/jboss-web.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0"?>
-
-<!DOCTYPE jboss-web PUBLIC
- "-//JBoss//DTD Web Application 4.2//EN"
- "http://www.jboss.org/j2ee/dtd/jboss-web_4_2.dtd">
-
-<!-- This is just a sample as needed by the Sample Perspective. Copy this file to your
- application and modify the loader as needed.
- -->
-
-<jboss-web>
-
- <class-loading>
- <loader-repository>
- org.rhq:loader=sample-perspective
- <loader-repository-config>java2ParentDelegation=false</loader-repository-config>
- </loader-repository>
- </class-loading>
-
-</jboss-web>
diff --git a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/templates/mainTemplate.xhtml b/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/templates/mainTemplate.xhtml
deleted file mode 100644
index 21ec05f..0000000
--- a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/templates/mainTemplate.xhtml
+++ /dev/null
@@ -1,70 +0,0 @@
-<?xml version="1.0"?>
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-
-<html xmlns="http://www.w3.org/1999/xhtml"
- xmlns:f="http://java.sun.com/jsf/core"
- xmlns:h="http://java.sun.com/jsf/html"
- xmlns:ui="http://java.sun.com/jsf/facelets"
- xmlns:c="http://java.sun.com/jstl/core"
- xmlns:fn="http://java.sun.com/jsp/jstl/functions"
- xmlns:a4j="http://richfaces.org/a4j"
- xmlns:rich="http://richfaces.org/rich"
- xmlns:rhq="http://rhq-project.org/rhq"
- xmlns:onc="http://jboss.org/on/component">
-
-<ui:remove>
- <!-- Set the content type to "text/html" (overriding the default of "application/xhtml+xml") to force
-Firefox and other Gecko-based browsers to render the page in "Almost Standards" (i.e. transitional) mode. -->
-</ui:remove>
-<f:view contentType="text/html; charset=UTF-8">
-
-<head>
- <title>${msg["product.shortName"]} - #{(!empty pageTitle) ? pageTitle : defaultPageTitle}</title>
-
- <ui:insert name="metaHeaders"/>
-
- <link rel="stylesheet" type="text/css" media="screen" href="#{PerspectiveClientUIBean.coreGuiBaseUrl}/css/win.css"/>
- <link rel="stylesheet" type="text/css" media="screen" href="#{PerspectiveClientUIBean.coreGuiBaseUrl}/css/form-style.css"/>
- <link rel="stylesheet" type="text/css" media="screen" href="#{PerspectiveClientUIBean.coreGuiBaseUrl}/css/menu.css"/>
-
- <!-- Trims up the headers of RF toggle panel headers -->
- <style type="text/css">
- .BlockTitle {
- padding-top: 3px;
- padding-bottom: 3px;
- }
-
- HTML, BODY {
- overflow: hidden;
- }
- </style>
-
- <link rel="stylesheet" type="text/css" media="screen" href="#{PerspectiveClientUIBean.coreGuiBaseUrl}/css/tabular.css"/>
- <link rel="stylesheet" type="text/css" media="screen" href="#{PerspectiveClientUIBean.coreGuiBaseUrl}/css/layout.css"/>
-
- <script type="text/javascript">
- var imagePath = "/images/";
- </script>
-
-</head>
-
-<body bgcolor="#FFFFFF" style="height: 100%;">
-
-<h:panelGroup layout="block" style="font-weight: bold; margin-left: 15px; margin-bottom: 15px;">
- <ui:insert name="breadcrumbs"/>
-</h:panelGroup>
-
-<rich:messages globalOnly="true"
- infoClass="InfoBlock"
- warnClass="WarnBlock"
- errorClass="ErrorBlock"
- fatalClass="FatalBlock" />
-
-<ui:insert name="body"/>
-
-</body>
-</f:view>
-</html>
diff --git a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/web.xml b/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index fb66dca..0000000
--- a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,108 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<web-app xmlns="http://java.sun.com/xml/ns/javaee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
- version="2.5">
-
- <display-name>RHQ Perspective Webapp</display-name>
-
- <!--=== Seam ===-->
-
- <listener>
- <listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
- </listener>
-
- <!-- From Seam docs: The Seam master filter must be the first filter specified
- in web.xml. This ensures it is run first. -->
- <filter>
- <filter-name>Seam Filter</filter-name>
- <filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>Seam Filter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
-
- <servlet>
- <servlet-name>Seam Resource Servlet</servlet-name>
- <servlet-class>org.jboss.seam.servlet.SeamResourceServlet</servlet-class>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>Seam Resource Servlet</servlet-name>
- <url-pattern>/seam/resource/*</url-pattern>
- </servlet-mapping>
-
- <!-- flags for debugging during development -->
- <context-param>
- <param-name>com.sun.faces.validateXml</param-name>
- <param-value>false</param-value>
- </context-param>
- <context-param>
- <param-name>com.sun.faces.verifyObjects</param-name>
- <param-value>false</param-value>
- </context-param>
-
- <!--=== JSF spec ===-->
-
- <servlet>
- <servlet-name>Faces Servlet</servlet-name>
- <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <!-- serve Facelets pages (*.xhtml) via the JSF servlet -->
- <servlet-mapping>
- <servlet-name>Faces Servlet</servlet-name>
- <url-pattern>*.seam</url-pattern>
- </servlet-mapping>
-
- <servlet-mapping>
- <servlet-name>Faces Servlet</servlet-name>
- <url-pattern>*.xhtml</url-pattern>
- </servlet-mapping>
-
- <!-- the suffix for files containing JSF content (default is ".jsp") -->
- <context-param>
- <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
- <param-value>.xhtml</param-value>
- </context-param>
-
- <!-- see http://www.jroller.com/page/mert?entry=state_saving_method_client_side for an explanation of the below param -->
- <context-param>
- <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
- <param-value>server</param-value>
- </context-param>
-
- <!--=== Facelets ===-->
-
- <!-- enable special debug output for development -->
- <context-param>
- <param-name>facelets.DEVELOPMENT</param-name>
- <param-value>true</param-value>
- </context-param>
-
- <!--=== RichFaces ===-->
-
- <!-- From Seam docs: If RichFaces is used in your project, Seam will install
- the RichFaces Ajax filter for you, making sure to install it before all
- other built-in filters. You don't need to install the RichFaces Ajax
- filter in web.xml yourself. -->
-
- <context-param>
- <param-name>org.ajax4jsf.VIEW_HANDLERS</param-name>
- <param-value>com.sun.facelets.FaceletViewHandler</param-value>
- </context-param>
-
- <!-- Temporarily uncomment the below context-param to disable compression of JavaScript files associated with
- RichFaces components in order to debug those script files. -->
- <context-param>
- <param-name>org.ajax4jsf.COMPRESS_SCRIPT</param-name>
- <param-value>false</param-value>
- </context-param>
-
- <welcome-file-list>
- <welcome-file>index.xhtml</welcome-file>
- </welcome-file-list>
-
-</web-app>
diff --git a/etc/modules/base-perspective-war/src/main/webapp/index.xhtml b/etc/modules/base-perspective-war/src/main/webapp/index.xhtml
deleted file mode 100644
index a461356..0000000
--- a/etc/modules/base-perspective-war/src/main/webapp/index.xhtml
+++ /dev/null
@@ -1,36 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
- xmlns:h="http://java.sun.com/jsf/html"
- xmlns:f="http://java.sun.com/jsf/core"
- xmlns:s="http://jboss.com/products/seam/taglib"
- xmlns:ui="http://java.sun.com/jsf/facelets"
- xmlns:a4j="http://richfaces.org/a4j"
- xmlns:rich="http://richfaces.org/rich">
-
- <head>
- <title>
- Perspective Web Application
- </title>
- </head>
-
- <body style="background-color: #FF66CC">
-
- <ui:remove>
- <!-- Set the content type to "text/html" to ensure "application/xhtml+xml", which would put Firefox and
- other Gecko-based browsers into XML mode (which requires pages to be well-formed XML), is not used.
- We also specify the charset/encoding here, since we cannot specify it via the xml prolog, since
- including an xml prolog causes IE6 to go into the undesirable "quirks mode".
- (see https://jira.jboss.org/jira/browse/EMBJOPR-19) -->
- </ui:remove>
-
- <f:view contentType="text/html; charset=UTF-8">
-
- <h1>YOUR CONTENT GOES HERE.</h1>
-
- </f:view>
-
- </body>
-
-</html>
-
diff --git a/modules/enterprise/gui/pom.xml b/modules/enterprise/gui/pom.xml
index 0da70b7..1e39958 100644
--- a/modules/enterprise/gui/pom.xml
+++ b/modules/enterprise/gui/pom.xml
@@ -34,6 +34,7 @@
<modules>
<module>portal-war</module>
<module>installer-war</module>
+ <module>base-perspective-war</module>
<module>webdav-war</module>
<module>content_http-war</module>
<module>alert-migration</module>
diff --git a/modules/enterprise/pom.xml b/modules/enterprise/pom.xml
index 82e5209..7b3f967 100644
--- a/modules/enterprise/pom.xml
+++ b/modules/enterprise/pom.xml
@@ -61,9 +61,9 @@
<module>server/jar</module>
<module>server/safe-invoker</module>
<module>server/sars</module>
+ <module>remoting</module>
<module>gui</module>
<module>server/plugins</module>
- <module>remoting</module>
<module>server/ear</module>
<module>server/container-lib</module>
<module>server/container</module>
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/pom.xml b/modules/enterprise/server/plugins/perspectives/policy/app/pom.xml
index 3c53325..27aa634 100644
--- a/modules/enterprise/server/plugins/perspectives/policy/app/pom.xml
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/pom.xml
@@ -27,7 +27,7 @@
<dependency>
<groupId>org.rhq</groupId>
<artifactId>rhq-enterprise-server-base-perspective-war</artifactId>
- <version>1.0.0-SNAPSHOT</version>
+ <version>${project.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@@ -42,7 +42,7 @@
<dependency>
<groupId>org.rhq</groupId>
<artifactId>rhq-enterprise-server-base-perspective-war</artifactId>
- <version>1.0.0-SNAPSHOT</version>
+ <version>${project.version}</version>
<type>war</type>
</dependency>
@@ -51,7 +51,7 @@
<dependency>
<groupId>org.rhq</groupId>
<artifactId>rhq-enterprise-server-base-perspective-war</artifactId>
- <version>1.0.0-SNAPSHOT</version>
+ <version>${project.version}</version>
<type>warpath</type>
</dependency>
commit fe17e6f371b816d6b5cb453219246a18928c2f21
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Tue Feb 16 16:54:07 2010 -0500
add support for optional plugin profiles to ear/pom.xml and remove hudson module from linux-plugins profile in plugins/pom.xml
diff --git a/modules/enterprise/server/ear/pom.xml b/modules/enterprise/server/ear/pom.xml
index bb2ff06..175420d 100644
--- a/modules/enterprise/server/ear/pom.xml
+++ b/modules/enterprise/server/ear/pom.xml
@@ -219,7 +219,7 @@
<executions>
<execution>
- <id>copy-rhq-plugins</id>
+ <id>copy-core-plugins</id>
<phase>process-resources</phase>
<goals>
<goal>copy</goal>
@@ -229,159 +229,23 @@
<artifactItem>
<groupId>org.rhq</groupId>
- <artifactId>rhq-agent-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-aliases-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-apache-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-augeas-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-cron-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-database-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-grub-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-hosts-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-hudson-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-iis-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <!--
- TODO: Uncomment once errors from RHQ-1226 are fixed. <artifactItem>
- <groupId>org.rhq</groupId> <artifactId>rhq-jira-plugin</artifactId>
- <version>${project.version}</version> </artifactItem>
- -->
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-jmx-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-mysql-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-netservices-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-oracle-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-perftest-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
<artifactId>rhq-platform-plugin</artifactId>
<version>${project.version}</version>
</artifactItem>
<artifactItem>
<groupId>org.rhq</groupId>
- <artifactId>rhq-postfix-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-postgres-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-samba-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-script-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-snmptrapd-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-sshd-plugin</artifactId>
+ <artifactId>rhq-agent-plugin</artifactId>
<version>${project.version}</version>
</artifactItem>
<artifactItem>
<groupId>org.rhq</groupId>
- <artifactId>rhq-sudoers-plugin</artifactId>
+ <artifactId>rhq-jmx-plugin</artifactId>
<version>${project.version}</version>
</artifactItem>
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-virt-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-kickstart-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
+ <!-- NOTE: The rest of the plugins are copied by enabled-by-default profiles defined below. -->
</artifactItems>
<outputDirectory>${earDirectory}/rhq-downloads/rhq-plugins</outputDirectory>
</configuration>
@@ -432,6 +296,308 @@
<profiles>
+ <profile>
+ <id>jboss-plugins</id>
+ <activation>
+ <property>
+ <name>java.home</name>
+ </property>
+ </activation>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+
+ <execution>
+ <id>copy-jboss-plugins</id>
+ <phase>process-resources</phase>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-augeas-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-apache-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.jboss.on</groupId>
+ <artifactId>jopr-tomcat-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.jboss.on</groupId>
+ <artifactId>jopr-jboss-as-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.jboss.on</groupId>
+ <artifactId>jopr-hibernate-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.jboss.on</groupId>
+ <artifactId>jopr-rhq-server-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.jboss.on</groupId>
+ <artifactId>jopr-jboss-cache-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.jboss.on</groupId>
+ <artifactId>jopr-jboss-as-5-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.jboss.on</groupId>
+ <artifactId>jopr-jboss-cache-v3-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ </artifactItems>
+ <outputDirectory>${earDirectory}/rhq-downloads/rhq-plugins</outputDirectory>
+ </configuration>
+ </execution>
+
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+
+ <profile>
+ <id>linux-plugins</id>
+ <activation>
+ <property>
+ <name>java.home</name>
+ </property>
+ </activation>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+
+ <execution>
+ <id>copy-linux-plugins</id>
+ <phase>process-resources</phase>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-augeas-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-cron-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-script-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-script2-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-grub-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-hosts-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-cobbler-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-sudoers-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-netservices-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-samba-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-postfix-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-aliases-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-sshd-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-virt-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-kickstart-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ </artifactItems>
+ <outputDirectory>${earDirectory}/rhq-downloads/rhq-plugins</outputDirectory>
+ </configuration>
+ </execution>
+
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ </profile>
+
+ <profile>
+ <id>misc-plugins</id>
+ <activation>
+ <property>
+ <name>java.home</name>
+ </property>
+ </activation>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+
+ <execution>
+ <id>copy-misc-plugins</id>
+ <phase>process-resources</phase>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-hudson-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-iis-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-database-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-postgres-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-mysql-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-oracle-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-snmptrapd-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-twitter-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-filetemplate-bundle-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ </artifactItems>
+ <outputDirectory>${earDirectory}/rhq-downloads/rhq-plugins</outputDirectory>
+ </configuration>
+ </execution>
+
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ </profile>
+
<profile>
<id>dev</id>
@@ -516,3 +682,4 @@
</profiles>
</project>
+
diff --git a/modules/plugins/pom.xml b/modules/plugins/pom.xml
index db7d4be..55e0546 100644
--- a/modules/plugins/pom.xml
+++ b/modules/plugins/pom.xml
@@ -128,9 +128,7 @@
<module>hosts</module>
<module>cobbler</module>
<module>sudoers</module>
- <module>hudson</module>
<module>netservices</module>
- <module>perftest</module>
<module>samba</module>
<module>postfix</module>
<module>aliases</module>
commit aca7641c34a3a79b50ce5dd44ee565948f3a0f46
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Tue Feb 16 09:24:33 2010 -0500
further work on policy persp bundle CRUD pages
diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/table/renderer/AllRowsSelectorRenderer.java b/modules/core/gui/src/main/java/org/rhq/core/gui/table/renderer/AllRowsSelectorRenderer.java
index 85d8ddc..40da965 100644
--- a/modules/core/gui/src/main/java/org/rhq/core/gui/table/renderer/AllRowsSelectorRenderer.java
+++ b/modules/core/gui/src/main/java/org/rhq/core/gui/table/renderer/AllRowsSelectorRenderer.java
@@ -18,7 +18,6 @@
*/
package org.rhq.core.gui.table.renderer;
-import com.sun.faces.util.MessageUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rhq.core.gui.table.component.AllRowsSelectorComponent;
@@ -57,6 +56,8 @@ public class AllRowsSelectorRenderer extends AbstractRenderer {
return;
}
+ // TODO: Do not render if the data model's row count is 0.
+
ResponseWriter writer = context.getResponseWriter();
writer.startElement("input", component);
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 530b91d..3045872 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
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2009 Red Hat, Inc.
+ * Copyright (C) 2005-2010 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -55,6 +55,7 @@ import org.rhq.enterprise.server.util.CriteriaQueryRunner;
* Manages the creation and usage of bundles.
*
* @author John Mazzitelli
+ * @author Ian Springer
*/
@Stateless
public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemote {
@@ -182,14 +183,25 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
Bundle bundle = new Bundle(UUID.randomUUID().toString(), bundleType);
+ bundle = createBundle(subject, bundle);
+
// Add 1 to 5 bundle versions.
int bundleVersionCount = random.nextInt(5) + 1;
for (int i = 0; i < bundleVersionCount; i++) {
String bundleVersionName = UUID.randomUUID().toString();
- BundleVersion bundleVersion = new BundleVersion(bundleVersionName, String.valueOf(i), null, "blah blah blah");
+ final String RECIPE = "repo rhel-x86_64-5\n" +
+ "package foo-1.25.rpm\n" +
+ "package bar-1.25.rpm\n" +
+ "script foo.bash -c some parameter\n" +
+ "deploy jboss.tar %{jboss.home.directory}\n" +
+ "realize %{jboss.home.directory}/server/default/setting.xml\n" +
+ "file example.setting /etc/some/setting.ini\n" +
+ "service example restart\n";
+ BundleVersion bundleVersion = new BundleVersion(bundleVersionName, String.valueOf(i + 1), null, RECIPE);
bundle.addBundleVersion(bundleVersion);
}
- return createBundle(subject, bundle);
+ bundle = entityManager.merge(bundle);
+ return bundle;
}
}
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 025d1cb..09408b3 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
@@ -28,9 +28,11 @@ import javax.jws.soap.SOAPBinding;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.Bundle;
+import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.criteria.BundleCriteria;
+import org.rhq.core.domain.criteria.BundleDeployDefinitionCriteria;
import org.rhq.core.domain.criteria.BundleVersionCriteria;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
@@ -53,6 +55,9 @@ public interface BundleManagerRemote {
PageList<BundleVersion> findBundleVersionsByCriteria(Subject subject, BundleVersionCriteria criteria);
+ PageList<BundleDeployDefinition> findBundleDeployDefinitionsByCriteria(Subject subject,
+ BundleDeployDefinitionCriteria criteria);
+
void deleteBundles(Subject subject, int[] bundleIds);
void deleteBundleVersions(Subject subject, int[] bundleVersionIds);
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundleDetailsUIBean.java b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundleDetailsUIBean.java
index d9e6db3..0dd1fb3 100644
--- a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundleDetailsUIBean.java
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundleDetailsUIBean.java
@@ -145,8 +145,8 @@ public class BundleDetailsUIBean extends AbstractPerspectivePagedDataUIBean {
}
BundleVersionCriteria bundleVersionCriteria = new BundleVersionCriteria();
- String bundleName = BundleDetailsUIBean.this.getBundle().getName();
bundleVersionCriteria.setPageControl(pageControl);
+ String bundleName = BundleDetailsUIBean.this.getBundle().getName();
bundleVersionCriteria.addFilterBundleName(bundleName);
// TODO: Implement user-specified filters.
PageList<BundleVersion> bundleVersions = bundleManager.findBundleVersionsByCriteria(subject,
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundleVersionDetailsUIBean.java b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundleVersionDetailsUIBean.java
new file mode 100644
index 0000000..b602595
--- /dev/null
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundleVersionDetailsUIBean.java
@@ -0,0 +1,163 @@
+/*
+ * 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.server.perspective.policy;
+
+import org.ajax4jsf.model.KeepAlive;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.web.RequestParameter;
+import org.jboss.seam.international.StatusMessage;
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.bundle.Bundle;
+import org.rhq.core.domain.bundle.BundleDeployDefinition;
+import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.criteria.BundleDeployDefinitionCriteria;
+import org.rhq.core.domain.criteria.BundleVersionCriteria;
+import org.rhq.core.domain.util.PageControl;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.core.gui.table.bean.AbstractPagedDataUIBean;
+import org.rhq.core.gui.table.model.PagedListDataModel;
+import org.rhq.enterprise.client.RemoteClient;
+import org.rhq.enterprise.server.bundle.BundleManagerRemote;
+import org.rhq.enterprise.server.perspective.AbstractPerspectivePagedDataUIBean;
+import org.rhq.enterprise.server.perspective.PerspectiveClientUIBean;
+
+import java.util.List;
+
+/**
+ * Provides details about a particular {@link org.rhq.core.domain.bundle.BundleVersion version} of a provisioning
+ * bundle, including CRUD operations on the {@link org.rhq.core.domain.bundle.BundleDeployDefinition deployment
+ * definition}s defined for that bundle version. The backing bean for bundleVersionDetails.xhtml.
+ *
+ * @author Ian Springer
+ */
+@Name("BundleVersionDetailsUIBean")
+(a)Scope(ScopeType.EVENT)
+@KeepAlive
+public class BundleVersionDetailsUIBean extends AbstractPerspectivePagedDataUIBean {
+ private List<BundleDeployDefinition> selectedBundleDeployDefinitions;
+
+ @RequestParameter
+ private int bundleVersionId;
+
+ private BundleVersion bundleVersion;
+
+ public BundleVersion getBundleVersion() {
+ if (this.bundleVersion == null) {
+ this.bundleVersion = loadBundleVersion();
+ }
+ return this.bundleVersion;
+ }
+
+ public Bundle getBundle() {
+ return getBundleVersion().getBundle();
+ }
+
+ @Override
+ public PagedListDataModel createDataModel() {
+ return new DataModel(this);
+ }
+
+ public List<BundleDeployDefinition> getSelectedBundleDeployDefinitions() {
+ return this.selectedBundleDeployDefinitions;
+ }
+
+ public void setSelectedBundleDeployDefinitions(List<BundleDeployDefinition> selectedBundleDeployDefinitions) {
+ this.selectedBundleDeployDefinitions = selectedBundleDeployDefinitions;
+ }
+
+ public void deleteSelectedBundleDeployDefinitions() throws Exception {
+ RemoteClient remoteClient;
+ Subject subject;
+ try {
+ remoteClient = this.perspectiveClient.getRemoteClient();
+ subject = this.perspectiveClient.getSubject();
+ } catch (Exception e) {
+ this.facesMessages.add(StatusMessage.Severity.FATAL, "Failed to connect to RHQ Server - cause: " + e);
+ return;
+ }
+
+ // ***NOTE***: The javassist.NotFoundException stack traces that are logged by this call can be ignored.
+ BundleManagerRemote bundleManager = remoteClient.getBundleManagerRemote();
+
+ int[] selectedBundleDeployDefinitionIds = new int[this.selectedBundleDeployDefinitions.size()];
+ for (int i = 0, selectedBundlesSize = this.selectedBundleDeployDefinitions.size(); i < selectedBundlesSize; i++) {
+ BundleDeployDefinition selectedBundleDeployDefinition = this.selectedBundleDeployDefinitions.get(i);
+ selectedBundleDeployDefinitionIds[i] = selectedBundleDeployDefinition.getId();
+ }
+
+ //bundleManager.deleteBundleDeploymentDefinitions(subject, selectedBundleDeploymentDefinitionsIds);
+
+ // Add message to tell the user the uninventory was a success.
+ String pluralizer = (this.selectedBundleDeployDefinitions.size() == 1) ? "" : "s";
+ this.facesMessages.add("Deleted " + this.selectedBundleDeployDefinitions.size() + " bundle deployment definition" + pluralizer + ".");
+
+ // Reset the data model, so the current page will get refreshed to reflect the Resources we just uninventoried.
+ // This is essential, since we are CONVERSATION-scoped and will live on beyond this request.
+ setDataModel(null);
+ }
+
+ private BundleVersion loadBundleVersion() {
+ BundleManagerRemote bundleManager;
+ Subject subject;
+ try {
+ bundleManager = this.perspectiveClient.getRemoteClient().getBundleManagerRemote();
+ subject = this.perspectiveClient.getSubject();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ BundleVersionCriteria bundleVersionCriteria = new BundleVersionCriteria();
+ bundleVersionCriteria.addFilterId(this.bundleVersionId);
+ PageList<BundleVersion> bundleVersions = bundleManager.findBundleVersionsByCriteria(subject, bundleVersionCriteria);
+ if (bundleVersions.isEmpty()) {
+ throw new IllegalStateException("Bundle version with id " + this.bundleVersionId + " not found.");
+ }
+ return bundleVersions.get(0);
+ }
+
+ private class DataModel extends PagedListDataModel<BundleDeployDefinition> {
+ private DataModel(AbstractPagedDataUIBean pagedDataBean) {
+ super(pagedDataBean);
+ }
+
+ @Override
+ public PageList<BundleDeployDefinition> fetchPage(PageControl pageControl) {
+ PerspectiveClientUIBean perspectiveClient = BundleVersionDetailsUIBean.this.perspectiveClient;
+ BundleManagerRemote bundleManager;
+ Subject subject;
+ try {
+ bundleManager = perspectiveClient.getRemoteClient().getBundleManagerRemote();
+ subject = BundleVersionDetailsUIBean.this.perspectiveClient.getSubject();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ BundleDeployDefinitionCriteria bundleDeployDefinitionCriteria = new BundleDeployDefinitionCriteria();
+ bundleDeployDefinitionCriteria.setPageControl(pageControl);
+ // TODO
+ //bundleDeployDefinitionCriteria.addFilterVersionId(BundleVersionDetailsUIBean.this.bundleVersionId);
+ bundleDeployDefinitionCriteria.fetchBundle(true);
+ // TODO: Implement user-specified filters.
+ PageList<BundleDeployDefinition> bundleDeployDefinitions = bundleManager.findBundleDeployDefinitionsByCriteria(subject,
+ bundleDeployDefinitionCriteria);
+ return bundleDeployDefinitions;
+ }
+ }
+}
\ No newline at end of file
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundleDetails.xhtml b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundleDetails.xhtml
index 64d78bd..a0b504d 100644
--- a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundleDetails.xhtml
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundleDetails.xhtml
@@ -23,20 +23,22 @@
<ui:define name="body">
- <div><h:panelGroup layout="block" rendered="#{ServerInfoUIBean.debugModeEnabled}">
- <b>Id:</b> #{bundle.id}
- </h:panelGroup></div>
- <div><h:panelGroup layout="block">
- <b>Name:</b> #{bundle.name}
- </h:panelGroup></div>
- <div><h:panelGroup layout="block">
- <b>Type:</b> #{bundle.bundleType.name}
- </h:panelGroup></div>
+ <rich:panel>
+ <div><h:panelGroup layout="block" rendered="#{ServerInfoUIBean.debugModeEnabled}">
+ <b>Id:</b> #{bundle.id}
+ </h:panelGroup></div>
+ <div><h:panelGroup layout="block">
+ <b>Name:</b> #{bundle.name}
+ </h:panelGroup></div>
+ <div><h:panelGroup layout="block">
+ <b>Type:</b> #{bundle.bundleType.name}
+ </h:panelGroup></div>
+ </rich:panel>
<ui:remove><!-- NOTE: The table needs to be surrounded by a form for paging and sorting to work! --></ui:remove>
<a4j:form ajaxSubmit="false" reRender="bundlesVersionsDataTable">
- <f:param name="bundleId" value="#{bundleId}"/>
+ <f:param name="bundleId" value="#{param.bundleId}"/>
<rich:dataTable id="bundleVersionsDataTable"
value="#{BundleDetailsUIBean.dataModel}" var="bundleVersion"
@@ -77,7 +79,7 @@
</rhq:sortableColumnHeader>
</f:facet>
- <h:outputLink value="bundleDeploymentDefinitions.seam">
+ <h:outputLink value="bundleVersionDetails.seam">
<f:param name="bundleVersionId" value="#{bundleVersion.id}"/>
<h:outputText value="#{bundleVersion.name}"/>
</h:outputLink>
@@ -88,7 +90,8 @@
<rich:column colspan="3">
<rhq:selectedRowsCommandButton
value="DELETE"
- action="#{BundleDetailsUIBean.deleteSelectedBundleVersions}"/>
+ action="#{BundleDetailsUIBean.deleteSelectedBundleVersions}"
+ rendered="#{BundleDetailsUIBean.dataModel.rowCount gt 0}"/>
<ui:include src="/WEB-INF/includes/pageControls.xhtml">
<ui:param name="pagedDataUIBean" value="#{BundleDetailsUIBean}"/>
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundleVersionDetails.xhtml b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundleVersionDetails.xhtml
new file mode 100644
index 0000000..76d5d74
--- /dev/null
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundleVersionDetails.xhtml
@@ -0,0 +1,120 @@
+<?xml version="1.0"?>
+
+<ui:composition
+ template="/WEB-INF/templates/mainTemplate.xhtml"
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:fn="http://java.sun.com/jsp/jstl/functions"
+ xmlns:a4j="http://richfaces.org/a4j"
+ xmlns:rich="http://richfaces.org/rich"
+ xmlns:rhq="http://rhq-project.org/rhq"
+ xmlns:onc="http://jboss.org/on/component">
+
+ <ui:param name="bundleVersion" value="#{BundleVersionDetailsUIBean.bundleVersion}"/>
+ <ui:param name="bundle" value="#{BundleVersionDetailsUIBean.bundle}"/>
+
+ <ui:define name="breadcrumbs">
+ Administration >
+ <h:outputLink value="bundles.seam">Provisioning Bundles</h:outputLink> >
+ <h:outputLink value="bundleDetails.seam">
+ <f:param name="bundleId" value="#{bundle.id}"/>
+ #{bundle.bundleType.name} Bundle '#{bundle.name}'
+ </h:outputLink> >
+ Version #{bundleVersion.version}
+ </ui:define>
+
+ <ui:define name="body">
+
+ <rich:panel>
+ <div><h:panelGroup layout="block" rendered="#{ServerInfoUIBean.debugModeEnabled}">
+ <b>Id:</b> #{bundleVersion.id}
+ </h:panelGroup></div>
+ <div><h:panelGroup layout="block">
+ <b>Version:</b> #{bundleVersion.version}
+ </h:panelGroup></div>
+ <div><h:panelGroup layout="block">
+ <b>Name:</b> #{bundleVersion.name}
+ </h:panelGroup></div>
+ </rich:panel>
+
+ <rich:panel>
+ <f:facet name="header">
+ Recipe
+ </f:facet>
+ <h:inputTextarea value="#{bundleVersion.recipe}" cols="80" rows="10" disabled="true"/>
+ </rich:panel>
+
+ <ui:remove><!-- NOTE: The table needs to be surrounded by a form for paging and sorting to work! --></ui:remove>
+ <a4j:form ajaxSubmit="false" reRender="bundleDeployDefinitionsDataTable">
+
+ <f:param name="bundleVersionId" value="#{param.bundleVersionId}"/>
+
+ <rich:dataTable id="bundleDeployDefinitionsDataTable"
+ value="#{BundleVersionDetailsUIBean.dataModel}" var="bundleDeployDefinition"
+ first="#{BundleVersionDetailsUIBean.pageControl.pageNumber}"
+ rows="#{BundleVersionDetailsUIBean.pageControl.pageSize}"
+ sortMode="multi"
+ width="100%">
+
+ <f:facet name="header">
+ <h:outputText value="Deployment Definitions"/>
+ </f:facet>
+
+ <rich:column width="20">
+ <f:facet name="header">
+ <rhq:allRowsSelector/>
+ </f:facet>
+ <rhq:rowSelector value="#{BundleVersionDetailsUIBean.selectedBundleDeployDefinitions}"/>
+ </rich:column>
+
+ <rich:column width="125">
+ <f:facet name="header">
+ <rhq:sortableColumnHeader sortBy="BundleDeployDefinition.name">
+ <a4j:support event="onclick"
+ actionListener="#{BundleVersionDetailsUIBean.ajaxSortListener}"/>
+ <h:outputText value="Name"/>
+ </rhq:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputLink value="bundleDeployDefinitionDetails.seam">
+ <f:param name="bundleDeployDefinitionId" value="#{bundleDeployDefinition.id}"/>
+ <h:outputText value="#{bundleDeployDefinition.name}"/>
+ </h:outputLink>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <rhq:sortableColumnHeader sortBy="BundleDeployDefinition.description">
+ <a4j:support event="onclick"
+ actionListener="#{BundleVersionDetailsUIBean.ajaxSortListener}"/>
+ <h:outputText value="Description"/>
+ </rhq:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{bundleDeployDefinition.description}"/>
+ </rich:column>
+
+ <f:facet name="footer">
+ <rich:columnGroup>
+ <rich:column colspan="3">
+ <rhq:selectedRowsCommandButton
+ value="DELETE"
+ action="#{BundleVersionDetailsUIBean.deleteSelectedBundleDeployDefinitions}"
+ rendered="#{BundleVersionDetailsUIBean.dataModel.rowCount gt 0}"/>
+
+ <ui:include src="/WEB-INF/includes/pageControls.xhtml">
+ <ui:param name="pagedDataUIBean" value="#{BundleVersionDetailsUIBean}"/>
+ <ui:param name="dataTableName" value="bundleDeployDefinitionsDataTable"/>
+ </ui:include>
+ </rich:column>
+ </rich:columnGroup>
+ </f:facet>
+ </rich:dataTable>
+ </a4j:form>
+
+ </ui:define>
+
+</ui:composition>
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml
index 8c9b809..b680fe3 100644
--- a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml
@@ -69,7 +69,8 @@
<rich:column colspan="3">
<rhq:selectedRowsCommandButton
value="DELETE"
- action="#{BundlesUIBean.deleteSelectedBundles}"/>
+ action="#{BundlesUIBean.deleteSelectedBundles}"
+ rendered="#{BundlesUIBean.dataModel.rowCount gt 0}"/>
<ui:include src="/WEB-INF/includes/pageControls.xhtml">
<ui:param name="pagedDataUIBean" value="#{BundlesUIBean}"/>
commit a4a0aefc4b2cdf83d3011f591e7eecddeba2e0c1
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Mon Feb 15 18:30:00 2010 -0500
fix bug in fetchPageGuarded()'s check for pageControl that's inconsistent w/ the results
diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/table/model/PagedListDataModel.java b/modules/core/gui/src/main/java/org/rhq/core/gui/table/model/PagedListDataModel.java
index efb5f56..c327c7b 100644
--- a/modules/core/gui/src/main/java/org/rhq/core/gui/table/model/PagedListDataModel.java
+++ b/modules/core/gui/src/main/java/org/rhq/core/gui/table/model/PagedListDataModel.java
@@ -213,9 +213,10 @@ public abstract class PagedListDataModel<T> extends DataModel {
* RF components, the DataTable component does not see this change. so, we have to explicitly
* update the page control to get the view consistent with the backend once again.
*/
- if (results.getTotalSize() <= pageControl.getStartRow() || (results.isEmpty() && pageControl.getPageNumber() != 0)) {
+ if ((results.getTotalSize() != 0 && results.getTotalSize() <= pageControl.getStartRow()) ||
+ (results.isEmpty() && pageControl.getPageNumber() != 0)) {
if (log.isTraceEnabled()) {
- if (results.getTotalSize() <= pageControl.getStartRow()) {
+ if (results.getTotalSize() != 0 && results.getTotalSize() <= pageControl.getStartRow()) {
//log.trace(pageControlView + ": Results size[" + results.getTotalSize()
// + "] was less than PageControl startRow[" + pageControl.getStartRow() + "]");
} else {
commit b174715037e064aafd8d20ba8d10634673625c2e
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Mon Feb 15 18:28:46 2010 -0500
add bundleDetails.xhtml page and associated UIBean to policy perspective
diff --git a/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java b/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java
index 1430a79..27629db 100644
--- a/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java
+++ b/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java
@@ -33,6 +33,9 @@ public abstract class AbstractPerspectivePagedDataUIBean extends AbstractPagedDa
@Create
public void init() {
- this.perspectiveClient = (PerspectiveClientUIBean) Component.getInstance(PerspectiveClientUIBean.class, true);
+ if (this.perspectiveClient == null) {
+ this.perspectiveClient = (PerspectiveClientUIBean) Component.getInstance(PerspectiveClientUIBean.class,
+ true);
+ }
}
}
diff --git a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/templates/mainTemplate.xhtml b/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/templates/mainTemplate.xhtml
index 9b7826e..21ec05f 100644
--- a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/templates/mainTemplate.xhtml
+++ b/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/templates/mainTemplate.xhtml
@@ -53,7 +53,9 @@ Firefox and other Gecko-based browsers to render the page in "Almost Standards"
<body bgcolor="#FFFFFF" style="height: 100%;">
-<h1>#{(!empty pageTitle) ? pageTitle : defaultPageTitle}</h1>
+<h:panelGroup layout="block" style="font-weight: bold; margin-left: 15px; margin-bottom: 15px;">
+ <ui:insert name="breadcrumbs"/>
+</h:panelGroup>
<rich:messages globalOnly="true"
infoClass="InfoBlock"
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/perspective/main.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/perspective/main.xhtml
index 72f70b8..31cb447 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/perspective/main.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/perspective/main.xhtml
@@ -20,7 +20,7 @@
value="PERSPECTIVE PAGE" />
<ui:define name="breadcrumbs">
- <h:outputLink value="/">Custom</h:outputLink>
+ <ui:remove><!-- Leave this empty, so the embedded page can render the breadcrumbs itself. --></ui:remove>
</ui:define>
<ui:define name="body">
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 7c95fdd..530b91d 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
@@ -157,6 +157,13 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
}
+ public void deleteBundleVersions(Subject subject, int[] bundleVersionIds) {
+ for (int bundleVersionId : bundleVersionIds) {
+ BundleVersion bundleVersion = this.entityManager.find(BundleVersion.class, bundleVersionId);
+ this.entityManager.remove(bundleVersion);
+ }
+ }
+
public BundleType createMockBundleType(Subject subject) {
ResourceType linuxPlatformResourceType = this.resourceTypeManager.getResourceTypeByNameAndPlugin("Linux",
"Platforms");
@@ -165,15 +172,24 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
public Bundle createMockBundle(Subject subject, List<BundleType> bundleTypes) {
+ Random random = new Random();
BundleType bundleType;
if (bundleTypes.isEmpty()) {
bundleType = createMockBundleType(subject);
} else {
- Random random = new Random();
int randomIndex = random.nextInt(bundleTypes.size());
bundleType = bundleTypes.get(randomIndex);
}
Bundle bundle = new Bundle(UUID.randomUUID().toString(), bundleType);
+
+ // Add 1 to 5 bundle versions.
+ int bundleVersionCount = random.nextInt(5) + 1;
+ for (int i = 0; i < bundleVersionCount; i++) {
+ String bundleVersionName = UUID.randomUUID().toString();
+ BundleVersion bundleVersion = new BundleVersion(bundleVersionName, String.valueOf(i), null, "blah blah blah");
+ bundle.addBundleVersion(bundleVersion);
+ }
+
return createBundle(subject, bundle);
}
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
index 4542574..9cfc099 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
@@ -65,4 +65,6 @@ public interface BundleManagerLocal {
List<BundleType> getAllBundleTypes(Subject subject);
void deleteBundles(Subject subject, int[] bundleIds);
+
+ void deleteBundleVersions(Subject subject, int[] bundleVersionIds);
}
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 3b6454a..025d1cb 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
@@ -29,7 +29,9 @@ import javax.jws.soap.SOAPBinding;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleType;
+import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.criteria.BundleCriteria;
+import org.rhq.core.domain.criteria.BundleVersionCriteria;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.system.ServerVersion;
@@ -49,5 +51,9 @@ public interface BundleManagerRemote {
PageList<Bundle> findBundlesByCriteria(Subject subject, BundleCriteria criteria);
+ PageList<BundleVersion> findBundleVersionsByCriteria(Subject subject, BundleVersionCriteria criteria);
+
void deleteBundles(Subject subject, int[] bundleIds);
+
+ void deleteBundleVersions(Subject subject, int[] bundleVersionIds);
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginManager.java
index 85aa235..88153a6 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginManager.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginManager.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2009 Red Hat, Inc.
+ * Copyright (C) 2005-2010 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -26,6 +26,7 @@ import java.util.Collections;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
+import javax.management.MBeanException;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.naming.Context;
@@ -106,29 +107,25 @@ public class PerspectiveServerPluginManager extends ServerPluginManager {
}
}
} catch (Exception e) {
- getLog().error("Failed to deploy " + env.getPluginKey().getPluginName() + "#" + name, e);
+ Throwable t = (e instanceof MBeanException) ? e.getCause() : e;
+ log.error("Failed to deploy " + env.getPluginKey().getPluginName() + "#" + name, t);
}
}
- private void deployWar(ServerPluginEnvironment env, String name, InputStream iStream) {
- try {
- // Save the war file to the plugins data directory. This survives restarts and will
- // act as our deploy directory.
- File deployFile = writeWarToFile(getDeployFile(env, name), iStream);
-
- // get reference to MBean server
- Context ic = new InitialContext();
- MBeanServerConnection server = (MBeanServerConnection) ic.lookup("jmx/invoker/RMIAdaptor");
+ private void deployWar(ServerPluginEnvironment env, String name, InputStream iStream) throws Exception {
+ // Save the war file to the plugins data directory. This survives restarts and will
+ // act as our deploy directory.
+ File deployFile = writeWarToFile(getDeployFile(env, name), iStream);
- // get reference to MainDeployer MBean
- ObjectName mainDeployer = new ObjectName("jboss.system:service=MainDeployer");
+ // get reference to MBean server
+ Context ic = new InitialContext();
+ MBeanServerConnection server = (MBeanServerConnection) ic.lookup("jmx/invoker/RMIAdaptor");
- server.invoke(mainDeployer, "deploy", new Object[] { deployFile.getAbsolutePath() },
- new String[] { String.class.getName() });
+ // get reference to MainDeployer MBean
+ ObjectName mainDeployer = new ObjectName("jboss.system:service=MainDeployer");
- } catch (Exception e) {
- e.printStackTrace();
- }
+ server.invoke(mainDeployer, "deploy", new Object[] { deployFile.getAbsolutePath() },
+ new String[] { String.class.getName() });
}
private File getDeployFile(ServerPluginEnvironment env, String name) throws IOException {
@@ -260,5 +257,4 @@ public class PerspectiveServerPluginManager extends ServerPluginManager {
log.error("Failed to undeploy perspective WAR [" + deployFile + "].", e);
}
}
-
}
\ No newline at end of file
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundleDetailsUIBean.java b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundleDetailsUIBean.java
new file mode 100644
index 0000000..d9e6db3
--- /dev/null
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundleDetailsUIBean.java
@@ -0,0 +1,157 @@
+/*
+ * 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.server.perspective.policy;
+
+import org.ajax4jsf.model.KeepAlive;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.web.RequestParameter;
+import org.jboss.seam.international.StatusMessage;
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.bundle.Bundle;
+import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.criteria.BundleCriteria;
+import org.rhq.core.domain.criteria.BundleVersionCriteria;
+import org.rhq.core.domain.util.PageControl;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.core.gui.table.bean.AbstractPagedDataUIBean;
+import org.rhq.core.gui.table.model.PagedListDataModel;
+import org.rhq.enterprise.client.RemoteClient;
+import org.rhq.enterprise.server.bundle.BundleManagerRemote;
+import org.rhq.enterprise.server.perspective.AbstractPerspectivePagedDataUIBean;
+import org.rhq.enterprise.server.perspective.PerspectiveClientUIBean;
+
+import java.util.List;
+
+/**
+ * Provides details about a particular provisioning {@link Bundle bundle}, including CRUD operations on
+ * the {@link org.rhq.core.domain.bundle.BundleVersion version}s defined for that bundle. The backing bean for
+ * bundleDetails.xhtml.
+ *
+ * @author Ian Springer
+ */
+@Name("BundleDetailsUIBean")
+(a)Scope(ScopeType.EVENT)
+@KeepAlive
+public class BundleDetailsUIBean extends AbstractPerspectivePagedDataUIBean {
+ private List<BundleVersion> selectedBundleVersions;
+
+ @RequestParameter
+ private int bundleId;
+
+ private Bundle bundle;
+
+ public Bundle getBundle() {
+ if (this.bundle == null) {
+ this.bundle = loadBundle();
+ }
+ return this.bundle;
+ }
+
+ @Override
+ public PagedListDataModel createDataModel() {
+ return new DataModel(this);
+ }
+
+ public List<BundleVersion> getSelectedBundleVersions() {
+ return this.selectedBundleVersions;
+ }
+
+ public void setSelectedBundleVersions(List<BundleVersion> selectedBundleVersions) {
+ this.selectedBundleVersions = selectedBundleVersions;
+ }
+
+ public void deleteSelectedBundles() throws Exception {
+ RemoteClient remoteClient;
+ Subject subject;
+ try {
+ remoteClient = this.perspectiveClient.getRemoteClient();
+ subject = this.perspectiveClient.getSubject();
+ } catch (Exception e) {
+ this.facesMessages.add(StatusMessage.Severity.FATAL, "Failed to connect to RHQ Server - cause: " + e);
+ return;
+ }
+
+ // ***NOTE***: The javassist.NotFoundException stack traces that are logged by this call can be ignored.
+ BundleManagerRemote bundleManager = remoteClient.getBundleManagerRemote();
+
+ int[] selectedBundleVersionIds = new int[this.selectedBundleVersions.size()];
+ for (int i = 0, selectedBundlesSize = this.selectedBundleVersions.size(); i < selectedBundlesSize; i++) {
+ BundleVersion selectedBundleVersion = this.selectedBundleVersions.get(i);
+ selectedBundleVersionIds[i] = selectedBundleVersion.getId();
+ }
+
+ bundleManager.deleteBundleVersions(subject, selectedBundleVersionIds);
+
+ // Add message to tell the user the uninventory was a success.
+ String pluralizer = (this.selectedBundleVersions.size() == 1) ? "" : "s";
+ this.facesMessages.add("Deleted " + this.selectedBundleVersions.size() + " bundle version" + pluralizer + ".");
+
+ // Reset the data model, so the current page will get refreshed to reflect the Resources we just uninventoried.
+ // This is essential, since we are CONVERSATION-scoped and will live on beyond this request.
+ setDataModel(null);
+ }
+
+ private Bundle loadBundle() {
+ BundleManagerRemote bundleManager;
+ Subject subject;
+ try {
+ bundleManager = this.perspectiveClient.getRemoteClient().getBundleManagerRemote();
+ subject = this.perspectiveClient.getSubject();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ BundleCriteria bundleCriteria = new BundleCriteria();
+ bundleCriteria.addFilterId(this.bundleId);
+ PageList<Bundle> bundles = bundleManager.findBundlesByCriteria(subject, bundleCriteria);
+ if (bundles.isEmpty()) {
+ throw new IllegalStateException("Bundle with id " + this.bundleId + " not found.");
+ }
+ return bundles.get(0);
+ }
+
+ private class DataModel extends PagedListDataModel<BundleVersion> {
+ private DataModel(AbstractPagedDataUIBean pagedDataBean) {
+ super(pagedDataBean);
+ }
+
+ @Override
+ public PageList<BundleVersion> fetchPage(PageControl pageControl) {
+ PerspectiveClientUIBean perspectiveClient = BundleDetailsUIBean.this.perspectiveClient;
+ BundleManagerRemote bundleManager;
+ Subject subject;
+ try {
+ bundleManager = perspectiveClient.getRemoteClient().getBundleManagerRemote();
+ subject = BundleDetailsUIBean.this.perspectiveClient.getSubject();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ BundleVersionCriteria bundleVersionCriteria = new BundleVersionCriteria();
+ String bundleName = BundleDetailsUIBean.this.getBundle().getName();
+ bundleVersionCriteria.setPageControl(pageControl);
+ bundleVersionCriteria.addFilterBundleName(bundleName);
+ // TODO: Implement user-specified filters.
+ PageList<BundleVersion> bundleVersions = bundleManager.findBundleVersionsByCriteria(subject,
+ bundleVersionCriteria);
+ return bundleVersions;
+ }
+ }
+}
\ No newline at end of file
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java
index 1cc14dd..3cd1959 100644
--- a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java
@@ -110,7 +110,8 @@ public class BundlesUIBean extends AbstractPerspectivePagedDataUIBean {
}
BundleCriteria bundleCriteria = new BundleCriteria();
- // TODO: Implement filtering.
+ bundleCriteria.setPageControl(pageControl);
+ // TODO: Implement user-specified filters.
PageList<Bundle> bundles = bundleManager.findBundlesByCriteria(subject, bundleCriteria);
return bundles;
}
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundleDetails.xhtml b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundleDetails.xhtml
new file mode 100644
index 0000000..64d78bd
--- /dev/null
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundleDetails.xhtml
@@ -0,0 +1,105 @@
+<?xml version="1.0"?>
+
+<ui:composition
+ template="/WEB-INF/templates/mainTemplate.xhtml"
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:fn="http://java.sun.com/jsp/jstl/functions"
+ xmlns:a4j="http://richfaces.org/a4j"
+ xmlns:rich="http://richfaces.org/rich"
+ xmlns:rhq="http://rhq-project.org/rhq"
+ xmlns:onc="http://jboss.org/on/component">
+
+ <ui:param name="bundle" value="#{BundleDetailsUIBean.bundle}"/>
+
+ <ui:define name="breadcrumbs">
+ Administration >
+ <h:outputLink value="bundles.seam">Provisioning Bundles</h:outputLink> >
+ #{bundle.bundleType.name} Bundle '#{bundle.name}'
+ </ui:define>
+
+ <ui:define name="body">
+
+ <div><h:panelGroup layout="block" rendered="#{ServerInfoUIBean.debugModeEnabled}">
+ <b>Id:</b> #{bundle.id}
+ </h:panelGroup></div>
+ <div><h:panelGroup layout="block">
+ <b>Name:</b> #{bundle.name}
+ </h:panelGroup></div>
+ <div><h:panelGroup layout="block">
+ <b>Type:</b> #{bundle.bundleType.name}
+ </h:panelGroup></div>
+
+ <ui:remove><!-- NOTE: The table needs to be surrounded by a form for paging and sorting to work! --></ui:remove>
+ <a4j:form ajaxSubmit="false" reRender="bundlesVersionsDataTable">
+
+ <f:param name="bundleId" value="#{bundleId}"/>
+
+ <rich:dataTable id="bundleVersionsDataTable"
+ value="#{BundleDetailsUIBean.dataModel}" var="bundleVersion"
+ first="#{BundleDetailsUIBean.pageControl.pageNumber}"
+ rows="#{BundleDetailsUIBean.pageControl.pageSize}"
+ sortMode="multi"
+ width="100%">
+
+ <f:facet name="header">
+ <h:outputText value="Versions"/>
+ </f:facet>
+
+ <rich:column width="20">
+ <f:facet name="header">
+ <rhq:allRowsSelector/>
+ </f:facet>
+ <rhq:rowSelector value="#{BundleDetailsUIBean.selectedBundleVersions}"/>
+ </rich:column>
+
+ <rich:column width="70">
+ <f:facet name="header">
+ <rhq:sortableColumnHeader sortBy="BundleVersion.version">
+ <a4j:support event="onclick"
+ actionListener="#{BundleDetailsUIBean.ajaxSortListener}"/>
+ <h:outputText value="Version"/>
+ </rhq:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{bundleVersion.version}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <rhq:sortableColumnHeader sortBy="BundleVersion.name">
+ <a4j:support event="onclick"
+ actionListener="#{BundleDetailsUIBean.ajaxSortListener}"/>
+ <h:outputText value="Name"/>
+ </rhq:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputLink value="bundleDeploymentDefinitions.seam">
+ <f:param name="bundleVersionId" value="#{bundleVersion.id}"/>
+ <h:outputText value="#{bundleVersion.name}"/>
+ </h:outputLink>
+ </rich:column>
+
+ <f:facet name="footer">
+ <rich:columnGroup>
+ <rich:column colspan="3">
+ <rhq:selectedRowsCommandButton
+ value="DELETE"
+ action="#{BundleDetailsUIBean.deleteSelectedBundleVersions}"/>
+
+ <ui:include src="/WEB-INF/includes/pageControls.xhtml">
+ <ui:param name="pagedDataUIBean" value="#{BundleDetailsUIBean}"/>
+ <ui:param name="dataTableName" value="bundleVersionsDataTable"/>
+ </ui:include>
+ </rich:column>
+ </rich:columnGroup>
+ </f:facet>
+ </rich:dataTable>
+ </a4j:form>
+
+ </ui:define>
+
+</ui:composition>
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml
index cf34d97..8c9b809 100644
--- a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml
@@ -11,12 +11,11 @@
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
xmlns:rhq="http://rhq-project.org/rhq"
- xmlns:onc="http://jboss.org/on/component">
-
- <ui:param name="pageTitle" value="Provisioning Bundles"/>
+ xmlns:onc="http://jboss.org/on/component">
<ui:define name="breadcrumbs">
- <h:outputText value="Provisioning Bundles"/>
+ Administration >
+ Provisioning Bundles
</ui:define>
<ui:define name="body">
@@ -40,14 +39,14 @@
<rich:column width="235">
<f:facet name="header">
- <rhq:sortableColumnHeader sortBy="b.name">
+ <rhq:sortableColumnHeader sortBy="Bundle.name">
<a4j:support event="onclick"
actionListener="#{BundlesUIBean.ajaxSortListener}"/>
<h:outputText value="Name"/>
</rhq:sortableColumnHeader>
</f:facet>
- <h:outputLink value="bundleVersions.seam">
+ <h:outputLink value="bundleDetails.seam">
<f:param name="bundleId" value="#{bundle.id}"/>
<h:outputText value="#{bundle.name}"/>
</h:outputLink>
@@ -55,7 +54,7 @@
<rich:column>
<f:facet name="header">
- <rhq:sortableColumnHeader sortBy="b.bundleType.name">
+ <rhq:sortableColumnHeader sortBy="Bundle.bundleType.name">
<a4j:support event="onclick"
actionListener="#{BundlesUIBean.ajaxSortListener}"/>
<h:outputText value="Type"/>
diff --git a/modules/enterprise/server/plugins/perspectives/policy/perspective/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/perspectives/policy/perspective/src/main/resources/META-INF/rhq-serverplugin.xml
index 6053d09..ded5e86 100644
--- a/modules/enterprise/server/plugins/perspectives/policy/perspective/src/main/resources/META-INF/rhq-serverplugin.xml
+++ b/modules/enterprise/server/plugins/perspectives/policy/perspective/src/main/resources/META-INF/rhq-serverplugin.xml
@@ -19,7 +19,7 @@
<!-- Administration > Provisioning -->
<menu-item
name="administration.provisioning"
- displayName="Provisioning"
+ displayName="Provisioning Bundles"
application="policy"
url="bundles.seam">
<position
commit 4c95a2fada6ade201ee88006be2280fb5ba7dcf5
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Mon Feb 15 10:15:30 2010 -0500
get rid of calls to t.printStackTrace() - use logging instead
diff --git a/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClientProxy.java b/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClientProxy.java
index 36dbf2b..a1ecc61 100644
--- a/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClientProxy.java
+++ b/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClientProxy.java
@@ -30,6 +30,8 @@ import javassist.CtNewMethod;
import javassist.NotFoundException;
import javassist.bytecode.ParameterAnnotationsAttribute;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.jboss.remoting.invocation.NameBasedInvocation;
import org.rhq.core.domain.auth.Subject;
@@ -39,11 +41,11 @@ import org.rhq.core.domain.util.serial.ExternalizableStrategy;
* This class acts as a local SLSB proxy to make remote invocations
* to SLSB Remotes over a remoting invoker.
*
- *
* @author Greg Hinkle
*/
@SuppressWarnings("unchecked")
public class RemoteClientProxy implements InvocationHandler {
+ private static final Log LOG = LogFactory.getLog(RemoteClientProxy.class);
private RemoteClient client;
private RemoteClient.Manager manager;
@@ -78,13 +80,14 @@ public class RemoteClientProxy implements InvocationHandler {
String simpleName = intf.getName() + "Simple";
try {
+ @SuppressWarnings({"UnusedDeclaration"})
CtClass cached = cp.get(simpleName);
return Class.forName(simpleName, false, cp.getClassLoader());
} catch (NotFoundException e) {
// ok... load it
} catch (ClassNotFoundException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ LOG.debug("Class [" + simpleName + "] not found - cause: " + e);
}
CtClass cc = cp.get(intf.getName());
@@ -121,11 +124,10 @@ public class RemoteClientProxy implements InvocationHandler {
.getAnnotations();
javassist.bytecode.annotation.Annotation[][] newAnnotations = new javassist.bytecode.annotation.Annotation[originalAnnotations.length - 1][];
- int i = 1;
- for (int x = 1; x < originalAnnotations.length; x++) {
- newAnnotations[x - 1] = new javassist.bytecode.annotation.Annotation[originalAnnotations[x].length];
- System.arraycopy(originalAnnotations[x], 0, newAnnotations[x - 1], 0,
- originalAnnotations[x].length);
+ for (int i = 1; i < originalAnnotations.length; i++) {
+ newAnnotations[i - 1] = new javassist.bytecode.annotation.Annotation[originalAnnotations[i].length];
+ System.arraycopy(originalAnnotations[i], 0, newAnnotations[i - 1], 0,
+ originalAnnotations[i].length);
}
ParameterAnnotationsAttribute newAnnotationsAttribute = new ParameterAnnotationsAttribute(
@@ -144,9 +146,9 @@ public class RemoteClientProxy implements InvocationHandler {
return cz.toClass();
} catch (NotFoundException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ LOG.debug("Failed to simplify " + intf + " - cause: " + e);
} catch (CannotCompileException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ LOG.error("Failed to simplify " + intf + ".", e);
}
return intf;
}
@@ -164,7 +166,7 @@ public class RemoteClientProxy implements InvocationHandler {
try {
Class[] interfaces = method.getDeclaringClass().getInterfaces();
- Class originalClass = null;
+ Class originalClass;
if (interfaces != null && interfaces.length > 0) {
originalClass = interfaces[0];
} else {
@@ -215,5 +217,4 @@ public class RemoteClientProxy implements InvocationHandler {
}
return paramSig;
}
-
}
commit e2209f9015bb1f29eed75674fc2c1e5147c63c84
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 15 11:52:23 2010 -0500
Fix up BundleTest
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
index 0cb550a..783b707 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
@@ -50,9 +50,12 @@ import javax.xml.bind.annotation.XmlAccessorType;
*/
@Entity
@NamedQueries( {
- @NamedQuery(name = Bundle.QUERY_FIND_ALL, query = "SELECT b FROM Bundle b"), //
- @NamedQuery(name = Bundle.QUERY_FIND_BY_TYPE_AND_NAME, query = "SELECT b FROM Bundle b WHERE " +
- "(:type = b.bundleType.name OR :type IS NULL) AND (:name = b.name OR :name IS NULL)")
+ // Below queries primarily used for domain test code.
+ @NamedQuery(name = Bundle.QUERY_FIND_ALL, query = "SELECT b FROM Bundle b"), //
+ @NamedQuery(name = Bundle.QUERY_FIND_BY_NAME, query = "SELECT b FROM Bundle b WHERE :name = b.name"),
+ @NamedQuery(name = Bundle.QUERY_FIND_BY_TYPE_AND_NAME, query = "SELECT b FROM Bundle b WHERE "
+ + "(:type = b.bundleType.name OR :type IS NULL) AND (:name = b.name OR :name IS NULL)")
+
})
@SequenceGenerator(name = "SEQ", sequenceName = "RHQ_BUNDLE_ID_SEQ")
@Table(name = "RHQ_BUNDLE")
@@ -61,6 +64,7 @@ public class Bundle implements Serializable {
private static final long serialVersionUID = 1L;
public static final String QUERY_FIND_ALL = "Bundle.findAll";
+ public static final String QUERY_FIND_BY_NAME = "Bundle.findByName";
public static final String QUERY_FIND_BY_TYPE_AND_NAME = "Bundle.findByTypeAndName";
@Column(name = "ID", nullable = false)
diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/bundle/test/BundleTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/bundle/test/BundleTest.java
index e229fef..83b9f9f 100644
--- a/modules/core/domain/src/test/java/org/rhq/core/domain/bundle/test/BundleTest.java
+++ b/modules/core/domain/src/test/java/org/rhq/core/domain/bundle/test/BundleTest.java
@@ -42,6 +42,7 @@ import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.test.AbstractEJB3Test;
@Test
+@SuppressWarnings("unchecked")
public class BundleTest extends AbstractEJB3Test {
public void testBundleVersionRepo() throws Throwable {
getTransactionManager().begin();
@@ -50,7 +51,7 @@ public class BundleTest extends AbstractEJB3Test {
int id;
String name = "BundleTest-testBundleVersionRepo";
- String action = "action/script/recipe is here";
+ String recipe = "action/script/recipe is here";
Repo repo1 = new Repo(name + "-Repo1");
Repo repo2 = new Repo(name + "-Repo2");
@@ -65,11 +66,10 @@ public class BundleTest extends AbstractEJB3Test {
q.setParameter("id", repo2.getId());
assert q.getResultList().size() == 0 : "should not have repo2 mapping in the db yet";
- BundleType bundleType = new BundleType(name + "-Type", createResourceType(em));
+ BundleType bundleType = createBundleType(em, name + "-Type", createResourceType(em));
Bundle bundle = new Bundle(name + "-Bundle", bundleType);
em.persist(bundle);
- BundleVersion bundleVersion = new BundleVersion(name, "1.0.0.BETA", bundle);
- bundleVersion.setAction(action);
+ BundleVersion bundleVersion = new BundleVersion(name, "1.0.0.BETA", bundle, recipe);
em.persist(bundleVersion);
id = bundleVersion.getId();
assert id > 0;
@@ -127,17 +127,16 @@ public class BundleTest extends AbstractEJB3Test {
int id;
String name = "BundleTest-testBundleVersion";
- String action = "action/script/recipe is here";
+ String recipe = "action/script/recipe is here";
- BundleType bundleType = new BundleType(name + "-Type", createResourceType(em));
+ BundleType bundleType = createBundleType(em, name + "-Type", createResourceType(em));
Bundle bundle = new Bundle(name + "-Bundle", bundleType);
em.persist(bundle);
id = bundle.getId();
assert id > 0;
assert bundle.getBundleType().getId() != 0 : "bundleType should have been cascade persisted too";
- BundleVersion bv = new BundleVersion(name, "1.0.0.BETA", bundle);
- bv.setAction(action);
+ BundleVersion bv = new BundleVersion(name, "1.0.0.BETA", bundle, recipe);
Query q = em.createNamedQuery(BundleVersion.QUERY_FIND_BY_NAME);
q.setParameter("name", bv.getName());
assert q.getResultList().size() == 0; // not in the db yet
@@ -148,6 +147,7 @@ public class BundleTest extends AbstractEJB3Test {
q = em.createNamedQuery(BundleVersion.QUERY_FIND_BY_NAME);
q.setParameter("name", bv.getName());
+ q.setParameter("name", bv.getName());
assert q.getResultList().size() == 1;
assert ((BundleVersion) q.getSingleResult()).getName().equals(bv.getName());
@@ -156,7 +156,7 @@ public class BundleTest extends AbstractEJB3Test {
assert bvFind.getId() == bv.getId();
assert bvFind.getName().equals(bv.getName());
assert bvFind.getVersion().equals(bv.getVersion());
- assert bvFind.getAction().equals(bv.getAction());
+ assert bvFind.getRecipe().equals(bv.getRecipe());
assert bvFind.getBundle().equals(bv.getBundle());
assert bvFind.equals(bv);
assert bvFind.hashCode() == bv.hashCode();
@@ -234,7 +234,7 @@ public class BundleTest extends AbstractEJB3Test {
q.setParameter("name", name);
assert q.getResultList().size() == 0; // not in the db yet
- BundleType bundleType = new BundleType(name + "-Type", createResourceType(em));
+ BundleType bundleType = createBundleType(em, name + "-Type", createResourceType(em));
Bundle b = new Bundle(name, bundleType);
em.persist(b);
@@ -307,9 +307,8 @@ public class BundleTest extends AbstractEJB3Test {
q.setParameter("name", name);
assert q.getResultList().size() == 0; // not in the db yet
- BundleType bt = new BundleType(name, createResourceType(em));
+ BundleType bt = createBundleType(em, name, createResourceType(em));
- em.persist(bt);
id = bt.getId();
assert id > 0;
@@ -357,6 +356,12 @@ public class BundleTest extends AbstractEJB3Test {
return rt;
}
+ private BundleType createBundleType(EntityManager em, String name, ResourceType rt) throws Exception {
+ BundleType bt = new BundleType(name, rt);
+ em.persist(bt);
+ return bt;
+ }
+
private ResourceType deleteResourceType(EntityManager em, ResourceType rt) {
rt = em.find(ResourceType.class, rt.getId());
em.remove(rt);
commit 6b3a0e331baa5a4bee4b6356555058fce2b24aba
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 15 11:10:53 2010 -0500
Add test for BundleVersionCriteria search.
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
index 155eca6..4003c40 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
@@ -183,7 +183,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
assertEquals(b, bv.getBundle());
}
- @Test(enabled = false)
+ @Test(enabled = ENABLED)
public void testfindBundleVersionsByCriteria() throws Exception {
Bundle b1 = createBundle("one");
BundleVersion bv1 = createBundleVersion(b1.getName(), "1.0", b1);
@@ -215,7 +215,8 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
assertEquals(bv2, bv);
assertEquals(bv.getBundle(), b1);
assertNull(bv.getDistribution());
- assertNull(bv.getBundleDeployDefinitions());
+ assertNotNull(bv.getBundleDeployDefinitions());
+ assertTrue(bv.getBundleDeployDefinitions().isEmpty());
}
private BundleType createBundleType(String name) throws Exception {
commit 4df3bcecbbc460a596784819356832cf70455c9c
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 15 11:10:34 2010 -0500
bundle field is lazy loaded so remove bundle field from hashcode/equals.
Name+Version should be a sufficient key.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java
index 7bc3dea..125baa7 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java
@@ -193,7 +193,6 @@ public class BundleVersion implements Serializable {
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((version == null) ? 0 : version.hashCode());
- result = prime * result + ((bundle == null) ? 0 : bundle.hashCode());
return result;
}
@@ -224,14 +223,6 @@ public class BundleVersion implements Serializable {
return false;
}
- if (bundle == null) {
- if (other.bundle != null) {
- return false;
- }
- } else if (!bundle.equals(other.bundle)) {
- return false;
- }
-
return true;
}
}
\ No newline at end of file
commit 4450158f44bf351a4aa820f8925899f07c010106
Merge: 712ba06... b6a25ca...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 15 09:42:37 2010 -0500
Merge branch 'bundle' into bundle-jay
Conflicts:
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
diff --cc modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java
index 471b0d6,19d17c2..7c95fdd
--- 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
@@@ -18,17 -18,8 +18,19 @@@
*/
package org.rhq.enterprise.server.bundle;
+import java.util.List;
++import java.util.Random;
++import java.util.UUID;
+
+import javax.ejb.EJB;
+import javax.ejb.Stateless;
+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.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
@@@ -38,8 -29,9 +40,10 @@@ import org.rhq.core.domain.bundle.Bundl
import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleDeployDefinitionCriteria;
import org.rhq.core.domain.criteria.BundleDeploymentCriteria;
+import org.rhq.core.domain.criteria.BundleVersionCriteria;
+ import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.util.PageList;
+ import org.rhq.core.domain.util.PersistenceUtility;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.authz.AuthorizationManagerLocal;
import org.rhq.enterprise.server.authz.PermissionException;
@@@ -113,19 -118,51 +121,59 @@@ public class BundleManagerBean implemen
return queryRunner.execute();
}
+ public PageList<BundleVersion> findBundleVersionsByCriteria(Subject subject, BundleVersionCriteria criteria) {
+ CriteriaQueryGenerator generator = new CriteriaQueryGenerator(criteria);
+
+ CriteriaQueryRunner<BundleVersion> queryRunner = new CriteriaQueryRunner<BundleVersion>(criteria, generator,
+ entityManager);
+ return queryRunner.execute();
+ }
+
public PageList<Bundle> findBundlesByCriteria(Subject subject, BundleCriteria criteria) {
- Query totalCountQuery = PersistenceUtility.createCountQuery(entityManager,
- Bundle.QUERY_FIND_ALL);
++ Query totalCountQuery = PersistenceUtility.createCountQuery(entityManager, Bundle.QUERY_FIND_ALL);
+ long totalCount = (Long) totalCountQuery.getSingleResult();
+ if (totalCount == 0) {
+ List<BundleType> bundleTypes = getAllBundleTypes(subject);
+ for (int i = 0; i < 50; i++) {
+ createMockBundle(subject, bundleTypes);
+ }
+ }
+
CriteriaQueryGenerator generator = new CriteriaQueryGenerator(criteria);
CriteriaQueryRunner<Bundle> queryRunner = new CriteriaQueryRunner<Bundle>(criteria, generator, entityManager);
return queryRunner.execute();
}
+ public PageList<BundleDeployment> findBundleDeploymentsByCriteria(BundleDeploymentCriteria criteria) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void deleteBundles(Subject subject, int[] bundleIds) {
+ for (int bundleId : bundleIds) {
+ Bundle bundle = this.entityManager.find(Bundle.class, bundleId);
+ this.entityManager.remove(bundle);
+ }
+ }
+
+ public BundleType createMockBundleType(Subject subject) {
- ResourceType linuxPlatformResourceType = this.resourceTypeManager.getResourceTypeByNameAndPlugin("Linux", "Platforms");
++ ResourceType linuxPlatformResourceType = this.resourceTypeManager.getResourceTypeByNameAndPlugin("Linux",
++ "Platforms");
+ BundleType bundleType = new BundleType(UUID.randomUUID().toString(), linuxPlatformResourceType);
+ return createBundleType(subject, bundleType);
+ }
+
+ public Bundle createMockBundle(Subject subject, List<BundleType> bundleTypes) {
+ BundleType bundleType;
+ if (bundleTypes.isEmpty()) {
+ bundleType = createMockBundleType(subject);
+ } else {
+ Random random = new Random();
+ int randomIndex = random.nextInt(bundleTypes.size());
+ bundleType = bundleTypes.get(randomIndex);
+ }
+ Bundle bundle = new Bundle(UUID.randomUUID().toString(), bundleType);
+ return createBundle(subject, bundle);
+ }
}
commit 712ba06393292d96353700d3ed347e9483c3a256
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 15 09:33:05 2010 -0500
More work on criteria search for bundle domain
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleVersionCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleVersionCriteria.java
new file mode 100644
index 0000000..72c07ed
--- /dev/null
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleVersionCriteria.java
@@ -0,0 +1,81 @@
+/*
+ * 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.core.domain.criteria;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.rhq.core.domain.bundle.BundleVersion;
+
+/**
+ * @author Jay Shaughnessy
+ */
+@XmlRootElement
+(a)XmlAccessorType(XmlAccessType.FIELD)
+@SuppressWarnings("unused")
+public class BundleVersionCriteria extends Criteria {
+ private static final long serialVersionUID = 1L;
+
+ private Integer filterId;
+ private String filterName;
+ private String filterVersion;
+ private String filterBundleName; // needs override
+
+ private boolean fetchBundle;
+ private boolean fetchBundleDeployDefinitions;
+ private boolean fetchDistribution;
+ private boolean fetchConfigurationDefinition;
+
+ public BundleVersionCriteria() {
+ super(BundleVersion.class);
+
+ filterOverrides.put("bundleName", "bundle.name like ?");
+ }
+
+ public void addFilterId(Integer filterId) {
+ this.filterId = filterId;
+ }
+
+ public void addFilterName(String filterName) {
+ this.filterName = filterName;
+ }
+
+ public void addFilterBundleName(String filterBundleName) {
+ this.filterBundleName = filterBundleName;
+ }
+
+ public void addFilterVersion(String filterVersion) {
+ this.filterVersion = filterVersion;
+ }
+
+ public void fetchBundle(boolean fetchBundle) {
+ this.fetchBundle = fetchBundle;
+ }
+
+ public void fetchDistribution(boolean fetchDistribution) {
+ this.fetchDistribution = fetchDistribution;
+ }
+
+ public void fetchBundleDeployDefinitions(boolean fetchBundleDeployDefinitions) {
+ this.fetchBundleDeployDefinitions = fetchBundleDeployDefinitions;
+ }
+
+}
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 c25c0b9..471b0d6 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
@@ -38,6 +38,7 @@ import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleDeployDefinitionCriteria;
import org.rhq.core.domain.criteria.BundleDeploymentCriteria;
+import org.rhq.core.domain.criteria.BundleVersionCriteria;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.authz.AuthorizationManagerLocal;
@@ -112,6 +113,14 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
return queryRunner.execute();
}
+ public PageList<BundleVersion> findBundleVersionsByCriteria(Subject subject, BundleVersionCriteria criteria) {
+ CriteriaQueryGenerator generator = new CriteriaQueryGenerator(criteria);
+
+ CriteriaQueryRunner<BundleVersion> queryRunner = new CriteriaQueryRunner<BundleVersion>(criteria, generator,
+ entityManager);
+ return queryRunner.execute();
+ }
+
public PageList<Bundle> findBundlesByCriteria(Subject subject, BundleCriteria criteria) {
CriteriaQueryGenerator generator = new CriteriaQueryGenerator(criteria);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
index ee808d0..33afd50 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
@@ -31,6 +31,7 @@ import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleDeployDefinitionCriteria;
import org.rhq.core.domain.criteria.BundleDeploymentCriteria;
+import org.rhq.core.domain.criteria.BundleVersionCriteria;
import org.rhq.core.domain.util.PageList;
/**
@@ -58,6 +59,8 @@ public interface BundleManagerLocal {
PageList<BundleDeployment> findBundleDeploymentsByCriteria(Subject subject, BundleDeploymentCriteria criteria);
+ PageList<BundleVersion> findBundleVersionsByCriteria(Subject subject, BundleVersionCriteria criteria);
+
PageList<Bundle> findBundlesByCriteria(Subject subject, BundleCriteria criteria);
List<BundleType> getAllBundleTypes(Subject subject);
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
index 35666db..155eca6 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
@@ -36,6 +36,7 @@ import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.criteria.BundleCriteria;
+import org.rhq.core.domain.criteria.BundleVersionCriteria;
import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.util.PageList;
@@ -45,7 +46,7 @@ import org.rhq.enterprise.server.util.LookupUtil;
/**
* @author John Mazzitelli
*/
-@SuppressWarnings("unchecked")
+@SuppressWarnings( { "unchecked", "unused" })
@Test
public class BundleManagerBeanTest extends AbstractEJB3Test {
@@ -167,6 +168,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
// return bundle "two" using all criteria and with all optional data
c.addFilterId(b.getId());
c.addFilterName(b.getName());
+ c.addFilterBundleTypeName(b.getName());
c.fetchBundleVersions(true);
bundles = bundleManagerBean.findBundlesByCriteria(getOverlord(), c);
assertNotNull(bundles);
@@ -181,6 +183,41 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
assertEquals(b, bv.getBundle());
}
+ @Test(enabled = false)
+ public void testfindBundleVersionsByCriteria() throws Exception {
+ Bundle b1 = createBundle("one");
+ BundleVersion bv1 = createBundleVersion(b1.getName(), "1.0", b1);
+ BundleVersion bv2 = createBundleVersion(b1.getName(), "2.0", b1);
+ BundleVersion bv3 = createBundleVersion(b1.getName(), "2.1", b1);
+ BundleVersionCriteria c = new BundleVersionCriteria();
+ PageList<BundleVersion> bvs = null;
+ BundleVersion bv = null;
+
+ // return all with no optional data
+ bvs = bundleManagerBean.findBundleVersionsByCriteria(getOverlord(), c);
+ bv = bvs.get(1);
+ assertNotNull(bvs);
+ assertEquals(3, bvs.size());
+ assertEquals(bv2, bv);
+
+ // return bundle version using all criteria and with all optional data
+ c.addFilterId(bv.getId());
+ c.addFilterName(bv.getName());
+ c.addFilterBundleName("one");
+ c.addFilterVersion(bv.getVersion());
+ c.fetchBundle(true);
+ c.fetchDistribution(true);
+ c.fetchBundleDeployDefinitions(true);
+ bvs = bundleManagerBean.findBundleVersionsByCriteria(getOverlord(), c);
+ assertNotNull(bvs);
+ assertEquals(1, bvs.size());
+ bv = bvs.get(0);
+ assertEquals(bv2, bv);
+ assertEquals(bv.getBundle(), b1);
+ assertNull(bv.getDistribution());
+ assertNull(bv.getBundleDeployDefinitions());
+ }
+
private BundleType createBundleType(String name) throws Exception {
final String fullName = TEST_PREFIX + "-type-" + name;
BundleType bt = new BundleType(fullName, createResourceType(name));
commit 79f799ed6bb0514c23ee469c9cf03dc24242b4ae
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 15 09:32:19 2010 -0500
Added access to deploy defs
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java
index 202eeac..7bc3dea 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java
@@ -23,6 +23,8 @@
package org.rhq.core.domain.bundle;
import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
@@ -35,6 +37,7 @@ import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
+import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlAccessType;
@@ -88,6 +91,9 @@ public class BundleVersion implements Serializable {
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private ConfigurationDefinition configurationDefinition;
+ @OneToMany(mappedBy = "bundleVersion", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
+ private List<BundleDeployDefinition> bundleDeployDefinitions = new ArrayList<BundleDeployDefinition>();
+
public BundleVersion() {
// for JPA use
}
@@ -163,6 +169,19 @@ public class BundleVersion implements Serializable {
this.configurationDefinition = configurationDefinition;
}
+ public List<BundleDeployDefinition> getBundleDeployDefinitions() {
+ return bundleDeployDefinitions;
+ }
+
+ public void addBundleDeployDefinition(BundleDeployDefinition bundleDeployDefinition) {
+ this.bundleDeployDefinitions.add(bundleDeployDefinition);
+ bundleDeployDefinition.setBundleVersion(this);
+ }
+
+ public void setBundleDeployDefinitions(List<BundleDeployDefinition> bundleDeployDefinitions) {
+ this.bundleDeployDefinitions = bundleDeployDefinitions;
+ }
+
@Override
public String toString() {
return "BundleVersion[id=" + id + ",name=" + name + ",version=" + version + ",bundle=" + bundle + "]";
commit fdaa9f42925f293aaa36004a69f6d1f492a91970
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 15 09:31:47 2010 -0500
Added filters for bundle type
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java
index d446891..5c40cd0 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java
@@ -35,18 +35,31 @@ public class BundleCriteria extends Criteria {
private static final long serialVersionUID = 1L;
private Integer filterId;
+ private Integer filterBundleTypeId; // needs override
+ private String filterBundleTypeName; // needs override
private String filterName;
private boolean fetchBundleVersions;
public BundleCriteria() {
super(Bundle.class);
+
+ filterOverrides.put("bundleTypeId", "bundleType.id = ?");
+ filterOverrides.put("bundleTypeName", "bundleType.name like ?");
}
public void addFilterId(Integer filterId) {
this.filterId = filterId;
}
+ public void addFilterBundleTypeId(Integer filterBundleTypeId) {
+ this.filterBundleTypeId = filterBundleTypeId;
+ }
+
+ public void addFilterBundleTypeName(String filterBundleTypeName) {
+ this.filterName = filterBundleTypeName;
+ }
+
public void addFilterName(String filterName) {
this.filterName = filterName;
}
commit b6a25ca1049c094e09e8c24678cbf009de81f699
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Fri Feb 12 18:26:55 2010 -0500
deploy policy perspective by default; misc minor changes
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
index 0dc6eb9..beecf66 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
@@ -47,11 +47,11 @@ public interface BundleManagerLocal {
BundleVersion createBundleVersion(Subject subject, BundleVersion bundleVersion);
- // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
- // The following are shared with the Remote Interface
+ // The remaining methods are shared with the Remote Interface.
//
- // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
PageList<BundleDeployDefinition> findBundleDeployDefinitionsByCriteria(Subject subject,
BundleDeployDefinitionCriteria criteria);
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java
index 73b8026..1cc14dd 100644
--- a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java
@@ -1,3 +1,21 @@
+/*
+ * 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.server.perspective.policy;
import org.ajax4jsf.model.KeepAlive;
@@ -8,7 +26,6 @@ import org.jboss.seam.international.StatusMessage;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.criteria.BundleCriteria;
-import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.gui.table.bean.AbstractPagedDataUIBean;
@@ -17,12 +34,13 @@ import org.rhq.enterprise.client.RemoteClient;
import org.rhq.enterprise.server.bundle.BundleManagerRemote;
import org.rhq.enterprise.server.perspective.AbstractPerspectivePagedDataUIBean;
import org.rhq.enterprise.server.perspective.PerspectiveClientUIBean;
-import org.rhq.enterprise.server.resource.ResourceManagerRemote;
import java.util.List;
/**
- * Provides CRUD operations for provisioning {@link Bundle}s. The backing bean for bundles.xhtml.
+ * Provides CRUD operations on provisioning {@link Bundle}s. The backing bean for bundles.xhtml.
+ *
+ * @author Ian Springer
*/
@Name("BundlesUIBean")
@Scope(ScopeType.EVENT)
@@ -74,7 +92,6 @@ public class BundlesUIBean extends AbstractPerspectivePagedDataUIBean {
setDataModel(null);
}
-
private class DataModel extends PagedListDataModel<Bundle> {
private DataModel(AbstractPagedDataUIBean pagedDataBean) {
super(pagedDataBean);
commit a32d94232ca13734c93437ce4d69bfa715103af6
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Fri Feb 12 17:54:05 2010 -0500
change start() so it sets isStarted even if one or more perspectives fail to deploy - that way, the redeploy logic will call start() when a plugin is hot-deployed even if the initial call to start() failed to deploy one or more perspectives
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java
index 72d62b5..2d39f87 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java
@@ -99,12 +99,14 @@ public class PerspectivePluginMetadataManager {
// TODO: Init lists of global tasks and resource tasks.
this.pageLinks = new ArrayList<PageLink>();
- // Always process the Core perspective first as other perspectives may remove extensions it defines.
- processCorePerspective();
- processNonCorePerspectives();
-
- this.isStarted = true;
- this.lastModifiedTime = System.currentTimeMillis();
+ // Always process the Core perspective first, as other perspectives may remove extensions it defines.
+ try {
+ processCorePerspective();
+ processNonCorePerspectives();
+ } finally {
+ this.isStarted = true;
+ this.lastModifiedTime = System.currentTimeMillis();
+ }
}
public synchronized void stop() {
@@ -119,24 +121,26 @@ public class PerspectivePluginMetadataManager {
private void processCorePerspective() {
PerspectivePluginDescriptorType corePerspectiveDescriptor = this.loadedPlugins.get(CORE_PERSPECTIVE_NAME);
if (corePerspectiveDescriptor == null) {
- throw new IllegalStateException("Core perspective must be loaded. Invalid startup. Load: "
- + CORE_PERSPECTIVE_NAME);
+ throw new IllegalStateException("Core perspective is required but is missing.");
+ }
+ try {
+ processPerspective(corePerspectiveDescriptor);
+ } catch (Exception e) {
+ throw new IllegalStateException("Failed to load core perspective.", e);
}
- processPerspective(corePerspectiveDescriptor);
-
- // TODO: remove this debug code
- //printMenu(this.menu, "");
}
private void processNonCorePerspectives() {
- for (String key : this.loadedPlugins.keySet()) {
- if (!CORE_PERSPECTIVE_NAME.equals(key)) {
- processPerspective(this.loadedPlugins.get(key));
+ for (String perspectiveName : this.loadedPlugins.keySet()) {
+ if (!CORE_PERSPECTIVE_NAME.equals(perspectiveName)) {
+ PerspectivePluginDescriptorType pluginDescriptor = this.loadedPlugins.get(perspectiveName);
+ try {
+ processPerspective(pluginDescriptor);
+ } catch (Exception e) {
+ log.error("Failed to load perspective [" + perspectiveName + "].", e);
+ }
}
}
-
- // TODO: remove this debug code
- //printMenu(this.menu, "");
}
private void processPerspective(PerspectivePluginDescriptorType perspective) {
commit cd68ab94767f2561f5ea658739e2147db8d9473b
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Fri Feb 12 17:51:49 2010 -0500
add ability to exclude subsets of agent plugins from the reactor
diff --git a/modules/plugins/pom.xml b/modules/plugins/pom.xml
index 104a373..db7d4be 100644
--- a/modules/plugins/pom.xml
+++ b/modules/plugins/pom.xml
@@ -81,54 +81,106 @@
<modules>
<!-- core plugins -->
<module>platform</module>
- <module>jmx</module>
<module>rhq-agent</module>
- <module>apache</module>
- <module>iis</module>
- <module>database</module>
- <module>postgres</module>
-
- <!-- jboss plugins (order is important) -->
- <module>tomcat</module>
- <module>jboss-as</module>
- <module>hibernate</module>
- <module>rhq-server</module>
- <module>jboss-cache</module>
- <module>jboss-as-5</module>
- <module>jboss-cache-v3</module>
- <!-- was not in Jopr build at merge time <module>jbossOSGi</module> -->
-
- <!-- other, possibly experimental plugins -->
- <module>augeas</module>
- <module>cron</module>
- <module>script</module>
- <module>script2</module>
- <module>grub</module>
- <!-- not behaving <module>hardware</module> -->
- <module>hosts</module>
- <module>cobbler</module>
- <module>sudoers</module>
- <module>hudson</module>
- <!-- error in code generation (see RHQ-1225) <module>jira</module> -->
- <module>mysql</module>
- <module>netservices</module>
- <!-- non-public dependency <module>onewire</module> -->
- <module>oracle</module>
- <module>perftest</module>
- <module>samba</module>
- <module>postfix</module>
- <module>aliases</module>
- <module>snmptrapd</module>
- <module>sshd</module>
- <module>twitter</module>
- <module>virt</module>
- <module>kickstart</module>
-
- <!-- bundle plugins -->
- <module>filetemplate-bundle</module>
-
- <!-- make this the last - it will validate all the plugins -->
- <module>validate-all-plugins</module>
+ <module>jmx</module>
</modules>
+ <profiles>
+
+ <profile>
+ <id>jboss-plugins</id>
+ <activation>
+ <property>
+ <name>java.home</name>
+ </property>
+ </activation>
+
+ <modules>
+ <!-- NOTE: Order is important. -->
+ <module>augeas</module>
+ <module>apache</module>
+ <module>tomcat</module>
+ <module>jboss-as</module>
+ <module>hibernate</module>
+ <module>rhq-server</module>
+ <module>jboss-cache</module>
+ <module>jboss-as-5</module>
+ <module>jboss-cache-v3</module>
+ <!-- was not in Jopr build at merge time <module>jbossOSGi</module> -->
+ </modules>
+ </profile>
+
+ <profile>
+ <id>linux-plugins</id>
+ <activation>
+ <property>
+ <name>java.home</name>
+ </property>
+ </activation>
+
+ <modules>
+ <module>augeas</module>
+ <module>cron</module>
+ <module>script</module>
+ <module>script2</module>
+ <module>grub</module>
+ <!-- not behaving <module>hardware</module> -->
+ <module>hosts</module>
+ <module>cobbler</module>
+ <module>sudoers</module>
+ <module>hudson</module>
+ <module>netservices</module>
+ <module>perftest</module>
+ <module>samba</module>
+ <module>postfix</module>
+ <module>aliases</module>
+ <module>sshd</module>
+ <module>virt</module>
+ <module>kickstart</module>
+ </modules>
+ </profile>
+
+ <profile>
+ <id>misc-plugins</id>
+ <activation>
+ <property>
+ <name>java.home</name>
+ </property>
+ </activation>
+
+ <modules>
+ <module>iis</module>
+ <module>database</module>
+ <module>postgres</module>
+ <module>hudson</module>
+ <!-- error in code generation (see RHQ-1225) <module>jira</module> -->
+ <module>mysql</module>
+ <!-- non-public dependency <module>onewire</module> -->
+ <module>oracle</module>
+ <module>perftest</module>
+ <module>snmptrapd</module>
+ <module>twitter</module>
+
+ <!-- bundle plugins -->
+ <module>filetemplate-bundle</module>
+ </modules>
+ </profile>
+
+ <profile>
+ <id>validate-plugins</id>
+ <activation>
+ <property>
+ <name>java.home</name>
+ </property>
+ </activation>
+
+ <modules>
+ <!-- make this the last - it will validate all the plugins -->
+ <module>validate-all-plugins</module>
+ </modules>
+ </profile>
+
+ </profiles>
+
</project>
+
commit 0bc6fca702f94c3989e9917bb647054ddf965574
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Fri Feb 12 17:50:59 2010 -0500
more work on SLSB methods and perspective-based GUI for listing bundles
diff --git a/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml
index dff673e..e5dfb1d 100644
--- a/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml
+++ b/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml
@@ -293,8 +293,8 @@
placement="after" />
</menu-item>
<menu-item
- name="administration.download"
- displayName="Download"
+ name="administration.downloads"
+ displayName="Downloads"
iconUrl="/images/icons/Save_16.png"
url="/rhq/admin/downloads.xhtml">
<position
@@ -306,7 +306,7 @@
displayName="License"
url="/admin/license/LicenseAdmin.do?mode=view">
<position
- name="administration.download"
+ name="administration.downloads"
placement="after" />
<activators>
<global-permission
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java
index 10344d9..73b8026 100644
--- a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java
@@ -2,17 +2,22 @@ package org.rhq.enterprise.server.perspective.policy;
import org.ajax4jsf.model.KeepAlive;
import org.jboss.seam.ScopeType;
-import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.international.StatusMessage;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.Bundle;
+import org.rhq.core.domain.criteria.BundleCriteria;
+import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.gui.table.bean.AbstractPagedDataUIBean;
import org.rhq.core.gui.table.model.PagedListDataModel;
+import org.rhq.enterprise.client.RemoteClient;
import org.rhq.enterprise.server.bundle.BundleManagerRemote;
import org.rhq.enterprise.server.perspective.AbstractPerspectivePagedDataUIBean;
+import org.rhq.enterprise.server.perspective.PerspectiveClientUIBean;
+import org.rhq.enterprise.server.resource.ResourceManagerRemote;
import java.util.List;
@@ -23,18 +28,8 @@ import java.util.List;
@Scope(ScopeType.EVENT)
@KeepAlive
public class BundlesUIBean extends AbstractPerspectivePagedDataUIBean {
- private BundleManagerRemote bundleManager;
private List<Bundle> selectedBundles;
- @Create
- public void init() {
- try {
- this.bundleManager = this.perspectiveClient.getRemoteClient().getBundleManagerRemote();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
@Override
public PagedListDataModel createDataModel() {
return new DataModel(this);
@@ -48,6 +43,38 @@ public class BundlesUIBean extends AbstractPerspectivePagedDataUIBean {
this.selectedBundles = selectedResources;
}
+ public void deleteSelectedBundles() throws Exception {
+ RemoteClient remoteClient;
+ Subject subject;
+ try {
+ remoteClient = this.perspectiveClient.getRemoteClient();
+ subject = this.perspectiveClient.getSubject();
+ } catch (Exception e) {
+ this.facesMessages.add(StatusMessage.Severity.FATAL, "Failed to connect to RHQ Server - cause: " + e);
+ return;
+ }
+
+ // ***NOTE***: The javassist.NotFoundException stack traces that are logged by this call can be ignored.
+ BundleManagerRemote bundleManager = remoteClient.getBundleManagerRemote();
+
+ int[] selectedBundleIds = new int[this.selectedBundles.size()];
+ for (int i = 0, selectedBundlesSize = this.selectedBundles.size(); i < selectedBundlesSize; i++) {
+ Bundle selectedBundle = this.selectedBundles.get(i);
+ selectedBundleIds[i] = selectedBundle.getId();
+ }
+
+ bundleManager.deleteBundles(subject, selectedBundleIds);
+
+ // Add message to tell the user the uninventory was a success.
+ String pluralizer = (this.selectedBundles.size() == 1) ? "" : "s";
+ this.facesMessages.add("Deleted " + this.selectedBundles.size() + " bundle" + pluralizer + ".");
+
+ // Reset the data model, so the current page will get refreshed to reflect the Resources we just uninventoried.
+ // This is essential, since we are CONVERSATION-scoped and will live on beyond this request.
+ setDataModel(null);
+ }
+
+
private class DataModel extends PagedListDataModel<Bundle> {
private DataModel(AbstractPagedDataUIBean pagedDataBean) {
super(pagedDataBean);
@@ -55,14 +82,19 @@ public class BundlesUIBean extends AbstractPerspectivePagedDataUIBean {
@Override
public PageList<Bundle> fetchPage(PageControl pageControl) {
+ PerspectiveClientUIBean perspectiveClient = BundlesUIBean.this.perspectiveClient;
+ BundleManagerRemote bundleManager;
Subject subject;
try {
+ bundleManager = perspectiveClient.getRemoteClient().getBundleManagerRemote();
subject = BundlesUIBean.this.perspectiveClient.getSubject();
} catch (Exception e) {
throw new RuntimeException(e);
}
+
+ BundleCriteria bundleCriteria = new BundleCriteria();
// TODO: Implement filtering.
- PageList<Bundle> bundles = BundlesUIBean.this.bundleManager.findBundlesByCriteria(subject, null, null, pageControl);
+ PageList<Bundle> bundles = bundleManager.findBundlesByCriteria(subject, bundleCriteria);
return bundles;
}
}
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml
index 102e407..cf34d97 100644
--- a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml
@@ -38,7 +38,7 @@
<rhq:rowSelector value="#{BundlesUIBean.selectedBundles}"/>
</rich:column>
- <rich:column width="235" sortBy="b.name">
+ <rich:column width="235">
<f:facet name="header">
<rhq:sortableColumnHeader sortBy="b.name">
<a4j:support event="onclick"
@@ -47,13 +47,13 @@
</rhq:sortableColumnHeader>
</f:facet>
- <h:outputLink value="#{bundle.name}">
+ <h:outputLink value="bundleVersions.seam">
<f:param name="bundleId" value="#{bundle.id}"/>
- <h:outputText value="#{resource.id}"/>
+ <h:outputText value="#{bundle.name}"/>
</h:outputLink>
</rich:column>
- <rich:column width="235">
+ <rich:column>
<f:facet name="header">
<rhq:sortableColumnHeader sortBy="b.bundleType.name">
<a4j:support event="onclick"
@@ -67,10 +67,10 @@
<f:facet name="footer">
<rich:columnGroup>
- <rich:column colspan="4">
+ <rich:column colspan="3">
<rhq:selectedRowsCommandButton
value="DELETE"
- action="#{BundlesUIBean.deleteBundle}"/>
+ action="#{BundlesUIBean.deleteSelectedBundles}"/>
<ui:include src="/WEB-INF/includes/pageControls.xhtml">
<ui:param name="pagedDataUIBean" value="#{BundlesUIBean}"/>
commit 259fbad99c29554896fd6b6b94019e88b09526a1
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Fri Feb 12 11:37:47 2010 -0500
start of SLSB methods and perspective-based GUI for listing bundles
diff --git a/dev-cli b/dev-cli
new file mode 120000
index 0000000..9e0363b
--- /dev/null
+++ b/dev-cli
@@ -0,0 +1 @@
+modules/enterprise/remoting/cli/target/rhq-remoting-cli-1.4.0-SNAPSHOT
\ No newline at end of file
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
index 7c5cda5..0cb550a 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
@@ -49,8 +49,10 @@ import javax.xml.bind.annotation.XmlAccessorType;
* @author John Mazzitelli
*/
@Entity
-@NamedQueries( { @NamedQuery(name = Bundle.QUERY_FIND_ALL, query = "SELECT b FROM Bundle b"), //
- @NamedQuery(name = Bundle.QUERY_FIND_BY_NAME, query = "SELECT b FROM Bundle b WHERE b.name = :name") //
+@NamedQueries( {
+ @NamedQuery(name = Bundle.QUERY_FIND_ALL, query = "SELECT b FROM Bundle b"), //
+ @NamedQuery(name = Bundle.QUERY_FIND_BY_TYPE_AND_NAME, query = "SELECT b FROM Bundle b WHERE " +
+ "(:type = b.bundleType.name OR :type IS NULL) AND (:name = b.name OR :name IS NULL)")
})
@SequenceGenerator(name = "SEQ", sequenceName = "RHQ_BUNDLE_ID_SEQ")
@Table(name = "RHQ_BUNDLE")
@@ -59,7 +61,7 @@ public class Bundle implements Serializable {
private static final long serialVersionUID = 1L;
public static final String QUERY_FIND_ALL = "Bundle.findAll";
- public static final String QUERY_FIND_BY_NAME = "Bundle.findByName";
+ public static final String QUERY_FIND_BY_TYPE_AND_NAME = "Bundle.findByTypeAndName";
@Column(name = "ID", nullable = false)
@GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ")
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 c25c0b9..19d17c2 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
@@ -18,17 +18,8 @@
*/
package org.rhq.enterprise.server.bundle;
-import java.util.List;
-
-import javax.ejb.EJB;
-import javax.ejb.Stateless;
-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.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
@@ -38,13 +29,25 @@ import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleDeployDefinitionCriteria;
import org.rhq.core.domain.criteria.BundleDeploymentCriteria;
+import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.util.PageList;
+import org.rhq.core.domain.util.PersistenceUtility;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.authz.AuthorizationManagerLocal;
import org.rhq.enterprise.server.authz.PermissionException;
+import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal;
import org.rhq.enterprise.server.util.CriteriaQueryGenerator;
import org.rhq.enterprise.server.util.CriteriaQueryRunner;
+import javax.ejb.EJB;
+import javax.ejb.Stateless;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
+import java.util.List;
+import java.util.Random;
+import java.util.UUID;
+
/**
* Manages the creation and usage of bundles.
*
@@ -60,6 +63,9 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
@EJB
private AuthorizationManagerLocal authorizationManager;
+ @EJB
+ private ResourceTypeManagerLocal resourceTypeManager;
+
public Bundle createBundle(Subject subject, Bundle bundle) {
entityManager.persist(bundle);
return bundle;
@@ -113,10 +119,50 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
public PageList<Bundle> findBundlesByCriteria(Subject subject, BundleCriteria criteria) {
+ Query totalCountQuery = PersistenceUtility.createCountQuery(entityManager,
+ Bundle.QUERY_FIND_ALL);
+ long totalCount = (Long) totalCountQuery.getSingleResult();
+ if (totalCount == 0) {
+ List<BundleType> bundleTypes = getAllBundleTypes(subject);
+ for (int i = 0; i < 50; i++) {
+ createMockBundle(subject, bundleTypes);
+ }
+ }
+
CriteriaQueryGenerator generator = new CriteriaQueryGenerator(criteria);
CriteriaQueryRunner<Bundle> queryRunner = new CriteriaQueryRunner<Bundle>(criteria, generator, entityManager);
return queryRunner.execute();
}
+ public PageList<BundleDeployment> findBundleDeploymentsByCriteria(BundleDeploymentCriteria criteria) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void deleteBundles(Subject subject, int[] bundleIds) {
+ for (int bundleId : bundleIds) {
+ Bundle bundle = this.entityManager.find(Bundle.class, bundleId);
+ this.entityManager.remove(bundle);
+ }
+ }
+
+ public BundleType createMockBundleType(Subject subject) {
+ ResourceType linuxPlatformResourceType = this.resourceTypeManager.getResourceTypeByNameAndPlugin("Linux", "Platforms");
+ BundleType bundleType = new BundleType(UUID.randomUUID().toString(), linuxPlatformResourceType);
+ return createBundleType(subject, bundleType);
+ }
+
+ public Bundle createMockBundle(Subject subject, List<BundleType> bundleTypes) {
+ BundleType bundleType;
+ if (bundleTypes.isEmpty()) {
+ bundleType = createMockBundleType(subject);
+ } else {
+ Random random = new Random();
+ int randomIndex = random.nextInt(bundleTypes.size());
+ bundleType = bundleTypes.get(randomIndex);
+ }
+ Bundle bundle = new Bundle(UUID.randomUUID().toString(), bundleType);
+ return createBundle(subject, bundle);
+ }
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
index ee808d0..0dc6eb9 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
@@ -31,6 +31,7 @@ import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleDeployDefinitionCriteria;
import org.rhq.core.domain.criteria.BundleDeploymentCriteria;
+import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
/**
@@ -40,7 +41,6 @@ import org.rhq.core.domain.util.PageList;
*/
@Local
public interface BundleManagerLocal {
-
Bundle createBundle(Subject subject, Bundle b);
BundleType createBundleType(Subject subject, BundleType bundleType);
@@ -61,4 +61,6 @@ public interface BundleManagerLocal {
PageList<Bundle> findBundlesByCriteria(Subject subject, BundleCriteria criteria);
List<BundleType> getAllBundleTypes(Subject subject);
+
+ void deleteBundles(Subject subject, int[] bundleIds);
}
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 a4fd8fe..3b6454a 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
@@ -27,7 +27,11 @@ import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleType;
+import org.rhq.core.domain.criteria.BundleCriteria;
+import org.rhq.core.domain.util.PageControl;
+import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.system.ServerVersion;
/**
@@ -42,4 +46,8 @@ public interface BundleManagerRemote {
@WebMethod
List<BundleType> getAllBundleTypes( //
@WebParam(name = "subject") Subject subject);
+
+ PageList<Bundle> findBundlesByCriteria(Subject subject, BundleCriteria criteria);
+
+ void deleteBundles(Subject subject, int[] bundleIds);
}
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/pom.xml b/modules/enterprise/server/plugins/perspectives/policy/app/pom.xml
new file mode 100644
index 0000000..3c53325
--- /dev/null
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/pom.xml
@@ -0,0 +1,106 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-parent</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server-policy-perspective-war</artifactId>
+ <packaging>war</packaging>
+
+ <name>RHQ Policy Perspective War</name>
+
+ <scm>
+ <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/etc/samples/sample-perspec...</connection>
+ <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/etc/samples/sample-perspec...</developerConnection>
+ </scm>
+
+ <dependencyManagement>
+
+ <dependencies>
+
+ <!-- This will pull in the managed dependencies from the base-perspective-war pom. -->
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server-base-perspective-war</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+
+ </dependencies>
+
+ </dependencyManagement>
+
+ <dependencies>
+
+ <!-- This is needed by the war plugin for the overlay functionality. -->
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server-base-perspective-war</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <type>war</type>
+ </dependency>
+
+ <!-- This is used to pull in the war's classes and dependencies, which are not pulled in by the above dependency
+ of type war (see http://jira.codehaus.org/browse/MNG-1991). -->
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server-base-perspective-war</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <type>warpath</type>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <finalName>rhq-policy-perspective</finalName>
+
+ <plugins>
+
+ <plugin>
+ <artifactId>maven-war-plugin</artifactId>
+ <configuration>
+ <overlays>
+ <overlay>
+ <!-- empty groupId/artifactId detected as the current build.
+ earlier overlays win over later overlays, so put ourselves first. -->
+ </overlay>
+ <overlay>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server-base-perspective-war</artifactId>
+ </overlay>
+ </overlays>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.appfuse</groupId>
+ <artifactId>maven-warpath-plugin</artifactId>
+ <version>2.0.2</version>
+ <extensions>true</extensions>
+ <executions>
+ <execution>
+ <goals>
+ <goal>add-classes</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ </plugins>
+
+ </build>
+
+</project>
+
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java
new file mode 100644
index 0000000..10344d9
--- /dev/null
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java
@@ -0,0 +1,69 @@
+package org.rhq.enterprise.server.perspective.policy;
+
+import org.ajax4jsf.model.KeepAlive;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Create;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.bundle.Bundle;
+import org.rhq.core.domain.util.PageControl;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.core.gui.table.bean.AbstractPagedDataUIBean;
+import org.rhq.core.gui.table.model.PagedListDataModel;
+import org.rhq.enterprise.server.bundle.BundleManagerRemote;
+import org.rhq.enterprise.server.perspective.AbstractPerspectivePagedDataUIBean;
+
+import java.util.List;
+
+/**
+ * Provides CRUD operations for provisioning {@link Bundle}s. The backing bean for bundles.xhtml.
+ */
+@Name("BundlesUIBean")
+(a)Scope(ScopeType.EVENT)
+@KeepAlive
+public class BundlesUIBean extends AbstractPerspectivePagedDataUIBean {
+ private BundleManagerRemote bundleManager;
+ private List<Bundle> selectedBundles;
+
+ @Create
+ public void init() {
+ try {
+ this.bundleManager = this.perspectiveClient.getRemoteClient().getBundleManagerRemote();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public PagedListDataModel createDataModel() {
+ return new DataModel(this);
+ }
+
+ public List<Bundle> getSelectedBundles() {
+ return this.selectedBundles;
+ }
+
+ public void setSelectedBundles(List<Bundle> selectedResources) {
+ this.selectedBundles = selectedResources;
+ }
+
+ private class DataModel extends PagedListDataModel<Bundle> {
+ private DataModel(AbstractPagedDataUIBean pagedDataBean) {
+ super(pagedDataBean);
+ }
+
+ @Override
+ public PageList<Bundle> fetchPage(PageControl pageControl) {
+ Subject subject;
+ try {
+ subject = BundlesUIBean.this.perspectiveClient.getSubject();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ // TODO: Implement filtering.
+ PageList<Bundle> bundles = BundlesUIBean.this.bundleManager.findBundlesByCriteria(subject, null, null, pageControl);
+ return bundles;
+ }
+ }
+}
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/resources/seam.properties b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/resources/seam.properties
new file mode 100644
index 0000000..b97c770
--- /dev/null
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/resources/seam.properties
@@ -0,0 +1,3 @@
+# NOTE: The presence of this file tells Seam to scan this WAR for Seam
+# components (i.e. classes with Name annotations) and to deploy
+# any that it finds.
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/WEB-INF/components.xml b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/WEB-INF/components.xml
new file mode 100644
index 0000000..4631d2e
--- /dev/null
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/WEB-INF/components.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<components xmlns="http://jboss.com/products/seam/components"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:security="http://jboss.com/products/seam/security"
+ xsi:schemaLocation=
+ "http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.0.xsd
+ http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.0.xsd">
+
+ <component name="org.jboss.seam.core.init">
+ <property name="debug">false</property>
+ <!-- enable only when needed -->
+ <property name="transactionManagementEnabled">false</property>
+ </component>
+
+</components>
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml
new file mode 100644
index 0000000..102e407
--- /dev/null
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml
@@ -0,0 +1,87 @@
+<?xml version="1.0"?>
+
+<ui:composition
+ template="/WEB-INF/templates/mainTemplate.xhtml"
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:fn="http://java.sun.com/jsp/jstl/functions"
+ xmlns:a4j="http://richfaces.org/a4j"
+ xmlns:rich="http://richfaces.org/rich"
+ xmlns:rhq="http://rhq-project.org/rhq"
+ xmlns:onc="http://jboss.org/on/component">
+
+ <ui:param name="pageTitle" value="Provisioning Bundles"/>
+
+ <ui:define name="breadcrumbs">
+ <h:outputText value="Provisioning Bundles"/>
+ </ui:define>
+
+ <ui:define name="body">
+
+ <ui:remove><!-- NOTE: The table needs to be surrounded by a form for paging and sorting to work! --></ui:remove>
+ <a4j:form ajaxSubmit="false" reRender="bundlesDataTable">
+
+ <rich:dataTable id="bundlesDataTable"
+ value="#{BundlesUIBean.dataModel}" var="bundle"
+ first="#{BundlesUIBean.pageControl.pageNumber}"
+ rows="#{BundlesUIBean.pageControl.pageSize}"
+ sortMode="multi"
+ width="100%">
+
+ <rich:column width="20">
+ <f:facet name="header">
+ <rhq:allRowsSelector/>
+ </f:facet>
+ <rhq:rowSelector value="#{BundlesUIBean.selectedBundles}"/>
+ </rich:column>
+
+ <rich:column width="235" sortBy="b.name">
+ <f:facet name="header">
+ <rhq:sortableColumnHeader sortBy="b.name">
+ <a4j:support event="onclick"
+ actionListener="#{BundlesUIBean.ajaxSortListener}"/>
+ <h:outputText value="Name"/>
+ </rhq:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputLink value="#{bundle.name}">
+ <f:param name="bundleId" value="#{bundle.id}"/>
+ <h:outputText value="#{resource.id}"/>
+ </h:outputLink>
+ </rich:column>
+
+ <rich:column width="235">
+ <f:facet name="header">
+ <rhq:sortableColumnHeader sortBy="b.bundleType.name">
+ <a4j:support event="onclick"
+ actionListener="#{BundlesUIBean.ajaxSortListener}"/>
+ <h:outputText value="Type"/>
+ </rhq:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{bundle.bundleType.name}"/>
+ </rich:column>
+
+ <f:facet name="footer">
+ <rich:columnGroup>
+ <rich:column colspan="4">
+ <rhq:selectedRowsCommandButton
+ value="DELETE"
+ action="#{BundlesUIBean.deleteBundle}"/>
+
+ <ui:include src="/WEB-INF/includes/pageControls.xhtml">
+ <ui:param name="pagedDataUIBean" value="#{BundlesUIBean}"/>
+ <ui:param name="dataTableName" value="bundlesDataTable"/>
+ </ui:include>
+ </rich:column>
+ </rich:columnGroup>
+ </f:facet>
+ </rich:dataTable>
+ </a4j:form>
+
+ </ui:define>
+
+</ui:composition>
diff --git a/modules/enterprise/server/plugins/perspectives/policy/perspective/pom.xml b/modules/enterprise/server/plugins/perspectives/policy/perspective/pom.xml
new file mode 100644
index 0000000..2039f89
--- /dev/null
+++ b/modules/enterprise/server/plugins/perspectives/policy/perspective/pom.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0"?>
+
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-parent</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server-policy-perspective</artifactId>
+ <packaging>jar</packaging>
+
+ <name>RHQ Policy Perspective</name>
+ <description>a perspective that adds support to the GUI for policy and provisioning</description>
+
+ <dependencies>
+
+ <!-- Below are the apps packaged with this perspective plugin -->
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server-policy-perspective-war</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ <type>war</type>
+ </dependency>
+
+ <!-- Below are the core modules that are required dependencies of all server plugins -->
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope> <!-- provided by the server/plugin-container -->
+ </dependency>
+
+
+ <!-- uncomment the one of the three logging systems your plugin uses: log4j, commons-logging or i18nlog -->
+ <!-- all three are provided to your plugin by the server/plugin-container -->
+ <!--
+ <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.14</version>
+ <scope>provided</scope> </dependency>
+ -->
+
+ <!--
+ <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1</version>
+ <scope>provided</scope> </dependency>
+ -->
+
+ <!--
+ <dependency> <groupId>i18nlog</groupId> <artifactId>i18nlog</artifactId> <version>1.0.9</version> </dependency>
+ -->
+
+ <!-- Define any third-party dependencies your plugin has here. -->
+ <!--
+ <dependency> <groupId>group-id-of-dependency-goes-here</groupId>
+ <artifactId>artifact-id-of-dependency-goes-here</artifactId> <version>version-of-dependency-goes-here</version>
+ </dependency>
+ -->
+
+ </dependencies>
+
+ <build>
+ <plugins>
+
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.1</version>
+ <executions>
+
+ <execution>
+ <id>add-war</id>
+ <phase>verify</phase>
+ <configuration>
+ <tasks>
+ <property
+ name="classes.dir"
+ location="${rhq.deploymentDir}/WEB-INF/classes" />
+ <jar
+ update="yes"
+ destfile="${basedir}/target/${project.artifactId}-${project.version}.jar"
+ basedir="${basedir}/../app/target"
+ includes="*.war" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>dev</id>
+
+ <properties>
+ <rhq.rootDir>../../../../..</rhq.rootDir>
+ <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir>
+ <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/rhq-serverplugins</rhq.deploymentDir>
+ </properties>
+
+ <build>
+ <plugins>
+
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.1</version>
+ <executions>
+
+ <execution>
+ <id>deploy</id>
+ <phase>install</phase>
+ <configuration>
+ <tasks>
+ <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
+ <echo>*** Updating ${deployment.file}...</echo>
+ <copy file="${basedir}/target/${project.build.finalName}.jar" toDir="${rhq.deploymentDir}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ <execution>
+ <id>undeploy</id>
+ <phase>clean</phase>
+ <configuration>
+ <tasks>
+ <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
+ <echo>*** Deleting ${deployment.file}...</echo>
+ <delete file="${deployment.file}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ </executions>
+ </plugin>
+
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+</project>
diff --git a/modules/enterprise/server/plugins/perspectives/policy/perspective/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/perspectives/policy/perspective/src/main/resources/META-INF/rhq-serverplugin.xml
new file mode 100644
index 0000000..6053d09
--- /dev/null
+++ b/modules/enterprise/server/plugins/perspectives/policy/perspective/src/main/resources/META-INF/rhq-serverplugin.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<perspective-plugin
+ apiVersion="1.0"
+ version="1.0"
+ description="a perspective that adds support to the GUI for policy and provisioning"
+ displayName="Policy Perspective"
+ name="PolicyPerspective"
+ package="org.rhq.perspective.sample"
+ xmlns="urn:xmlns:rhq-serverplugin.perspective"
+ xmlns:serverplugin="urn:xmlns:rhq-serverplugin"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <!-- Declare supporting applications for this perspective -->
+ <application
+ name="policy"
+ baseUrl="/rhq-policy-perspective" />
+
+ <!-- Administration > Provisioning -->
+ <menu-item
+ name="administration.provisioning"
+ displayName="Provisioning"
+ application="policy"
+ url="bundles.seam">
+ <position
+ name="administration.content"
+ placement="after" />
+ </menu-item>
+
+</perspective-plugin>
\ No newline at end of file
diff --git a/modules/enterprise/server/plugins/perspectives/policy/pom.xml b/modules/enterprise/server/plugins/perspectives/policy/pom.xml
new file mode 100644
index 0000000..87b03cb
--- /dev/null
+++ b/modules/enterprise/server/plugins/perspectives/policy/pom.xml
@@ -0,0 +1,28 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-parent</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server-policy-perspective-parent</artifactId>
+ <packaging>pom</packaging>
+
+ <name>RHQ Policy Perspective Parent</name>
+ <description>parent POM for modules comprising the RHQ Policy Perspective</description>
+
+ <scm>
+ <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/plugins...</connection>
+ <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/plugins...</developerConnection>
+ </scm>
+
+ <modules>
+ <module>perspective</module>
+ <module>app</module>
+ </modules>
+
+</project>
diff --git a/modules/enterprise/server/plugins/pom.xml b/modules/enterprise/server/plugins/pom.xml
index abec716..8a66c49 100644
--- a/modules/enterprise/server/plugins/pom.xml
+++ b/modules/enterprise/server/plugins/pom.xml
@@ -64,23 +64,24 @@
</dependency>
</dependencies>
- <modules>
- <module>disk</module>
- <module>yum</module>
- <module>url</module>
- <module>rhnhosted</module>
- <module>jboss-software</module>
- <module>perspectives/core</module>
- <module>alert-email</module>
- <module>alert-irc</module>
- <module>alert-mobicents</module>
- <module>alert-microblog</module>
- <module>alert-roles</module>
- <module>alert-snmp</module>
- <module>alert-subject</module>
- <module>cobbler</module>
- <module>filetemplate-bundle</module>
- <module>validate-all-serverplugins</module>
- </modules>
+ <modules>
+ <module>disk</module>
+ <module>yum</module>
+ <module>url</module>
+ <module>rhnhosted</module>
+ <module>jboss-software</module>
+ <module>perspectives/core</module>
+ <module>perspectives/policy</module>
+ <module>alert-email</module>
+ <module>alert-irc</module>
+ <module>alert-mobicents</module>
+ <module>alert-microblog</module>
+ <module>alert-roles</module>
+ <module>alert-snmp</module>
+ <module>alert-subject</module>
+ <module>cobbler</module>
+ <module>filetemplate-bundle</module>
+ <module>validate-all-serverplugins</module>
+ </modules>
-</project>
\ No newline at end of file
+</project>
commit 092d7140fd628e2ea84d112757f1c41146b43e27
Merge: f9f9338... 65b7f84...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri Feb 12 16:18:54 2010 -0500
Merge branch 'bundle' of ssh://git.fedorahosted.org/git/rhq/rhq into bundle
commit f9f93387bdf2b3fb3c193fd7320ebc710a4ac806
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri Feb 12 16:15:58 2010 -0500
Added BundleCriteria and other criteria search. BundleCriteria is tested.
More testing tbd for the others.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java
new file mode 100644
index 0000000..d446891
--- /dev/null
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java
@@ -0,0 +1,57 @@
+/*
+ * 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.core.domain.criteria;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.rhq.core.domain.bundle.Bundle;
+
+/**
+ * @author Jay Shaughnessy
+ */
+@XmlRootElement
+(a)XmlAccessorType(XmlAccessType.FIELD)
+@SuppressWarnings("unused")
+public class BundleCriteria extends Criteria {
+ private static final long serialVersionUID = 1L;
+
+ private Integer filterId;
+ private String filterName;
+
+ private boolean fetchBundleVersions;
+
+ public BundleCriteria() {
+ super(Bundle.class);
+ }
+
+ public void addFilterId(Integer filterId) {
+ this.filterId = filterId;
+ }
+
+ public void addFilterName(String filterName) {
+ this.filterName = filterName;
+ }
+
+ public void fetchBundleVersions(boolean fetchBundleVersions) {
+ this.fetchBundleVersions = fetchBundleVersions;
+ }
+}
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 ea5d2b2..c25c0b9 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
@@ -20,6 +20,7 @@ package org.rhq.enterprise.server.bundle;
import java.util.List;
+import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@@ -33,10 +34,16 @@ import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleDeployment;
import org.rhq.core.domain.bundle.BundleType;
+import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleDeployDefinitionCriteria;
import org.rhq.core.domain.criteria.BundleDeploymentCriteria;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.RHQConstants;
+import org.rhq.enterprise.server.authz.AuthorizationManagerLocal;
+import org.rhq.enterprise.server.authz.PermissionException;
+import org.rhq.enterprise.server.util.CriteriaQueryGenerator;
+import org.rhq.enterprise.server.util.CriteriaQueryRunner;
/**
* Manages the creation and usage of bundles.
@@ -50,14 +57,22 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
@PersistenceContext(unitName = RHQConstants.PERSISTENCE_UNIT_NAME)
private EntityManager entityManager;
- public BundleType createBundleType(BundleType bundleType) {
+ @EJB
+ private AuthorizationManagerLocal authorizationManager;
+
+ public Bundle createBundle(Subject subject, Bundle bundle) {
+ entityManager.persist(bundle);
+ return bundle;
+ }
+
+ public BundleType createBundleType(Subject subject, BundleType bundleType) {
entityManager.persist(bundleType);
return bundleType;
}
- public Bundle createBundle(Bundle bundle) {
- entityManager.persist(bundle);
- return bundle;
+ public BundleVersion createBundleVersion(Subject subject, BundleVersion bundleVersion) {
+ entityManager.persist(bundleVersion);
+ return bundleVersion;
}
@SuppressWarnings("unchecked")
@@ -68,15 +83,40 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
return types;
}
- public PageList<BundleDeployDefinition> findBundleDeployDefinitionsByCriteria(
+ public PageList<BundleDeployDefinition> findBundleDeployDefinitionsByCriteria(Subject subject,
BundleDeployDefinitionCriteria criteria) {
- // TODO Auto-generated method stub
- return null;
+
+ CriteriaQueryGenerator generator = new CriteriaQueryGenerator(criteria);
+
+ CriteriaQueryRunner<BundleDeployDefinition> queryRunner = new CriteriaQueryRunner<BundleDeployDefinition>(
+ criteria, generator, entityManager);
+ return queryRunner.execute();
+ }
+
+ public PageList<BundleDeployment> findBundleDeploymentsByCriteria(Subject subject, BundleDeploymentCriteria criteria) {
+
+ CriteriaQueryGenerator generator = new CriteriaQueryGenerator(criteria);
+ if (!authorizationManager.isInventoryManager(subject)) {
+ if (criteria.isInventoryManagerRequired()) {
+ throw new PermissionException("Subject [" + subject.getName()
+ + "] requires InventoryManager permission for requested query criteria.");
+ }
+
+ generator.setAuthorizationResourceFragment(CriteriaQueryGenerator.AuthorizationTokenType.RESOURCE, null,
+ subject.getId());
+ }
+
+ CriteriaQueryRunner<BundleDeployment> queryRunner = new CriteriaQueryRunner<BundleDeployment>(criteria,
+ generator, entityManager);
+
+ return queryRunner.execute();
}
- public PageList<BundleDeployment> findBundleDeploymentsByCriteria(BundleDeploymentCriteria criteria) {
- // TODO Auto-generated method stub
- return null;
+ public PageList<Bundle> findBundlesByCriteria(Subject subject, BundleCriteria criteria) {
+ CriteriaQueryGenerator generator = new CriteriaQueryGenerator(criteria);
+
+ CriteriaQueryRunner<Bundle> queryRunner = new CriteriaQueryRunner<Bundle>(criteria, generator, entityManager);
+ return queryRunner.execute();
}
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
index 70601b4..ee808d0 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
@@ -27,6 +27,8 @@ import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleDeployment;
import org.rhq.core.domain.bundle.BundleType;
+import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleDeployDefinitionCriteria;
import org.rhq.core.domain.criteria.BundleDeploymentCriteria;
import org.rhq.core.domain.util.PageList;
@@ -38,13 +40,12 @@ import org.rhq.core.domain.util.PageList;
*/
@Local
public interface BundleManagerLocal {
- BundleType createBundleType(BundleType bundleType);
- Bundle createBundle(Bundle b);
+ Bundle createBundle(Subject subject, Bundle b);
- PageList<BundleDeployDefinition> findBundleDeployDefinitionsByCriteria(BundleDeployDefinitionCriteria criteria);
+ BundleType createBundleType(Subject subject, BundleType bundleType);
- PageList<BundleDeployment> findBundleDeploymentsByCriteria(BundleDeploymentCriteria criteria);
+ BundleVersion createBundleVersion(Subject subject, BundleVersion bundleVersion);
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
@@ -52,5 +53,12 @@ public interface BundleManagerLocal {
//
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ PageList<BundleDeployDefinition> findBundleDeployDefinitionsByCriteria(Subject subject,
+ BundleDeployDefinitionCriteria criteria);
+
+ PageList<BundleDeployment> findBundleDeploymentsByCriteria(Subject subject, BundleDeploymentCriteria criteria);
+
+ PageList<Bundle> findBundlesByCriteria(Subject subject, BundleCriteria criteria);
+
List<BundleType> getAllBundleTypes(Subject subject);
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
index 5e65547..35666db 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
@@ -26,6 +26,7 @@ import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.transaction.TransactionManager;
+import org.hibernate.LazyInitializationException;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@@ -34,19 +35,24 @@ import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.test.AbstractEJB3Test;
import org.rhq.enterprise.server.util.LookupUtil;
/**
* @author John Mazzitelli
*/
+@SuppressWarnings("unchecked")
@Test
public class BundleManagerBeanTest extends AbstractEJB3Test {
private static final String TEST_PREFIX = "bundletest";
+ private static final boolean ENABLED = true;
+
private BundleManagerLocal bundleManagerBean;
@BeforeMethod
@@ -107,6 +113,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
}
}
+ @Test(enabled = ENABLED)
public void testGetBundleTypes() throws Exception {
BundleType bt1 = createBundleType("one");
BundleType bt2 = createBundleType("two");
@@ -122,6 +129,68 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
assert btNames.contains(bt2.getName());
}
+ @Test(enabled = ENABLED)
+ public void testfindBundlesByCriteria() throws Exception {
+ Bundle b1 = createBundle("one");
+ Bundle b2 = createBundle("two");
+ BundleVersion bv1 = createBundleVersion(b1.getName(), "1.0", b1);
+ BundleVersion bv2 = createBundleVersion(b2.getName(), "1.0", b2);
+ BundleCriteria c = new BundleCriteria();
+ PageList<Bundle> bundles = null;
+ Bundle b = null;
+ String name = null;
+
+ // return all with no optional data
+ bundles = bundleManagerBean.findBundlesByCriteria(getOverlord(), c);
+ assertNotNull(bundles);
+ assertEquals(2, bundles.size());
+ b = bundles.get(0);
+ name = "one";
+ assertNotNull(b);
+ assertTrue(b.getBundleType().getName(), b.getName().contains(name));
+ assertTrue(b.getBundleType().getName(), b.getBundleType().getName().contains(name));
+ try {
+ assertTrue(b.getBundleVersions().isEmpty());
+ fail("Should have thrown LazyInitializationException");
+ } catch (LazyInitializationException e) {
+ // expected
+ } catch (Exception e) {
+ fail("Should have thrown LazyInitializationException");
+ }
+
+ b = bundles.get(1);
+ name = "two";
+ assertNotNull(b);
+ assertTrue(b.getBundleType().getName(), b.getName().contains(name));
+ assertTrue(b.getBundleType().getName(), b.getBundleType().getName().contains(name));
+
+ // return bundle "two" using all criteria and with all optional data
+ c.addFilterId(b.getId());
+ c.addFilterName(b.getName());
+ c.fetchBundleVersions(true);
+ bundles = bundleManagerBean.findBundlesByCriteria(getOverlord(), c);
+ assertNotNull(bundles);
+ assertEquals(1, bundles.size());
+ b = bundles.get(0);
+ assertTrue(b.getBundleType().getName(), b.getName().contains(name));
+ assertTrue(b.getBundleType().getName(), b.getBundleType().getName().contains(name));
+ assertNotNull(b.getBundleVersions());
+ assertEquals(1, b.getBundleVersions().size());
+ BundleVersion bv = b.getBundleVersions().get(0);
+ assertEquals(bv2, bv);
+ assertEquals(b, bv.getBundle());
+ }
+
+ private BundleType createBundleType(String name) throws Exception {
+ final String fullName = TEST_PREFIX + "-type-" + name;
+ BundleType bt = new BundleType(fullName, createResourceType(name));
+ bt = bundleManagerBean.createBundleType(getOverlord(), bt);
+
+ assert bt.getId() > 0;
+ assert bt.getName().endsWith(fullName);
+ return bt;
+ }
+
private Bundle createBundle(String name) throws Exception {
BundleType bt = createBundleType(name);
return createBundle(name, bt);
@@ -130,19 +199,22 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
private Bundle createBundle(String name, BundleType bt) throws Exception {
final String fullName = TEST_PREFIX + "-bundle-" + name;
Bundle b = new Bundle(fullName, bt);
- b = bundleManagerBean.createBundle(b);
+ b = bundleManagerBean.createBundle(getOverlord(), b);
+
assert b.getId() > 0;
assert b.getName().endsWith(fullName);
return b;
}
- private BundleType createBundleType(String name) throws Exception {
- final String fullName = TEST_PREFIX + "-type-" + name;
- BundleType bt = new BundleType(fullName, createResourceType(name));
- bt = bundleManagerBean.createBundleType(bt);
- assert bt.getId() > 0;
- assert bt.getName().endsWith(fullName);
- return bt;
+ private BundleVersion createBundleVersion(String name, String version, Bundle bundle) throws Exception {
+ final String fullName = TEST_PREFIX + "-version-" + version + "-" + name;
+ final String recipe = TEST_PREFIX + "-recipe-" + name;
+ BundleVersion bv = new BundleVersion(fullName, version, bundle, recipe);
+ bv = bundleManagerBean.createBundleVersion(getOverlord(), bv);
+
+ assert bv.getId() > 0;
+ assert bv.getName().endsWith(fullName);
+ return bv;
}
private ResourceType createResourceType(String name) throws Exception {
commit b46293bdcd898427141b4f13f4f75af64ed87b93
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri Feb 12 16:14:51 2010 -0500
Change name of action to "recipe". We can change it back but it seems we
call this recipe all of the time, regardless of bundle type. For now,
will leave the db column as ACTION.
Added parameterized constructor to suppoert a simple create() slsb method.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java
index 38a3439..202eeac 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java
@@ -74,7 +74,7 @@ public class BundleVersion implements Serializable {
private String version;
@Column(name = "ACTION", nullable = false)
- private String action;
+ private String recipe;
@JoinColumn(name = "BUNDLE_ID", referencedColumnName = "ID", nullable = false)
@ManyToOne(fetch = FetchType.LAZY)
@@ -92,10 +92,11 @@ public class BundleVersion implements Serializable {
// for JPA use
}
- public BundleVersion(String name, String version, Bundle bundle) {
+ public BundleVersion(String name, String version, Bundle bundle, String recipe) {
setName(name);
setVersion(version);
setBundle(bundle);
+ setRecipe(recipe);
}
public int getId() {
@@ -122,12 +123,12 @@ public class BundleVersion implements Serializable {
this.version = version;
}
- public String getAction() {
- return action;
+ public String getRecipe() {
+ return recipe;
}
- public void setAction(String action) {
- this.action = action;
+ public void setRecipe(String recipe) {
+ this.recipe = recipe;
}
public Bundle getBundle() {
commit be423884b755fb90162766c5e917346c354e5464
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri Feb 12 16:12:32 2010 -0500
Remove CascadeType.PERSIST on bundleType as the BundleType should already
be defined in the db and not persisted as part of the bundle entity.
Added bundleVersions OneToMany to allow bv access from the bundle.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
index 8faec6c..7c5cda5 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
@@ -23,6 +23,8 @@
package org.rhq.core.domain.bundle;
import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
@@ -35,6 +37,7 @@ import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
+import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlAccessType;
@@ -67,9 +70,12 @@ public class Bundle implements Serializable {
private String name;
@JoinColumn(name = "BUNDLE_TYPE_ID", referencedColumnName = "ID", nullable = false)
- @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
+ @ManyToOne(fetch = FetchType.EAGER)
private BundleType bundleType;
+ @OneToMany(mappedBy = "bundle", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
+ private List<BundleVersion> bundleVersions = new ArrayList<BundleVersion>();
+
public Bundle() {
// for JPA use
}
@@ -103,6 +109,19 @@ public class Bundle implements Serializable {
this.bundleType = bundleType;
}
+ public List<BundleVersion> getBundleVersions() {
+ return bundleVersions;
+ }
+
+ public void addBundleVersion(BundleVersion bundleVersion) {
+ this.bundleVersions.add(bundleVersion);
+ bundleVersion.setBundle(this);
+ }
+
+ public void setBundleVersions(List<BundleVersion> bundleVersions) {
+ this.bundleVersions = bundleVersions;
+ }
+
@Override
public String toString() {
return "Bundle[id=" + id + ",name=" + name + ",bundleType=" + bundleType + "]";
commit 89383e0f0657bb17458442936dc92b35baa3f7ba
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri Feb 12 16:10:30 2010 -0500
fix a version problem in the sample perspective build
diff --git a/etc/samples/perspectives/sample-perspective/perspective/pom.xml b/etc/samples/perspectives/sample-perspective/perspective/pom.xml
index 8a9587a..e0ad5c4 100644
--- a/etc/samples/perspectives/sample-perspective/perspective/pom.xml
+++ b/etc/samples/perspectives/sample-perspective/perspective/pom.xml
@@ -30,7 +30,7 @@
<dependency>
<groupId>org.rhq</groupId>
<artifactId>rhq-sample-perspective-war</artifactId>
- <version>${rhq.version}</version>
+ <version>1.0.0-SNAPSHOT</version>
<scope>provided</scope>
<type>war</type>
</dependency>
commit 65b7f843d2d07bf4d36a5ea0da61aac94d0345d1
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 12 11:46:56 2010 -0500
the installer should create a keystore with the server's public endpoint in the CN
this is BZ 564409
diff --git a/modules/enterprise/gui/installer-war/pom.xml b/modules/enterprise/gui/installer-war/pom.xml
index 3481a24..6c9121b 100644
--- a/modules/enterprise/gui/installer-war/pom.xml
+++ b/modules/enterprise/gui/installer-war/pom.xml
@@ -57,6 +57,13 @@
</dependency>
<dependency>
+ <!-- need this solely for SecurityUtils -->
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-comm</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
<groupId>ant</groupId>
<artifactId>ant</artifactId>
<version>1.6.5</version>
diff --git a/modules/enterprise/gui/installer-war/src/main/java/org/rhq/enterprise/installer/ConfigurationBean.java b/modules/enterprise/gui/installer-war/src/main/java/org/rhq/enterprise/installer/ConfigurationBean.java
index 90f4072..bca6381 100644
--- a/modules/enterprise/gui/installer-war/src/main/java/org/rhq/enterprise/installer/ConfigurationBean.java
+++ b/modules/enterprise/gui/installer-war/src/main/java/org/rhq/enterprise/installer/ConfigurationBean.java
@@ -722,6 +722,9 @@ public class ConfigurationBean {
// Ensure the install server info is up to date and stored in the DB
serverInfo.storeServer(configurationAsProperties, haServer);
+ // build a keystore whose cert has a CN of this server's public endpoint address
+ serverInfo.createKeystore(haServer);
+
// now deploy RHQ Server fully
serverInfo.moveDeploymentArtifacts(true);
} catch (Exception e) {
diff --git a/modules/enterprise/gui/installer-war/src/main/java/org/rhq/enterprise/installer/ServerInformation.java b/modules/enterprise/gui/installer-war/src/main/java/org/rhq/enterprise/installer/ServerInformation.java
index f90c526..0896ace 100644
--- a/modules/enterprise/gui/installer-war/src/main/java/org/rhq/enterprise/installer/ServerInformation.java
+++ b/modules/enterprise/gui/installer-war/src/main/java/org/rhq/enterprise/installer/ServerInformation.java
@@ -61,6 +61,7 @@ import org.rhq.core.db.SQLServerDatabaseType;
import org.rhq.core.db.setup.DBSetup;
import org.rhq.core.util.PropertiesFileUpdate;
import org.rhq.core.util.jdbc.JDBCUtil;
+import org.rhq.enterprise.communications.util.SecurityUtil;
/**
* Finds out information about the RHQ Server and the JBossAS server it is running in. It can also be used to modify
@@ -97,6 +98,7 @@ public class ServerInformation {
private File binDirectory = null;
private File logDirectory = null;
private File dataDirectory = null;
+ private File confDirectory = null;
public ServerInformation() {
// This is called both within the context of the GUI and the auto-install startup servlet.
@@ -565,6 +567,18 @@ public class ServerInformation {
return dataDirectory;
}
+ private File getConfDirectory() {
+ if (confDirectory == null) {
+ MBeanServer mbs = getMBeanServer();
+ ObjectName name = ObjectNameFactory.create("jboss.system:type=ServerConfig");
+ Object mbean = MBeanServerInvocationHandler.newProxyInstance(mbs, name, ServerConfig.class, false);
+
+ confDirectory = new File(((ServerConfig) mbean).getServerHomeDir(), "conf");
+ }
+
+ return confDirectory;
+ }
+
private MBeanServer getMBeanServer() {
if (mbeanServer == null) {
mbeanServer = MBeanServerLocator.locateJBoss();
@@ -1230,4 +1244,40 @@ public class ServerInformation {
}
}
+ public void createKeystore(Server haServer) {
+ File confDir = getConfDirectory();
+ File keystore = new File(confDir, "rhq.keystore");
+ File keystoreBackup = new File(confDir, "rhq.keystore.backup");
+
+ // if there is one out-of-box, we want to remove it and create one with our proper CN
+ if (keystore.exists()) {
+ keystoreBackup.delete();
+ if (!keystore.renameTo(keystoreBackup)) {
+ LOG.warn("Cannot backup existing keystore - cannot generate a new cert with a proper domain name. ["
+ + keystore + "] will be the keystore used by this server");
+ return;
+ }
+ }
+
+ try {
+ String keystorePath = keystore.getAbsolutePath();
+ String keyAlias = "RHQ";
+ String domainName = "CN=" + haServer.endpointAddress + ", OU=RHQ, O=rhq-project.org, C=US";
+ String keystorePassword = "RHQManagement";
+ String keyPassword = keystorePassword;
+ String keyAlgorithm = "rsa";
+ int validity = 7300;
+ SecurityUtil.createKeyStore(keystorePath, keyAlias, domainName, keystorePassword, keyPassword,
+ keyAlgorithm, validity);
+ LOG.info("New keystore created [" + keystorePath + "] with cert domain name of [" + domainName + "]");
+ } catch (Exception e) {
+ LOG.warn("Could not generate a new cert with a proper domain name, will use the original keystore");
+ keystore.delete();
+ if (!keystoreBackup.renameTo(keystore)) {
+ LOG.warn("Failed to restore the original keystore from backup - please rename [" + keystoreBackup
+ + "] to [" + keystore + "]");
+ }
+ }
+ }
+
}
\ No newline at end of file
commit 619e5ea07de1ed26e790ed148911fb2bf4d3dd26
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 12 11:17:54 2010 -0500
should use rhq-project as the org name
diff --git a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/ServiceContainer.java b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/ServiceContainer.java
index 9f79ab4..6d1bf38 100644
--- a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/ServiceContainer.java
+++ b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/ServiceContainer.java
@@ -1355,7 +1355,7 @@ public class ServiceContainer {
*/
private void createKeyStore() {
SecurityUtil.createKeyStore(m_configuration.getConnectorSecurityKeystoreFile(), m_configuration
- .getConnectorSecurityKeystoreAlias(), "CN=RHQ, OU=RedHat, O=redhat.com, C=US", m_configuration
+ .getConnectorSecurityKeystoreAlias(), "CN=RHQ, OU=RHQ, O=rhq-project.org, C=US", m_configuration
.getConnectorSecurityKeystorePassword(), m_configuration.getConnectorSecurityKeystoreKeyPassword(), "DSA",
36500);
commit 63287379ccdcf153e57e7da89d56e459547acf49
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 12 10:42:27 2010 -0500
opps.. this sample plugin has been deleted, remove from eclipse classpath
diff --git a/.classpath b/.classpath
index 8c4665b..e9a098f 100644
--- a/.classpath
+++ b/.classpath
@@ -128,7 +128,6 @@
<classpathentry kind="src" path="modules/helpers/pluginAnnotations/src/main/java"/>
<classpathentry kind="src" path="modules/helpers/pluginGen/src/main/java"/>
<classpathentry kind="src" path="etc/samples/skeleton-plugin/src/main/java"/>
- <classpathentry kind="src" path="etc/samples/custom-bundle-plugin/src/main/java"/>
<classpathentry kind="src" path="etc/samples/custom-serverplugin/src/main/java"/>
<classpathentry kind="src" path="etc/samples/simplereport-serverplugin/src/main/java"/>
<classpathentry kind="src" path="etc/agentspawn/src/main/java"/>
commit f71b39d42542bbf2e2ed3c67520179a70eeabfd1
Merge: 01e9c60... d80bb12...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Thu Feb 11 09:48:47 2010 -0500
Merge branch 'bundle' into bundle-jay
Conflicts:
modules/enterprise/gui/portal-war/src/main/webapp/resource/hub/GroupHub.jsp
commit 01e9c607c759c86b68ad352544773281d9cb8639
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Thu Feb 11 09:47:03 2010 -0500
git forced LT commit
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/resource/hub/GroupHub.jsp b/modules/enterprise/gui/portal-war/src/main/webapp/resource/hub/GroupHub.jsp
index 26721d4..f61437d 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/resource/hub/GroupHub.jsp
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/resource/hub/GroupHub.jsp
@@ -1,369 +1,369 @@
-<%@ page language="java" %>
-
-<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
-<%@ taglib uri="http://jakarta.apache.org/struts/tags-html-el" prefix="html" %>
-<%@ taglib uri="http://jakarta.apache.org/struts/tags-tiles" prefix="tiles" %>
-<%@ taglib uri="/WEB-INF/tld/display.tld" prefix="display" %>
-<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
-<%@ taglib uri="/WEB-INF/tld/hq.tld" prefix="hq" %>
-
-<tiles:importAttribute name="nameSort" ignore="false" scope="page"/>
-<tiles:importAttribute name="typeSort" ignore="false"/>
-
-<script language="JavaScript" src="<html:rewrite page="/js/functions.js"/>" type="text/javascript"></script>
-<script language="JavaScript" src="<html:rewrite page="/js/listWidget.js"/>" type="text/javascript"></script>
-<c:set var="widgetInstanceName" value="listResources"/>
-<script type="text/javascript">
- var pageData = new Array();
- var FOO = "chart";
- var LIST = "list";
- var imagePath = "<html:rewrite page="/images/"/>";
-
- initializeWidgetProperties('<c:out value="${widgetInstanceName}"/>');
- widgetProperties = getWidgetProperties('<c:out value="${widgetInstanceName}"/>');
-</script>
-
-<hq:constant var="PLATFORM"
- classname="org.rhq.core.domain.resource.ResourceCategory"
- symbol="PLATFORM"/>
-<hq:constant var="SERVER"
- classname="org.rhq.core.domain.resource.ResourceCategory"
- symbol="SERVER"/>
-<hq:constant var="SERVICE"
- classname="org.rhq.core.domain.resource.ResourceCategory"
- symbol="SERVICE"/>
-
-<hq:constant var="COMPAT_GROUP"
- classname="org.rhq.core.domain.resource.group.GroupCategory"
- symbol="COMPATIBLE"/>
-<hq:constant var="MIXED_GROUP"
- classname="org.rhq.core.domain.resource.group.GroupCategory"
- symbol="MIXED"/>
-
-<c:choose>
- <c:when test="${GroupHubForm.groupCategory == COMPAT_GROUP}">
- <fmt:message var="resourceTypeTH" key="resource.hub.GroupTypeTH"/>
- </c:when>
- <%--
- Since mixed groups don't have a resourceType, do NOT set the
- resourceTypeTH, which will suppress the display of that column
- for Mixed groups.
- --%>
-</c:choose>
-
-
-<html:form method="GET" action="/GroupHub">
- <html:hidden property="groupCategory" value="${GroupHubForm.groupCategory}"/>
- <tiles:insert definition=".page.title.resource.hub">
- <tiles:put name="titleName">
- <c:out value="${navHierarchy}"/>
- </tiles:put>
- <tiles:put name="showSearch" value="true"/>
- </tiles:insert>
-</html:form>
-
-
-<html:form method="GET" action="/resource/hub/RemoveGroup.do">
-
- <c:if test="${not empty ResourceSummary}">
- <table width="100%" cellpadding="0" cellspacing="0" border="0">
- <tr>
- <td class="ResourceHubBlockTitle" width="100%">
-
- <c:url var="platformUrl" value="/ResourceHub.do">
- <c:param name="resourceCategory" value="${PLATFORM}"/>
- </c:url>
- <html:link href="${platformUrl}">
- <fmt:message key="resource.hub.filter.platform"/>
- ( <c:out value="${ResourceSummary.platformCount}"/> )
- </html:link>
- |
-
- <c:url var="serverUrl" value="/ResourceHub.do">
- <c:param name="resourceCategory" value="${SERVER}"/>
- </c:url>
- <html:link href="${serverUrl}">
- <fmt:message key="resource.hub.filter.server"/>
- ( <c:out value="${ResourceSummary.serverCount}"/> )
- </html:link>
- |
-
- <c:url var="serviceUrl" value="/ResourceHub.do">
- <c:param name="resourceCategory" value="${SERVICE}"/>
- </c:url>
- <html:link href="${serviceUrl}">
- <fmt:message key="resource.hub.filter.service"/>
- ( <c:out value="${ResourceSummary.serviceCount}"/> )
- </html:link>
- |
-
- <c:choose>
- <c:when test="${GroupHubForm.groupCategory == COMPAT_GROUP}">
- <fmt:message key="resource.hub.filter.compatibleGroups"/>
- ( <c:out value="${ResourceSummary.compatibleGroupCount}"/> )
- </c:when>
- <c:otherwise>
- <c:url var="groupUrl" value="/GroupHub.do">
- <c:param name="groupCategory" value="${COMPAT_GROUP}"/>
- </c:url>
- <html:link href="${groupUrl}">
- <fmt:message key="resource.hub.filter.compatibleGroups"/>
- ( <c:out value="${ResourceSummary.compatibleGroupCount}"/> )
- </html:link>
- </c:otherwise>
- </c:choose>
- |
- <c:choose>
- <c:when test="${GroupHubForm.groupCategory == MIXED_GROUP}">
- <fmt:message key="resource.hub.filter.mixedGroups"/>
- ( <c:out value="${ResourceSummary.mixedGroupCount}"/> )
- </c:when>
- <c:otherwise>
- <c:url var="groupUrl" value="/GroupHub.do">
- <c:param name="groupCategory" value="${MIXED_GROUP}"/>
- </c:url>
- <html:link href="${groupUrl}">
- <fmt:message key="resource.hub.filter.mixedGroups"/>
- ( <c:out value="${ResourceSummary.mixedGroupCount}"/> )
- </html:link>
- </c:otherwise>
- </c:choose>
- |
- <html:link href="/rhq/definition/group/list.xhtml">
- <fmt:message key="resource.hub.filter.groupDefinitions"/>
- ( <c:out value="${ResourceSummary.groupDefinitionCount}"/> )
- </html:link>
- </td>
- </tr>
- </table>
- </c:if>
-
- <fmt:message var="pluginTH" key="resource.hub.PluginTH"/>
-
- <tiles:insert definition=".portlet.confirm"/>
- <tiles:insert definition=".portlet.error"/>
-
- <!-- FILTER TOOLBAR CONTENTS -->
-
- <c:url var="resourceTypeAction" value="/GroupHub.do">
- <c:if test="${not empty param.keywords}">
- <c:param name="keywords" value="${param.keywords}"/>
- </c:if>
- <c:if test="${not empty param.ps}">
- <c:param name="ps" value="${param.ps}"/>
- </c:if>
- <c:if test="${not empty param.so}">
- <c:param name="so" value="${param.so}"/>
- </c:if>
- <c:if test="${not empty param.sc}">
- <c:param name="sc" value="${param.sc}"/>
- </c:if>
- <c:if test="${not empty param.plugin}">
- <c:param name="plugin" value="${param.plugin}"/>
- </c:if>
- <c:param name="groupCategory" value="${GroupHubForm.groupCategory}"/>
- </c:url>
- <c:url var="pluginAction" value="/GroupHub.do">
- <c:if test="${not empty param.keywords}">
- <c:param name="keywords" value="${param.keywords}"/>
- </c:if>
- <c:if test="${not empty param.ps}">
- <c:param name="ps" value="${param.ps}"/>
- </c:if>
- <c:if test="${not empty param.so}">
- <c:param name="so" value="${param.so}"/>
- </c:if>
- <c:if test="${not empty param.sc}">
- <c:param name="sc" value="${param.sc}"/>
- </c:if>
- <c:if test="${not empty param.resourceType}">
- <c:param name="resourceType" value="${param.resourceType}"/>
- </c:if>
- <c:param name="groupCategory" value="${GroupHubForm.groupCategory}"/>
- </c:url>
-
- <table width="100%" cellpadding="0" cellspacing="0" border="0">
- <tr>
- <td class="FilterLine" colspan="3">
- <html:img page="/images/spacer.gif" width="1" height="1" border="0"/>
- </td>
- </tr>
- <tr>
- <td class="FilterLabelText" nowrap="nowrap" align="right">
- <c:choose>
- <c:when test="${GroupHubForm.types == null}">
- <html:hidden property="resourceType" value=""/>
-
- </c:when>
- <c:otherwise>
- <fmt:message key="Filter.ViewLabel"/>
- </td>
- <td class="FilterLabelText">
- <html:select property="resourceType" styleClass="FilterFormText" size="1"
- onchange="goToSelectLocation(this, 'resourceType', '${resourceTypeAction}');">
- <html:optionsCollection property="types"/>
- </html:select>
- </c:otherwise>
- </c:choose>
- </td>
- <td class="FilterLabelText" width="100%">
- <c:choose>
- <c:when test="${GroupHubForm.plugins == null}">
- <html:hidden property="plugin" value=""/>
-
- </c:when>
- <c:otherwise>
- <html:select property="plugin" styleClass="FilterFormText" size="1"
- onchange="goToSelectLocation(this, 'plugin', '${pluginAction}');">
- <html:optionsCollection property="plugins"/>
- </html:select>
- </c:otherwise>
- </c:choose>
- </td>
-
- <c:url var="viewAction" value="/GroupHub.do">
- <c:if test="${not empty param.keywords}">
- <c:param name="keywords" value="${param.keywords}"/>
- </c:if>
- <c:if test="${not empty param.pn}">
- <c:param name="pn" value="${param.pn}"/>
- </c:if>
- <c:if test="${not empty param.so}">
- <c:param name="so" value="${param.so}"/>
- </c:if>
- <c:if test="${not empty param.sc}">
- <c:param name="sc" value="${param.sc}"/>
- </c:if>
- <c:if test="${not empty param.resourceType}">
- <c:param name="resourceType" value="${param.resourceType}"/>
- </c:if>
- <c:if test="${not empty param.plugin}">
- <c:param name="plugin" value="${param.plugin}"/>
- </c:if>
-
- <c:param name="groupCategory" value="${GroupHubForm.groupCategory}"/>
- </c:url>
-
- </tr>
- </table>
- <!-- / -->
-
- <!-- GROUP HUB CONTENTS -->
- <c:url var="sAction" value="/GroupHub.do">
- <c:if test="${not empty param.keywords}">
- <c:param name="keywords" value="${param.keywords}"/>
- </c:if>
- <c:if test="${not empty param.ps}">
- <c:param name="ps" value="${param.ps}"/>
- </c:if>
- <c:if test="${not empty param.pn}">
- <c:param name="pn" value="${param.pn}"/>
- </c:if>
- <c:if test="${not empty param.so}">
- <c:param name="so" value="${param.so}"/>
- </c:if>
- <c:if test="${not empty param.sc}">
- <c:param name="sc" value="${param.sc}"/>
- </c:if>
- <c:if test="${not empty param.resourceType}">
- <c:param name="resourceType" value="${param.resourceType}"/>
- </c:if>
- <c:if test="${not empty param.plugin}">
- <c:param name="plugin" value="${param.plugin}"/>
- </c:if>
- <c:param name="groupCategory" value="${GroupHubForm.groupCategory}"/>
- </c:url>
-
-
- <display:table items="${AllResources}" var="groupComposite" action="${sAction}"
- width="100%" cellspacing="0" cellpadding="0" styleId="resourceHub">
-
- <display:column width="1%" property="resourceGroup.id"
- title="<input type=\"checkbox\" onclick=\"ToggleAll(this, widgetProperties)\" name=\"listToggleAll\">"
- isLocalizedTitle="false" styleClass="ListCellCheckbox" headerStyleClass="ListHeaderCheckbox">
- <display:checkboxdecorator name="resources" onclick="ToggleSelection(this, widgetProperties)" styleClass="listMember"/>
- </display:column>
-
- <display:column width="5%" value="${groupComposite}" title="nbsp" nowrap="true">
- <display:group-quicknav-decorator/>
- </display:column>
-
- <c:choose>
- <c:when test="${GroupHubForm.groupCategory == 'COMPATIBLE'}">
- <display:column width="25%" property="resourceGroup.name" title="common.header.Group"
- isLocalizedTitle="true" sortAttr="groupName"
- href="/rhq/group/monitor/graphs.xhtml?category=${GroupHubForm.groupCategory}&groupId=${groupComposite.resourceGroup.id}"/>
- </c:when>
- <c:otherwise>
- <display:column width="25%" property="resourceGroup.name" title="common.header.Group"
- isLocalizedTitle="true" sortAttr="groupName"
- href="/rhq/group/inventory/view.xhtml?category=${GroupHubForm.groupCategory}&groupId=${groupComposite.resourceGroup.id}"/>
- </c:otherwise>
- </c:choose>
- <c:if test="${not empty resourceTypeTH}">
- <display:column width="15%" property="resourceGroup.resourceType.name" title="${resourceTypeTH}"
- isLocalizedTitle="false" sortAttr="resourceTypeName" />
- <display:column width="10%" property="resourceGroup.resourceType.plugin" title="${pluginTH}"
- isLocalizedTitle="false" sortAttr="res.resourceType.plugin" />
- </c:if>
-
- <display:column width="30%" property="resourceGroup.description"
- title="common.header.Description" sortAttr="groupDescription"/>
-
- <display:column width="10%" property="explicitFormatted" title="resource.common.monitor.visibility.ChildAvailabilityTH"
- headerStyleClass="ListHeaderCheckbox" valign="middle"
- sortAttr="explicitAvail"/>
-
- <display:column width="10%" property="implicitFormatted" title="resource.common.monitor.visibility.DescendentAvailabilityTH"
- headerStyleClass="ListHeaderCheckbox" valign="middle"
- sortAttr="implicitAvail"/>
-
- </display:table>
- <!-- / -->
-
- <c:url var="pageAction" value="/GroupHub.do">
- <c:if test="${not empty param.keywords}">
- <c:param name="keywords" value="${param.keywords}"/>
- </c:if>
- <c:if test="${not empty param.resourceType}">
- <c:param name="resourceType" value="${param.resourceType}"/>
- </c:if>
- <c:if test="${not empty param.plugin}">
- <c:param name="plugin" value="${param.plugin}"/>
- </c:if>
-
- <c:param name="groupCategory" value="${GroupHubForm.groupCategory}"/>
-
- <c:if test="${not empty param.so}">
- <c:param name="so" value="${param.so}"/>
- </c:if>
- <c:if test="${not empty param.sc}">
- <c:param name="sc" value="${param.sc}"/>
- </c:if>
-
- <c:if test="${not empty param.pn}">
- <c:param name="pn" value="${param.pn}"/>
- </c:if>
- <c:if test="${not empty param.ps}">
- <c:param name="ps" value="${param.ps}"/>
- </c:if>
- </c:url>
-
- <%-- I am a bit weary of this as the listNewUrl won't work in RHQ. --%>
- <tiles:insert definition=".toolbar.list">
- <tiles:put name="listNewUrl" value="/resource/platform/Inventory.do?mode=new"/>
- <tiles:put name="deleteOnly" value="true"/>
- <tiles:put name="pageList" beanName="AllResources"/>
- <tiles:put name="widgetInstanceName" beanName="widgetInstanceName"/>
- <tiles:put name="pageAction" beanName="pageAction"/>
- </tiles:insert>
-
- <html:hidden property="view"/>
- <html:hidden property="groupCategory"/>
-
- </html:form>
- <tiles:insert definition=".page.footer"/>
-
- <script type="text/javascript">
- clearIfAnyChecked();
- </script>
+<%@ page language="java" %>
+
+<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
+<%@ taglib uri="http://jakarta.apache.org/struts/tags-html-el" prefix="html" %>
+<%@ taglib uri="http://jakarta.apache.org/struts/tags-tiles" prefix="tiles" %>
+<%@ taglib uri="/WEB-INF/tld/display.tld" prefix="display" %>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
+<%@ taglib uri="/WEB-INF/tld/hq.tld" prefix="hq" %>
+
+<tiles:importAttribute name="nameSort" ignore="false" scope="page"/>
+<tiles:importAttribute name="typeSort" ignore="false"/>
+
+<script language="JavaScript" src="<html:rewrite page="/js/functions.js"/>" type="text/javascript"></script>
+<script language="JavaScript" src="<html:rewrite page="/js/listWidget.js"/>" type="text/javascript"></script>
+<c:set var="widgetInstanceName" value="listResources"/>
+<script type="text/javascript">
+ var pageData = new Array();
+ var FOO = "chart";
+ var LIST = "list";
+ var imagePath = "<html:rewrite page="/images/"/>";
+
+ initializeWidgetProperties('<c:out value="${widgetInstanceName}"/>');
+ widgetProperties = getWidgetProperties('<c:out value="${widgetInstanceName}"/>');
+</script>
+
+<hq:constant var="PLATFORM"
+ classname="org.rhq.core.domain.resource.ResourceCategory"
+ symbol="PLATFORM"/>
+<hq:constant var="SERVER"
+ classname="org.rhq.core.domain.resource.ResourceCategory"
+ symbol="SERVER"/>
+<hq:constant var="SERVICE"
+ classname="org.rhq.core.domain.resource.ResourceCategory"
+ symbol="SERVICE"/>
+
+<hq:constant var="COMPAT_GROUP"
+ classname="org.rhq.core.domain.resource.group.GroupCategory"
+ symbol="COMPATIBLE"/>
+<hq:constant var="MIXED_GROUP"
+ classname="org.rhq.core.domain.resource.group.GroupCategory"
+ symbol="MIXED"/>
+
+<c:choose>
+ <c:when test="${GroupHubForm.groupCategory == COMPAT_GROUP}">
+ <fmt:message var="resourceTypeTH" key="resource.hub.GroupTypeTH"/>
+ </c:when>
+ <%--
+ Since mixed groups don't have a resourceType, do NOT set the
+ resourceTypeTH, which will suppress the display of that column
+ for Mixed groups.
+ --%>
+</c:choose>
+
+
+<html:form method="GET" action="/GroupHub">
+ <html:hidden property="groupCategory" value="${GroupHubForm.groupCategory}"/>
+ <tiles:insert definition=".page.title.resource.hub">
+ <tiles:put name="titleName">
+ <c:out value="${navHierarchy}"/>
+ </tiles:put>
+ <tiles:put name="showSearch" value="true"/>
+ </tiles:insert>
+</html:form>
+
+
+<html:form method="GET" action="/resource/hub/RemoveGroup.do">
+
+ <c:if test="${not empty ResourceSummary}">
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="ResourceHubBlockTitle" width="100%">
+
+ <c:url var="platformUrl" value="/ResourceHub.do">
+ <c:param name="resourceCategory" value="${PLATFORM}"/>
+ </c:url>
+ <html:link href="${platformUrl}">
+ <fmt:message key="resource.hub.filter.platform"/>
+ ( <c:out value="${ResourceSummary.platformCount}"/> )
+ </html:link>
+ |
+
+ <c:url var="serverUrl" value="/ResourceHub.do">
+ <c:param name="resourceCategory" value="${SERVER}"/>
+ </c:url>
+ <html:link href="${serverUrl}">
+ <fmt:message key="resource.hub.filter.server"/>
+ ( <c:out value="${ResourceSummary.serverCount}"/> )
+ </html:link>
+ |
+
+ <c:url var="serviceUrl" value="/ResourceHub.do">
+ <c:param name="resourceCategory" value="${SERVICE}"/>
+ </c:url>
+ <html:link href="${serviceUrl}">
+ <fmt:message key="resource.hub.filter.service"/>
+ ( <c:out value="${ResourceSummary.serviceCount}"/> )
+ </html:link>
+ |
+
+ <c:choose>
+ <c:when test="${GroupHubForm.groupCategory == COMPAT_GROUP}">
+ <fmt:message key="resource.hub.filter.compatibleGroups"/>
+ ( <c:out value="${ResourceSummary.compatibleGroupCount}"/> )
+ </c:when>
+ <c:otherwise>
+ <c:url var="groupUrl" value="/GroupHub.do">
+ <c:param name="groupCategory" value="${COMPAT_GROUP}"/>
+ </c:url>
+ <html:link href="${groupUrl}">
+ <fmt:message key="resource.hub.filter.compatibleGroups"/>
+ ( <c:out value="${ResourceSummary.compatibleGroupCount}"/> )
+ </html:link>
+ </c:otherwise>
+ </c:choose>
+ |
+ <c:choose>
+ <c:when test="${GroupHubForm.groupCategory == MIXED_GROUP}">
+ <fmt:message key="resource.hub.filter.mixedGroups"/>
+ ( <c:out value="${ResourceSummary.mixedGroupCount}"/> )
+ </c:when>
+ <c:otherwise>
+ <c:url var="groupUrl" value="/GroupHub.do">
+ <c:param name="groupCategory" value="${MIXED_GROUP}"/>
+ </c:url>
+ <html:link href="${groupUrl}">
+ <fmt:message key="resource.hub.filter.mixedGroups"/>
+ ( <c:out value="${ResourceSummary.mixedGroupCount}"/> )
+ </html:link>
+ </c:otherwise>
+ </c:choose>
+ |
+ <html:link href="/rhq/definition/group/list.xhtml">
+ <fmt:message key="resource.hub.filter.groupDefinitions"/>
+ ( <c:out value="${ResourceSummary.groupDefinitionCount}"/> )
+ </html:link>
+ </td>
+ </tr>
+ </table>
+ </c:if>
+
+ <fmt:message var="pluginTH" key="resource.hub.PluginTH"/>
+
+ <tiles:insert definition=".portlet.confirm"/>
+ <tiles:insert definition=".portlet.error"/>
+
+ <!-- FILTER TOOLBAR CONTENTS -->
+
+ <c:url var="resourceTypeAction" value="/GroupHub.do">
+ <c:if test="${not empty param.keywords}">
+ <c:param name="keywords" value="${param.keywords}"/>
+ </c:if>
+ <c:if test="${not empty param.ps}">
+ <c:param name="ps" value="${param.ps}"/>
+ </c:if>
+ <c:if test="${not empty param.so}">
+ <c:param name="so" value="${param.so}"/>
+ </c:if>
+ <c:if test="${not empty param.sc}">
+ <c:param name="sc" value="${param.sc}"/>
+ </c:if>
+ <c:if test="${not empty param.plugin}">
+ <c:param name="plugin" value="${param.plugin}"/>
+ </c:if>
+ <c:param name="groupCategory" value="${GroupHubForm.groupCategory}"/>
+ </c:url>
+ <c:url var="pluginAction" value="/GroupHub.do">
+ <c:if test="${not empty param.keywords}">
+ <c:param name="keywords" value="${param.keywords}"/>
+ </c:if>
+ <c:if test="${not empty param.ps}">
+ <c:param name="ps" value="${param.ps}"/>
+ </c:if>
+ <c:if test="${not empty param.so}">
+ <c:param name="so" value="${param.so}"/>
+ </c:if>
+ <c:if test="${not empty param.sc}">
+ <c:param name="sc" value="${param.sc}"/>
+ </c:if>
+ <c:if test="${not empty param.resourceType}">
+ <c:param name="resourceType" value="${param.resourceType}"/>
+ </c:if>
+ <c:param name="groupCategory" value="${GroupHubForm.groupCategory}"/>
+ </c:url>
+
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="FilterLine" colspan="3">
+ <html:img page="/images/spacer.gif" width="1" height="1" border="0"/>
+ </td>
+ </tr>
+ <tr>
+ <td class="FilterLabelText" nowrap="nowrap" align="right">
+ <c:choose>
+ <c:when test="${GroupHubForm.types == null}">
+ <html:hidden property="resourceType" value=""/>
+
+ </c:when>
+ <c:otherwise>
+ <fmt:message key="Filter.ViewLabel"/>
+ </td>
+ <td class="FilterLabelText">
+ <html:select property="resourceType" styleClass="FilterFormText" size="1"
+ onchange="goToSelectLocation(this, 'resourceType', '${resourceTypeAction}');">
+ <html:optionsCollection property="types"/>
+ </html:select>
+ </c:otherwise>
+ </c:choose>
+ </td>
+ <td class="FilterLabelText" width="100%">
+ <c:choose>
+ <c:when test="${GroupHubForm.plugins == null}">
+ <html:hidden property="plugin" value=""/>
+
+ </c:when>
+ <c:otherwise>
+ <html:select property="plugin" styleClass="FilterFormText" size="1"
+ onchange="goToSelectLocation(this, 'plugin', '${pluginAction}');">
+ <html:optionsCollection property="plugins"/>
+ </html:select>
+ </c:otherwise>
+ </c:choose>
+ </td>
+
+ <c:url var="viewAction" value="/GroupHub.do">
+ <c:if test="${not empty param.keywords}">
+ <c:param name="keywords" value="${param.keywords}"/>
+ </c:if>
+ <c:if test="${not empty param.pn}">
+ <c:param name="pn" value="${param.pn}"/>
+ </c:if>
+ <c:if test="${not empty param.so}">
+ <c:param name="so" value="${param.so}"/>
+ </c:if>
+ <c:if test="${not empty param.sc}">
+ <c:param name="sc" value="${param.sc}"/>
+ </c:if>
+ <c:if test="${not empty param.resourceType}">
+ <c:param name="resourceType" value="${param.resourceType}"/>
+ </c:if>
+ <c:if test="${not empty param.plugin}">
+ <c:param name="plugin" value="${param.plugin}"/>
+ </c:if>
+
+ <c:param name="groupCategory" value="${GroupHubForm.groupCategory}"/>
+ </c:url>
+
+ </tr>
+ </table>
+ <!-- / -->
+
+ <!-- GROUP HUB CONTENTS -->
+ <c:url var="sAction" value="/GroupHub.do">
+ <c:if test="${not empty param.keywords}">
+ <c:param name="keywords" value="${param.keywords}"/>
+ </c:if>
+ <c:if test="${not empty param.ps}">
+ <c:param name="ps" value="${param.ps}"/>
+ </c:if>
+ <c:if test="${not empty param.pn}">
+ <c:param name="pn" value="${param.pn}"/>
+ </c:if>
+ <c:if test="${not empty param.so}">
+ <c:param name="so" value="${param.so}"/>
+ </c:if>
+ <c:if test="${not empty param.sc}">
+ <c:param name="sc" value="${param.sc}"/>
+ </c:if>
+ <c:if test="${not empty param.resourceType}">
+ <c:param name="resourceType" value="${param.resourceType}"/>
+ </c:if>
+ <c:if test="${not empty param.plugin}">
+ <c:param name="plugin" value="${param.plugin}"/>
+ </c:if>
+ <c:param name="groupCategory" value="${GroupHubForm.groupCategory}"/>
+ </c:url>
+
+
+ <display:table items="${AllResources}" var="groupComposite" action="${sAction}"
+ width="100%" cellspacing="0" cellpadding="0" styleId="resourceHub">
+
+ <display:column width="1%" property="resourceGroup.id"
+ title="<input type=\"checkbox\" onclick=\"ToggleAll(this, widgetProperties)\" name=\"listToggleAll\">"
+ isLocalizedTitle="false" styleClass="ListCellCheckbox" headerStyleClass="ListHeaderCheckbox">
+ <display:checkboxdecorator name="resources" onclick="ToggleSelection(this, widgetProperties)" styleClass="listMember"/>
+ </display:column>
+
+ <display:column width="5%" value="${groupComposite}" title="nbsp" nowrap="true">
+ <display:group-quicknav-decorator/>
+ </display:column>
+
+ <c:choose>
+ <c:when test="${GroupHubForm.groupCategory == 'COMPATIBLE'}">
+ <display:column width="25%" property="resourceGroup.name" title="common.header.Group"
+ isLocalizedTitle="true" sortAttr="groupName"
+ href="/rhq/group/monitor/graphs.xhtml?category=${GroupHubForm.groupCategory}&groupId=${groupComposite.resourceGroup.id}"/>
+ </c:when>
+ <c:otherwise>
+ <display:column width="25%" property="resourceGroup.name" title="common.header.Group"
+ isLocalizedTitle="true" sortAttr="groupName"
+ href="/rhq/group/inventory/view.xhtml?category=${GroupHubForm.groupCategory}&groupId=${groupComposite.resourceGroup.id}"/>
+ </c:otherwise>
+ </c:choose>
+ <c:if test="${not empty resourceTypeTH}">
+ <display:column width="15%" property="resourceGroup.resourceType.name" title="${resourceTypeTH}"
+ isLocalizedTitle="false" sortAttr="resourceTypeName" />
+ <display:column width="10%" property="resourceGroup.resourceType.plugin" title="${pluginTH}"
+ isLocalizedTitle="false" sortAttr="res.resourceType.plugin" />
+ </c:if>
+
+ <display:column width="30%" property="resourceGroup.description"
+ title="common.header.Description" sortAttr="groupDescription"/>
+
+ <display:column width="10%" property="explicitFormatted" title="resource.common.monitor.visibility.ChildAvailabilityTH"
+ headerStyleClass="ListHeaderCheckbox" valign="middle"
+ sortAttr="explicitAvail"/>
+
+ <display:column width="10%" property="implicitFormatted" title="resource.common.monitor.visibility.DescendentAvailabilityTH"
+ headerStyleClass="ListHeaderCheckbox" valign="middle"
+ sortAttr="implicitAvail"/>
+
+ </display:table>
+ <!-- / -->
+
+ <c:url var="pageAction" value="/GroupHub.do">
+ <c:if test="${not empty param.keywords}">
+ <c:param name="keywords" value="${param.keywords}"/>
+ </c:if>
+ <c:if test="${not empty param.resourceType}">
+ <c:param name="resourceType" value="${param.resourceType}"/>
+ </c:if>
+ <c:if test="${not empty param.plugin}">
+ <c:param name="plugin" value="${param.plugin}"/>
+ </c:if>
+
+ <c:param name="groupCategory" value="${GroupHubForm.groupCategory}"/>
+
+ <c:if test="${not empty param.so}">
+ <c:param name="so" value="${param.so}"/>
+ </c:if>
+ <c:if test="${not empty param.sc}">
+ <c:param name="sc" value="${param.sc}"/>
+ </c:if>
+
+ <c:if test="${not empty param.pn}">
+ <c:param name="pn" value="${param.pn}"/>
+ </c:if>
+ <c:if test="${not empty param.ps}">
+ <c:param name="ps" value="${param.ps}"/>
+ </c:if>
+ </c:url>
+
+ <%-- I am a bit weary of this as the listNewUrl won't work in RHQ. --%>
+ <tiles:insert definition=".toolbar.list">
+ <tiles:put name="listNewUrl" value="/resource/platform/Inventory.do?mode=new"/>
+ <tiles:put name="deleteOnly" value="true"/>
+ <tiles:put name="pageList" beanName="AllResources"/>
+ <tiles:put name="widgetInstanceName" beanName="widgetInstanceName"/>
+ <tiles:put name="pageAction" beanName="pageAction"/>
+ </tiles:insert>
+
+ <html:hidden property="view"/>
+ <html:hidden property="groupCategory"/>
+
+ </html:form>
+ <tiles:insert definition=".page.footer"/>
+
+ <script type="text/javascript">
+ clearIfAnyChecked();
+ </script>
14 years, 3 months
[rhq] Branch 'gwt' - 2 commits - modules/core modules/enterprise
by Greg Hinkle
modules/core/domain/src/main/java/org/rhq/core/domain/configuration/ResourceConfigurationUpdate.java | 4
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RoleEditView.java | 25 -
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RoleGroupsEditorItem.java | 6
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RolesDataSource.java | 42 +-
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/SubjectRolesEditorItem.java | 2
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UserEditView.java | 22 -
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersDataSource.java | 57 +--
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertDataSource.java | 42 +-
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java | 1
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ConfigurationGWTService.java | 5
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupListView.java | 2
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupsDataSource.java | 60 +--
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/definitions/GroupDefinitionDataSource.java | 42 +-
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceDatasource.java | 46 +-
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java | 3
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ConfigurationHistoryDataSource.java | 109 ++++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ConfigurationHistoryView.java | 162 ++++++++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/operation/OperationWizard.java | 69 ++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/menu/MenuBarView.java | 49 +--
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/menu/SearchBarPane.java | 73 ++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java | 41 ++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/preferences/UserPreferences.java | 2
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ConfigurationGWTServiceImpl.java | 24 +
modules/enterprise/gui/coregui/src/main/webapp/images/Favorite_24.png |binary
modules/enterprise/gui/coregui/src/main/webapp/images/Favorite_24_Selected.png |binary
modules/enterprise/gui/coregui/src/main/webapp/images/resources/Service_down_24.png |binary
modules/enterprise/gui/coregui/src/main/webapp/images/resources/Service_up_24.png |binary
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java | 4
28 files changed, 651 insertions(+), 241 deletions(-)
New commits:
commit 5ca5a668de1183a2425231d7066910183e203c28
Author: Greg Hinkle <ghinkle(a)redhat.com>
Date: Thu Mar 4 02:16:58 2010 -0500
some icon migration
diff --git a/modules/enterprise/gui/coregui/src/main/webapp/images/Favorite_24.png b/modules/enterprise/gui/coregui/src/main/webapp/images/Favorite_24.png
new file mode 100644
index 0000000..c87e683
Binary files /dev/null and b/modules/enterprise/gui/coregui/src/main/webapp/images/Favorite_24.png differ
diff --git a/modules/enterprise/gui/coregui/src/main/webapp/images/Favorite_24_Selected.png b/modules/enterprise/gui/coregui/src/main/webapp/images/Favorite_24_Selected.png
new file mode 100644
index 0000000..0772dc7
Binary files /dev/null and b/modules/enterprise/gui/coregui/src/main/webapp/images/Favorite_24_Selected.png differ
diff --git a/modules/enterprise/gui/coregui/src/main/webapp/images/resources/Service_down_24.png b/modules/enterprise/gui/coregui/src/main/webapp/images/resources/Service_down_24.png
new file mode 100644
index 0000000..24b1d98
Binary files /dev/null and b/modules/enterprise/gui/coregui/src/main/webapp/images/resources/Service_down_24.png differ
diff --git a/modules/enterprise/gui/coregui/src/main/webapp/images/resources/Service_up_24.png b/modules/enterprise/gui/coregui/src/main/webapp/images/resources/Service_up_24.png
new file mode 100644
index 0000000..7df5599
Binary files /dev/null and b/modules/enterprise/gui/coregui/src/main/webapp/images/resources/Service_up_24.png differ
commit a1dfc9958fd77f22674e89630ed73d884b78156e
Author: Greg Hinkle <ghinkle(a)redhat.com>
Date: Thu Mar 4 02:15:47 2010 -0500
RPCDataSource enhancements
Config History view
toolstrip width fix for sgwt 2.1
security fix in config manager
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/ResourceConfigurationUpdate.java b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/ResourceConfigurationUpdate.java
index 7d3ce29..3825097 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/ResourceConfigurationUpdate.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/configuration/ResourceConfigurationUpdate.java
@@ -189,8 +189,8 @@ public class ResourceConfigurationUpdate extends AbstractResourceConfigurationUp
@ManyToOne
private GroupResourceConfigurationUpdate groupConfigurationUpdate;
- protected ResourceConfigurationUpdate() {
- } // JPA
+ public ResourceConfigurationUpdate() {
+ }
public ResourceConfigurationUpdate(Resource resource, Configuration config, String subjectName) {
super(config, subjectName);
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RoleEditView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RoleEditView.java
index a6b8bd8..8d4025e 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RoleEditView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RoleEditView.java
@@ -24,8 +24,6 @@ import org.rhq.core.domain.resource.group.ResourceGroup;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.gui.coregui.client.components.HeaderLabel;
-import com.smartgwt.client.data.Criteria;
-import com.smartgwt.client.data.DataSource;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.types.DSOperationType;
import com.smartgwt.client.types.Overflow;
@@ -34,10 +32,7 @@ import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.events.SubmitValuesEvent;
import com.smartgwt.client.widgets.form.events.SubmitValuesHandler;
-import com.smartgwt.client.widgets.form.fields.CanvasItem;
-import com.smartgwt.client.widgets.form.fields.FormItem;
import com.smartgwt.client.widgets.form.fields.ResetItem;
-import com.smartgwt.client.widgets.form.fields.SectionItem;
import com.smartgwt.client.widgets.form.fields.SubmitItem;
import com.smartgwt.client.widgets.form.fields.TextItem;
import com.smartgwt.client.widgets.form.fields.events.ClickEvent;
@@ -45,8 +40,6 @@ import com.smartgwt.client.widgets.form.fields.events.ClickHandler;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.layout.VLayout;
-import java.util.HashMap;
-import java.util.HashSet;
import java.util.Set;
/**
@@ -105,7 +98,6 @@ public class RoleEditView extends VLayout {
permissionEditorItem.setColSpan(2);
-
assignedGroupEditorItem = new RoleGroupsEditorItem("assignedGroups", "Assigned Groups");
assignedGroupEditorItem.setShowTitle(false);
assignedGroupEditorItem.setColSpan(2);
@@ -163,29 +155,14 @@ public class RoleEditView extends VLayout {
}
public void editNew() {
- ListGridRecord r = new ListGridRecord();
- Role newRole = new Role(null); // todo make default constructor public
- RolesDataSource.copyValues(newRole, r);
+ ListGridRecord r = RolesDataSource.getInstance().copyValues(new Role());
editRecord(r);
form.setSaveOperationType(DSOperationType.ADD);
-//
-// HashSet<Permission> permissions = new HashSet<Permission>();
-// HashMap values = new HashMap();
-// values.put("permssions", permissions);
-//
-// form.editNewRecord();
-
-
editLabel.setContents("Create Role");
-// permissionEditorItem.setPermissions(permissions);
-
-// message.hide();
-// editCanvas.show();
}
-
public void save() {
System.out.println("Saving role");
form.saveData();
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RoleGroupsEditorItem.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RoleGroupsEditorItem.java
index 6eff51e..59ebf1c 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RoleGroupsEditorItem.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RoleGroupsEditorItem.java
@@ -57,7 +57,7 @@ public class RoleGroupsEditorItem extends CanvasItem {
availableGroupGrid.setCanDragRecordsOut(true);
availableGroupGrid.setDragTrackerMode(DragTrackerMode.RECORD);
availableGroupGrid.setDragDataAction(DragDataAction.MOVE);
- availableGroupGrid.setDataSource(new ResourceGroupsDataSource());
+ availableGroupGrid.setDataSource(ResourceGroupsDataSource.getInstance());
availableGroupGrid.setAutoFetchData(true);
availableGroupGrid.setFields(new ListGridField("id",50), new ListGridField("name"));
@@ -82,7 +82,7 @@ public class RoleGroupsEditorItem extends CanvasItem {
assignedGroupGrid.setHeight(350);
assignedGroupGrid.setCanDragRecordsOut(true);
assignedGroupGrid.setCanAcceptDroppedRecords(true);
- assignedGroupGrid.setDataSource(new ResourceGroupsDataSource());
+ assignedGroupGrid.setDataSource(ResourceGroupsDataSource.getInstance());
assignedGroupGrid.setFields(new ListGridField("id", 50), new ListGridField("name"));
layout.addMember(assignedGroupGrid);
@@ -94,7 +94,7 @@ public class RoleGroupsEditorItem extends CanvasItem {
public void setGroups(PageList<ResourceGroup> assignedGroups) {
this.assignedGroups = assignedGroups;
- assignedGroupGrid.setData(ResourceGroupsDataSource.buildRecords(assignedGroups));
+ assignedGroupGrid.setData(ResourceGroupsDataSource.getInstance().buildRecords(assignedGroups));
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RolesDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RolesDataSource.java
index 6f8894b..3a7de7f 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RolesDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RolesDataSource.java
@@ -44,19 +44,18 @@ import com.smartgwt.client.widgets.grid.ListGridRecord;
import java.util.Collection;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author Greg Hinkle
*/
-public class RolesDataSource extends RPCDataSource {
-
- private static RolesDataSource INSTANCE;
+public class RolesDataSource extends RPCDataSource<Role> {
private RoleGWTServiceAsync roleService = GWTServiceLookup.getRoleService();
+ private static RolesDataSource INSTANCE;
+
public static RolesDataSource getInstance() {
if (INSTANCE == null) {
INSTANCE = new RolesDataSource();
@@ -64,7 +63,7 @@ public class RolesDataSource extends RPCDataSource {
return INSTANCE;
}
- protected RolesDataSource() {
+ private RolesDataSource() {
super("Roles");
DataSourceField idDataField = new DataSourceIntegerField("id", "ID");
@@ -108,10 +107,7 @@ public class RolesDataSource extends RPCDataSource {
ListGridRecord[] records = new ListGridRecord[result.size()];
for (int x = 0; x < result.size(); x++) {
Role role = result.get(x);
- ListGridRecord record = new ListGridRecord();
-
- copyValues(role, record);
-
+ ListGridRecord record = copyValues(role);
records[x] = record;
}
@@ -127,8 +123,7 @@ public class RolesDataSource extends RPCDataSource {
protected void executeAdd(final DSRequest request, final DSResponse response) {
JavaScriptObject data = request.getData();
final ListGridRecord rec = new ListGridRecord(data);
- Role newRole = new Role("newName"); // TODO GH: Make default constructor public
- copyValues(rec, newRole);
+ Role newRole = copyValues(rec);
roleService.createRole(newRole, new AsyncCallback<Role>() {
public void onFailure(Throwable caught) {
@@ -142,8 +137,7 @@ public class RolesDataSource extends RPCDataSource {
public void onSuccess(Role result) {
ListGridRecord record = new ListGridRecord();
- copyValues(result,record);
- response.setData(new Record[] {record});
+ response.setData(new Record[] {copyValues(result)});
processResponse(request.getRequestId(),response);
}
});
@@ -154,8 +148,7 @@ public class RolesDataSource extends RPCDataSource {
protected void executeUpdate(final DSRequest request, final DSResponse response) {
final ListGridRecord record = getEditedRecord(request);
System.out.println("Updating record: " + record);
- Role updatedRole = new Role("foo");
- copyValues(record, updatedRole);
+ Role updatedRole = copyValues(record);
roleService.updateRole(updatedRole, new AsyncCallback<Role>() {
public void onFailure(Throwable caught) {
CoreGUI.getErrorHandler().handleError("Failed to update role",caught);
@@ -163,8 +156,7 @@ public class RolesDataSource extends RPCDataSource {
public void onSuccess(Role result) {
System.out.println("Role Updated");
- copyValues(result,record);
- response.setData(new Record[] {record});
+ response.setData(new Record[] {copyValues(result)});
processResponse(request.getRequestId(),response);
}
});
@@ -174,8 +166,7 @@ public class RolesDataSource extends RPCDataSource {
protected void executeRemove(final DSRequest request, final DSResponse response) {
JavaScriptObject data = request.getData();
final ListGridRecord rec = new ListGridRecord(data);
- Role newRole = new Role("newName"); // TODO GH: Make default constructor public
- copyValues(rec, newRole);
+ Role newRole = copyValues(rec);
roleService.removeRoles(new Integer[]{newRole.getId()}, new AsyncCallback<Void>() {
public void onFailure(Throwable caught) {
@@ -191,7 +182,8 @@ public class RolesDataSource extends RPCDataSource {
}
- private static void copyValues(ListGridRecord from, Role to) {
+ public Role copyValues(ListGridRecord from) {
+ Role to = new Role();
to.setId(from.getAttributeAsInt("id"));
to.setName(from.getAttributeAsString("name"));
// to.setDate (from.getAttributeAsDate ("date"));
@@ -199,9 +191,11 @@ public class RolesDataSource extends RPCDataSource {
to.setResourceGroups((Set<ResourceGroup>) from.getAttributeAsObject("resourceGroups"));
to.setPermissions((Set<Permission>) from.getAttributeAsObject("permissions"));
to.setSubjects((Set<Subject>) from.getAttributeAsObject("subjects"));
+ return to;
}
- static void copyValues(Role from, ListGridRecord to) {
+ public ListGridRecord copyValues(Role from) {
+ ListGridRecord to = new ListGridRecord();
to.setAttribute("id", from.getId());
to.setAttribute("name", from.getName());
to.setAttribute("resourceGroups", from.getResourceGroups());
@@ -209,6 +203,7 @@ public class RolesDataSource extends RPCDataSource {
to.setAttribute("subjects", from.getSubjects());
to.setAttribute("entity", from);
+ return to;
}
@@ -226,12 +221,11 @@ public class RolesDataSource extends RPCDataSource {
return newRecord;
}
- public static ListGridRecord[] buildRecords(Collection<Role> roles) {
+ public ListGridRecord[] buildRecords(Collection<Role> roles) {
ListGridRecord[] roleRecords = new ListGridRecord[roles.size()];
int i = 0;
for (Role role : roles) {
- ListGridRecord record = new ListGridRecord();
- copyValues(role, record);
+ ListGridRecord record = copyValues(role);
roleRecords[i++] = record;
}
return roleRecords;
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/SubjectRolesEditorItem.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/SubjectRolesEditorItem.java
index ab61eac..72fc465 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/SubjectRolesEditorItem.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/SubjectRolesEditorItem.java
@@ -106,7 +106,7 @@ public class SubjectRolesEditorItem extends CanvasItem {
public void setRoles(Set<Role> assignedRoles) {
this.assignedRoles = assignedRoles;
- assignedRoleGrid.setData(RolesDataSource.buildRecords(assignedRoles));
+ assignedRoleGrid.setData(RolesDataSource.getInstance().buildRecords(assignedRoles));
}
public Set<Role> getRoles() {
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UserEditView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UserEditView.java
index 1b74870..8f0429c 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UserEditView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UserEditView.java
@@ -20,21 +20,13 @@ package org.rhq.enterprise.gui.coregui.client.admin.users;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.authz.Role;
-import org.rhq.enterprise.gui.coregui.client.admin.roles.RolesDataSource;
-import org.rhq.enterprise.gui.coregui.client.admin.roles.RolesView;
import org.rhq.enterprise.gui.coregui.client.components.HeaderLabel;
-import com.google.gwt.user.client.ui.Widget;
-import com.smartgwt.client.data.Criteria;
import com.smartgwt.client.data.Record;
-import com.smartgwt.client.docs.FormLayout;
import com.smartgwt.client.types.DSOperationType;
-import com.smartgwt.client.types.VisibilityMode;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.form.DynamicForm;
-import com.smartgwt.client.widgets.form.fields.BooleanItem;
-import com.smartgwt.client.widgets.form.fields.FormItem;
import com.smartgwt.client.widgets.form.fields.ResetItem;
import com.smartgwt.client.widgets.form.fields.SectionItem;
import com.smartgwt.client.widgets.form.fields.SubmitItem;
@@ -42,12 +34,8 @@ import com.smartgwt.client.widgets.form.fields.TextItem;
import com.smartgwt.client.widgets.form.fields.events.ClickEvent;
import com.smartgwt.client.widgets.form.fields.events.ClickHandler;
import com.smartgwt.client.widgets.grid.ListGridRecord;
-import com.smartgwt.client.widgets.layout.HLayout;
-import com.smartgwt.client.widgets.layout.SectionStack;
-import com.smartgwt.client.widgets.layout.SectionStackSection;
import com.smartgwt.client.widgets.layout.VLayout;
-import java.util.List;
import java.util.Set;
/**
@@ -64,6 +52,8 @@ public class UserEditView extends VLayout {
private HeaderLabel editLabel;
private DynamicForm form;
+ private UsersDataSource dataSource;
+
private Subject subject;
@Override
@@ -107,10 +97,10 @@ public class UserEditView extends VLayout {
// form.setField//s(userEditSection);
- UsersDataSource ds = UsersDataSource.getInstance();
+ dataSource = UsersDataSource.getInstance();
form.setUseAllDataSourceFields(true);
- form.setDataSource(ds);
+ form.setDataSource(dataSource);
subjectRolesEditorItem = new SubjectRolesEditorItem("rolesEditor","Assigned Roles");
@@ -162,9 +152,7 @@ public class UserEditView extends VLayout {
public void editNew() {
form.getDataSource().getField("username").setCanEdit(true);
- ListGridRecord r = new ListGridRecord();
- Subject subject = new Subject(); // todo make default constructor public
- UsersDataSource.copyValues(subject, r);
+ ListGridRecord r = dataSource.copyValues(subject);
editRecord(r);
form.setSaveOperationType(DSOperationType.ADD);
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersDataSource.java
index 8e88e06..b874fe7 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersDataSource.java
@@ -54,7 +54,7 @@ import java.util.Set;
/**
* @author Greg Hinkle
*/
-public class UsersDataSource extends RPCDataSource {
+public class UsersDataSource extends RPCDataSource<Subject> {
private static UsersDataSource INSTANCE;
@@ -69,7 +69,7 @@ public class UsersDataSource extends RPCDataSource {
}
- protected UsersDataSource() {
+ private UsersDataSource() {
super("Users");
DataSourceField idDataField = new DataSourceIntegerField("id", "ID");
@@ -137,11 +137,8 @@ public class UsersDataSource extends RPCDataSource {
ListGridRecord[] records = new ListGridRecord[result.size()];
for (int x = 0; x < result.size(); x++) {
Subject subject = result.get(x);
- ListGridRecord record = new ListGridRecord();
- copyValues(subject, record);
-
- records[x] = record;
+ records[x] = copyValues(subject);
}
response.setData(records);
@@ -152,18 +149,16 @@ public class UsersDataSource extends RPCDataSource {
}
-
- @Override
+ @Override
protected void executeAdd(final DSRequest request, final DSResponse response) {
JavaScriptObject data = request.getData();
final ListGridRecord rec = new ListGridRecord(data);
- Subject newSubject = new Subject();
- copyValues(rec, newSubject);
+ Subject newSubject = copyValues(rec);
subjectService.createSubject(newSubject, new AsyncCallback<Subject>() {
public void onFailure(Throwable caught) {
// TODO better exceptions so we can set the right validation errors
- Map<String,String> errors = new HashMap<String, String>();
+ Map<String, String> errors = new HashMap<String, String>();
errors.put("username", "A user with this name already exists.");
response.setErrors(errors);
// CoreGUI.getErrorHandler().handleError("Failed to create role",caught);
@@ -172,10 +167,8 @@ public class UsersDataSource extends RPCDataSource {
}
public void onSuccess(Subject result) {
- ListGridRecord record = new ListGridRecord();
- copyValues(result,record);
- response.setData(new Record[] {record});
- processResponse(request.getRequestId(),response);
+ response.setData(new Record[]{copyValues(result)});
+ processResponse(request.getRequestId(), response);
}
});
@@ -185,11 +178,10 @@ public class UsersDataSource extends RPCDataSource {
protected void executeUpdate(final DSRequest request, final DSResponse response) {
final ListGridRecord record = getEditedRecord(request);
System.out.println("Updating record: " + record);
- final Subject updatedSubject = new Subject();
- copyValues(record, updatedSubject);
+ final Subject updatedSubject = copyValues(record);
subjectService.updateSubject(updatedSubject, new AsyncCallback<Subject>() {
public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError("Failed to update subject",caught);
+ CoreGUI.getErrorHandler().handleError("Failed to update subject", caught);
}
public void onSuccess(final Subject result) {
@@ -198,22 +190,20 @@ public class UsersDataSource extends RPCDataSource {
if (password != null) {
subjectService.changePassword(updatedSubject.getName(), password, new AsyncCallback<Void>() {
public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError("Failed to update subject's password",caught);
+ CoreGUI.getErrorHandler().handleError("Failed to update subject's password", caught);
}
public void onSuccess(Void nothing) {
System.out.println("Subject Updated");
- copyValues(result,record);
- response.setData(new Record[] {record});
- processResponse(request.getRequestId(),response);
+ response.setData(new Record[]{copyValues(result)});
+ processResponse(request.getRequestId(), response);
}
});
} else {
System.out.println("Subject Updated");
- copyValues(result,record);
- response.setData(new Record[] {record});
- processResponse(request.getRequestId(),response);
+ response.setData(new Record[]{copyValues(result)});
+ processResponse(request.getRequestId(), response);
}
}
});
@@ -223,12 +213,11 @@ public class UsersDataSource extends RPCDataSource {
protected void executeRemove(final DSRequest request, final DSResponse response) {
JavaScriptObject data = request.getData();
final ListGridRecord rec = new ListGridRecord(data);
- Subject subjectToDelete = new Subject(); // TODO GH: Make default constructor public
- copyValues(rec, subjectToDelete);
+ Subject subjectToDelete = copyValues(rec);
subjectService.deleteSubjects(new int[]{subjectToDelete.getId()}, new AsyncCallback<Void>() {
public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError("Failed to delete role",caught);
+ CoreGUI.getErrorHandler().handleError("Failed to delete role", caught);
}
public void onSuccess(Void result) {
@@ -241,8 +230,8 @@ public class UsersDataSource extends RPCDataSource {
}
-
- private static void copyValues(ListGridRecord from, Subject to) {
+ public Subject copyValues(ListGridRecord from) {
+ Subject to = new Subject();
to.setId(from.getAttributeAsInt("id"));
to.setName(from.getAttributeAsString("username"));
to.setFirstName(from.getAttributeAsString("firstName"));
@@ -253,9 +242,11 @@ public class UsersDataSource extends RPCDataSource {
to.setEmailAddress(from.getAttributeAsString("email"));
to.setRoles((Set<Role>) from.getAttributeAsObject("roles"));
+ return to;
}
- static void copyValues(Subject from, ListGridRecord to) {
+ public ListGridRecord copyValues(Subject from) {
+ ListGridRecord to = new ListGridRecord();
to.setAttribute("id", from.getId());
to.setAttribute("username", from.getName());
to.setAttribute("firstName", from.getFirstName());
@@ -265,13 +256,13 @@ public class UsersDataSource extends RPCDataSource {
to.setAttribute("phoneNumber", from.getPhoneNumber());
to.setAttribute("email", from.getEmailAddress());
- to.setAttribute("roles",from.getRoles());
+ to.setAttribute("roles", from.getRoles());
to.setAttribute("entity", from);
+ return to;
}
-
private ListGridRecord getEditedRecord(DSRequest request) {
// Retrieving values before edit
JavaScriptObject oldValues = request.getAttributeAsJavaScriptObject("oldValues");
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertDataSource.java
index c21d00a..cdbe515 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertDataSource.java
@@ -49,7 +49,7 @@ import java.util.Set;
*
* @author Ian Springer
*/
-public class AlertDataSource extends RPCDataSource {
+public class AlertDataSource extends RPCDataSource<Alert> {
private static final String NAME = "Alert";
private static final DateTimeFormat DATE_TIME_FORMAT = DateTimeFormat.getMediumDateTimeFormat();
@@ -146,14 +146,7 @@ public class AlertDataSource extends RPCDataSource {
long fetchTime = System.currentTimeMillis() - start;
System.out.println(result.size() + " Alerts fetched in: " + fetchTime + "ms");
- ListGridRecord[] records = new ListGridRecord[result.size()];
- for (int i = 0; i < result.size(); i++) {
- Alert alert = result.get(i);
- ListGridRecord record = createRecord(alert);
- records[i] = record;
- }
-
- response.setData(records);
+ response.setData(buildRecords(result));
// For paging to work, we have to specify size of full result set.
response.setTotalRows(result.getTotalSize());
processResponse(request.getRequestId(), response);
@@ -161,21 +154,21 @@ public class AlertDataSource extends RPCDataSource {
});
}
- protected void executeRemove(final DSRequest request, final DSResponse response) {
- JavaScriptObject data = request.getData ();
- ListGridRecord record = new ListGridRecord(data);
- Window.alert(String.valueOf(record.getAttributeAsInt("id")));
+ @Override
+ public Alert copyValues(ListGridRecord from) {
+ return null; // TODO: Implement this method.
}
- private ListGridRecord createRecord(Alert alert) {
+ @Override
+ public ListGridRecord copyValues(Alert from) {
ListGridRecord record = new ListGridRecord();
- record.setAttribute("id", alert.getId());
- record.setAttribute("resourceId", alert.getAlertDefinition().getResource().getId());
- record.setAttribute("name", alert.getAlertDefinition().getName());
- record.setAttribute("priority", alert.getAlertDefinition().getPriority().name());
- record.setAttribute("ctime", DATE_TIME_FORMAT.format(new Date(alert.getCtime())));
+ record.setAttribute("id", from.getId());
+ record.setAttribute("resourceId", from.getAlertDefinition().getResource().getId());
+ record.setAttribute("name", from.getAlertDefinition().getName());
+ record.setAttribute("priority", from.getAlertDefinition().getPriority().name());
+ record.setAttribute("ctime", DATE_TIME_FORMAT.format(new Date(from.getCtime())));
- Set<AlertConditionLog> conditionLogs = alert.getConditionLogs();
+ Set<AlertConditionLog> conditionLogs = from.getConditionLogs();
String conditionText;
String conditionValue;
if (conditionLogs.size() > 1) {
@@ -197,8 +190,15 @@ public class AlertDataSource extends RPCDataSource {
record.setAttribute("conditionText", conditionText);
record.setAttribute("conditionValue", conditionValue);
- String recoveryInfo = AlertFormatUtility.getAlertRecoveryInfo(alert);
+ String recoveryInfo = AlertFormatUtility.getAlertRecoveryInfo(from);
record.setAttribute("recoveryInfo", recoveryInfo);
return record;
}
+
+ protected void executeRemove(final DSRequest request, final DSResponse response) {
+ JavaScriptObject data = request.getData ();
+ ListGridRecord record = new ListGridRecord(data);
+ Window.alert(String.valueOf(record.getAttributeAsInt("id")));
+ }
+
}
\ No newline at end of file
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java
index ab6862c..cd0252f 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/configuration/ConfigurationEditor.java
@@ -578,6 +578,7 @@ public class ConfigurationEditor extends VLayout {
VLayout summaryTableHolder = new VLayout();
ToolStrip toolStrip = new ToolStrip();
+ toolStrip.setWidth100();
IButton addRowButton = new IButton();
addRowButton.setIcon(Window.getImgURL("[SKIN]/actions/add.png"));
addRowButton.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ConfigurationGWTService.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ConfigurationGWTService.java
index 9358332..307bafe 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ConfigurationGWTService.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ConfigurationGWTService.java
@@ -3,7 +3,9 @@ package org.rhq.enterprise.gui.coregui.client.gwt;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.RawConfiguration;
+import org.rhq.core.domain.configuration.ResourceConfigurationUpdate;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
+import org.rhq.core.domain.util.PageList;
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
@@ -19,6 +21,9 @@ public interface ConfigurationGWTService extends RemoteService {
ConfigurationDefinition getResourceConfigurationDefinition(int resourceTypeId);
+ PageList<ResourceConfigurationUpdate> findResourceConfigurationUpdates(int resourceId);
+
+
RawConfiguration dummy(RawConfiguration config);
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupListView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupListView.java
index 538fc95..43f99aa 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupListView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupListView.java
@@ -74,7 +74,7 @@ public class ResourceGroupListView extends VLayout {
// addMember(searchPanel);
- final ResourceGroupsDataSource datasource = new ResourceGroupsDataSource();
+ final ResourceGroupsDataSource datasource = ResourceGroupsDataSource.getInstance();
VLayout gridHolder = new VLayout();
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupsDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupsDataSource.java
index 1f88e32..ddfa206 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupsDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupsDataSource.java
@@ -19,8 +19,6 @@
package org.rhq.enterprise.gui.coregui.client.inventory.groups;
import org.rhq.core.domain.criteria.ResourceGroupCriteria;
-import org.rhq.core.domain.measurement.AvailabilityType;
-import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.group.ResourceGroup;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
@@ -28,12 +26,10 @@ import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGroupGWTServiceAsync;
import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
-import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.data.DSRequest;
import com.smartgwt.client.data.DSResponse;
import com.smartgwt.client.data.DataSourceField;
-import com.smartgwt.client.data.fields.DataSourceImageField;
import com.smartgwt.client.data.fields.DataSourceIntegerField;
import com.smartgwt.client.data.fields.DataSourceTextField;
import com.smartgwt.client.rpc.RPCResponse;
@@ -42,14 +38,24 @@ import com.smartgwt.client.widgets.grid.ListGridRecord;
/**
* @author Greg Hinkle
*/
-public class ResourceGroupsDataSource extends RPCDataSource {
+public class ResourceGroupsDataSource extends RPCDataSource<ResourceGroup> {
private String query;
private ResourceGroupGWTServiceAsync groupService = GWTServiceLookup.getResourceGroupService();
+ private static ResourceGroupsDataSource INSTANCE;
+
+ public static ResourceGroupsDataSource getInstance() {
+ if (INSTANCE == null) {
+ INSTANCE = new ResourceGroupsDataSource();
+ }
+ return INSTANCE;
+ }
- public ResourceGroupsDataSource() {
+
+ private ResourceGroupsDataSource() {
+ super("ResourceGroups");
DataSourceField idDataField = new DataSourceIntegerField("id", "ID", 20);
idDataField.setPrimaryKey(true);
@@ -93,31 +99,27 @@ public class ResourceGroupsDataSource extends RPCDataSource {
});
}
+ @Override
+ public ResourceGroup copyValues(ListGridRecord from) {
+ return null; // TODO: Implement this method.
+ }
- public static ListGridRecord[] buildRecords(PageList<ResourceGroup> groupList) {
-
- ListGridRecord[] records = null;
- if (groupList != null) {
- records = new ListGridRecord[groupList.size()];
-
- for (int x = 0; x < groupList.size(); x++) {
- ResourceGroup group = groupList.get(x);
- ListGridRecord record = new ListGridRecord();
- record.setAttribute("group", group);
- record.setAttribute("id", group.getId());
- record.setAttribute("name", group.getName());
- record.setAttribute("description", group.getDescription());
- record.setAttribute("groupCategory", group.getGroupCategory());
-
- if (group.getResourceType() != null) {
- record.setAttribute("resourceType", group.getResourceType());
- record.setAttribute("typeName", group.getResourceType().getName());
- record.setAttribute("pluginName", group.getResourceType().getPlugin());
- }
- records[x] = record;
- }
+ @Override
+ public ListGridRecord copyValues(ResourceGroup from) {
+ ListGridRecord record = new ListGridRecord();
+ record.setAttribute("group", from);
+ record.setAttribute("id", from.getId());
+ record.setAttribute("name", from.getName());
+ record.setAttribute("description", from.getDescription());
+ record.setAttribute("groupCategory", from.getGroupCategory());
+
+ if (from.getResourceType() != null) {
+ record.setAttribute("resourceType", from.getResourceType());
+ record.setAttribute("typeName", from.getResourceType().getName());
+ record.setAttribute("pluginName", from.getResourceType().getPlugin());
}
- return records;
+
+ return record;
}
}
\ No newline at end of file
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/definitions/GroupDefinitionDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/definitions/GroupDefinitionDataSource.java
index b5a9b89..2d2ca93 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/definitions/GroupDefinitionDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/definitions/GroupDefinitionDataSource.java
@@ -38,7 +38,7 @@ import com.smartgwt.client.widgets.grid.ListGridRecord;
/**
* @author Greg Hinkle
*/
-public class GroupDefinitionDataSource extends RPCDataSource {
+public class GroupDefinitionDataSource extends RPCDataSource<GroupDefinition> {
private ResourceGroupGWTServiceAsync groupService = GWTServiceLookup.getResourceGroupService();
@@ -88,27 +88,25 @@ public class GroupDefinitionDataSource extends RPCDataSource {
});
}
+ @Override
+ public GroupDefinition copyValues(ListGridRecord from) {
+ return null; // TODO: Implement this method.
+ }
- public ListGridRecord[] buildRecords(PageList<GroupDefinition> definitions) {
-
- ListGridRecord[] records = new ListGridRecord[definitions.size()];
- int i = 0;
- for (GroupDefinition def : definitions) {
- ListGridRecord record = new ListGridRecord();
- record.setAttribute("id", def.getId());
- record.setAttribute("name", def.getName());
- record.setAttribute("description", def.getDescription());
- record.setAttribute("expression", def.getExpression());
- record.setAttribute("recalculationInterval", def.getRecalculationInterval());
- record.setAttribute("modifiedTime", def.getModifiedTime());
- record.setAttribute("createdTime", def.getCreatedTime());
- record.setAttribute("lastCalculationTime", def.getLastCalculationTime());
- record.setAttribute("nextCalculationTime", def.getNextCalculationTime());
- record.setAttribute("managedResourceGroups", def.getManagedResourceGroups());
-
- records[i++] = record;
- }
-
- return records;
+ @Override
+ public ListGridRecord copyValues(GroupDefinition from) {
+ ListGridRecord record = new ListGridRecord();
+ record.setAttribute("id", from.getId());
+ record.setAttribute("name", from.getName());
+ record.setAttribute("description", from.getDescription());
+ record.setAttribute("expression", from.getExpression());
+ record.setAttribute("recalculationInterval", from.getRecalculationInterval());
+ record.setAttribute("modifiedTime", from.getModifiedTime());
+ record.setAttribute("createdTime", from.getCreatedTime());
+ record.setAttribute("lastCalculationTime", from.getLastCalculationTime());
+ record.setAttribute("nextCalculationTime", from.getNextCalculationTime());
+ record.setAttribute("managedResourceGroups", from.getManagedResourceGroups());
+
+ return record;
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceDatasource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceDatasource.java
index 294bda1..b692edf 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceDatasource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceDatasource.java
@@ -40,7 +40,7 @@ import com.smartgwt.client.widgets.grid.ListGridRecord;
/**
* @author Greg Hinkle
*/
-public class ResourceDatasource extends RPCDataSource {
+public class ResourceDatasource extends RPCDataSource<Resource> {
private String query;
@@ -104,29 +104,35 @@ public class ResourceDatasource extends RPCDataSource {
System.out.println("Data retrieved in: " + (System.currentTimeMillis() - start));
- ListGridRecord[] records = new ListGridRecord[result.size()];
- for (int x=0; x<result.size(); x++) {
- Resource res = result.get(x);
- ListGridRecord record = new ListGridRecord();
- record.setAttribute("resource",res);
- record.setAttribute("id",res.getId());
- record.setAttribute("name",res.getName());
- record.setAttribute("description",res.getDescription());
- record.setAttribute("typeName",res.getResourceType().getName());
- record.setAttribute("pluginName",res.getResourceType().getPlugin());
- record.setAttribute("category",res.getResourceType().getCategory().getDisplayName());
-
- record.setAttribute("currentAvailability",
- res.getCurrentAvailability().getAvailabilityType() == AvailabilityType.UP
- ? "/images/icons/availability_green_16.png"
- : "/images/icons/availability_red_16.png");
- records[x] = record;
- }
-
+ ListGridRecord[] records = buildRecords(result);
response.setData(records);
response.setTotalRows(result.getTotalSize()); // for paging to work we have to specify size of full result set
processResponse(request.getRequestId(), response);
}
});
}
+
+ @Override
+ public Resource copyValues(ListGridRecord from) {
+ return null; // TODO: Implement this method.
+ }
+
+ @Override
+ public ListGridRecord copyValues(Resource from) {
+ ListGridRecord record = new ListGridRecord();
+ record.setAttribute("resource",from);
+ record.setAttribute("id",from.getId());
+ record.setAttribute("name",from.getName());
+ record.setAttribute("description",from.getDescription());
+ record.setAttribute("typeName",from.getResourceType().getName());
+ record.setAttribute("pluginName",from.getResourceType().getPlugin());
+ record.setAttribute("category",from.getResourceType().getCategory().getDisplayName());
+
+ record.setAttribute("currentAvailability",
+ from.getCurrentAvailability().getAvailabilityType() == AvailabilityType.UP
+ ? "/images/icons/availability_green_16.png"
+ : "/images/icons/availability_red_16.png");
+
+ return record;
+ }
}
\ No newline at end of file
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java
index e1529ac..834a74d 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java
@@ -28,6 +28,7 @@ import org.rhq.enterprise.gui.coregui.client.components.tab.TwoLevelTab;
import org.rhq.enterprise.gui.coregui.client.components.tab.TwoLevelTabSet;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceSearchView;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceSelectListener;
+import org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.configuration.ConfigurationHistoryView;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.monitoring.GraphListView;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
@@ -153,7 +154,7 @@ public class ResourceDetailView extends VLayout implements ResourceSelectListene
configurationTab.updateSubTab("Current", new ConfigurationEditor(resource.getId(), resource.getResourceType().getId()));
-
+ configurationTab.updateSubTab("History", ConfigurationHistoryView.getHistoryOf(resource.getId()));
topTabSet.setSelectedTab(selectedTab);
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ConfigurationHistoryDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ConfigurationHistoryDataSource.java
new file mode 100644
index 0000000..9e424b6
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ConfigurationHistoryDataSource.java
@@ -0,0 +1,109 @@
+/*
+ * 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.client.inventory.resource.detail.configuration;
+
+import org.rhq.core.domain.configuration.ResourceConfigurationUpdate;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.gwt.ConfigurationGWTServiceAsync;
+import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.data.DSRequest;
+import com.smartgwt.client.data.DSResponse;
+import com.smartgwt.client.data.fields.DataSourceIntegerField;
+import com.smartgwt.client.data.fields.DataSourceTextField;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+
+/**
+ * @author Greg Hinkle
+ */
+public class ConfigurationHistoryDataSource extends RPCDataSource<ResourceConfigurationUpdate> {
+
+ private ConfigurationGWTServiceAsync configurationService = GWTServiceLookup.getConfigurationService();
+
+
+ public ConfigurationHistoryDataSource() {
+ super();
+
+ // id, resource, subject, configuration, createdTime, duration, errorMessage, modifiedTime, status
+
+
+ DataSourceIntegerField idField = new DataSourceIntegerField("id");
+ idField.setPrimaryKey(true);
+ addField(idField);
+
+ DataSourceTextField submittedField = new DataSourceTextField("createdTime");
+ addField(submittedField);
+
+ DataSourceTextField statusField = new DataSourceTextField("status");
+ addField(statusField);
+
+ DataSourceTextField subjectField = new DataSourceTextField("subject");
+ addField(subjectField);
+
+
+ }
+
+ @Override
+ protected void executeFetch(final DSRequest request, final DSResponse response) {
+
+ int resourceId = Integer.parseInt((String) request.getCriteria().getValues().get("resourceId"));
+
+ configurationService.findResourceConfigurationUpdates(resourceId, new AsyncCallback<PageList<ResourceConfigurationUpdate>>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Unable to load configuration history",caught);
+ response.setStatus(DSResponse.STATUS_FAILURE);
+ processResponse(request.getRequestId(),response);
+ }
+
+ public void onSuccess(PageList<ResourceConfigurationUpdate> result) {
+ response.setData(buildRecords(result));
+ response.setTotalRows(result.getTotalSize());
+ processResponse(request.getRequestId(), response);
+ }
+ });
+ }
+
+
+
+
+
+ @Override
+ public ResourceConfigurationUpdate copyValues(ListGridRecord from) {
+ return null; // TODO: Implement this method.
+ }
+
+ @Override
+ public ListGridRecord copyValues(ResourceConfigurationUpdate from) {
+ ListGridRecord record = new ListGridRecord();
+ record.setAttribute("id", from.getId());
+ record.setAttribute("resource",from.getResource());
+ record.setAttribute("subject",from.getSubjectName());
+ record.setAttribute("configuration", from.getConfiguration());
+ record.setAttribute("createdTime",from.getCreatedTime());
+ record.setAttribute("duration", from.getDuration());
+ record.setAttribute("errorMessage", from.getErrorMessage());
+ record.setAttribute("modifiedTime", from.getModifiedTime());
+ record.setAttribute("status",from.getStatus());
+
+ return record;
+ }
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ConfigurationHistoryView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ConfigurationHistoryView.java
new file mode 100644
index 0000000..3b52ecb
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/configuration/ConfigurationHistoryView.java
@@ -0,0 +1,162 @@
+/*
+ * 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.client.inventory.resource.detail.configuration;
+
+import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDatasource;
+import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceSelectListener;
+
+import com.google.gwt.event.dom.client.KeyCodes;
+import com.smartgwt.client.data.Criteria;
+import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.types.ListGridFieldType;
+import com.smartgwt.client.types.SelectionAppearance;
+import com.smartgwt.client.types.SelectionStyle;
+import com.smartgwt.client.util.BooleanCallback;
+import com.smartgwt.client.util.SC;
+import com.smartgwt.client.widgets.IButton;
+import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.events.ClickEvent;
+import com.smartgwt.client.widgets.events.ClickHandler;
+import com.smartgwt.client.widgets.form.DynamicForm;
+import com.smartgwt.client.widgets.form.fields.TextItem;
+import com.smartgwt.client.widgets.form.fields.events.KeyPressEvent;
+import com.smartgwt.client.widgets.form.fields.events.KeyPressHandler;
+import com.smartgwt.client.widgets.grid.CellFormatter;
+import com.smartgwt.client.widgets.grid.ListGrid;
+import com.smartgwt.client.widgets.grid.ListGridField;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+import com.smartgwt.client.widgets.grid.events.DataArrivedEvent;
+import com.smartgwt.client.widgets.grid.events.DataArrivedHandler;
+import com.smartgwt.client.widgets.grid.events.SelectionChangedHandler;
+import com.smartgwt.client.widgets.grid.events.SelectionEvent;
+import com.smartgwt.client.widgets.layout.LayoutSpacer;
+import com.smartgwt.client.widgets.layout.VLayout;
+import com.smartgwt.client.widgets.toolbar.ToolStrip;
+
+import java.util.ArrayList;
+
+/**
+ * @author Greg Hinkle
+ */
+public class ConfigurationHistoryView extends VLayout {
+
+ private ListGrid listGrid;
+
+ /**
+ * A resource list of all resources in the system
+ */
+ public ConfigurationHistoryView() {
+ this(null);
+ }
+
+ /**
+ * Resource list filtered by a given criteria
+ */
+ public ConfigurationHistoryView(Criteria criteria) {
+
+ setWidth100();
+ setHeight100();
+
+
+ final ConfigurationHistoryDataSource datasource = new ConfigurationHistoryDataSource();
+
+ VLayout gridHolder = new VLayout();
+
+ listGrid = new ListGrid();
+ listGrid.setWidth100();
+ listGrid.setHeight100();
+ listGrid.setDataSource(datasource);
+ listGrid.setAutoFetchData(true);
+ listGrid.setAlternateRecordStyles(true);
+ listGrid.setUseAllDataSourceFields(true);
+
+ if (criteria != null) {
+ listGrid.setInitialCriteria(criteria);
+ }
+
+ listGrid.setSelectionType(SelectionStyle.SIMPLE);
+ listGrid.setSelectionAppearance(SelectionAppearance.CHECKBOX);
+ listGrid.setResizeFieldsInRealTime(true);
+
+
+ gridHolder.addMember(listGrid);
+
+ ToolStrip toolStrip = new ToolStrip();
+ toolStrip.setPadding(5);
+ toolStrip.setWidth100();
+ toolStrip.setMembersMargin(15);
+
+ final IButton removeButton = new IButton("Remove");
+ removeButton.setDisabled(true);
+ removeButton.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent clickEvent) {
+ SC.confirm("Are you sure you want to delete " + listGrid.getSelection().length + " configurations?",
+ new BooleanCallback() {
+ public void execute(Boolean aBoolean) {
+
+ }
+ }
+ );
+ }
+ });
+
+
+ final Label tableInfo = new Label("Total: " + listGrid.getTotalRows());
+ tableInfo.setWrap(false);
+
+ toolStrip.addMember(removeButton);
+ toolStrip.addMember(new LayoutSpacer());
+ toolStrip.addMember(tableInfo);
+
+ gridHolder.addMember(toolStrip);
+
+
+ listGrid.addSelectionChangedHandler(new SelectionChangedHandler() {
+ public void onSelectionChanged(SelectionEvent selectionEvent) {
+ int selectedCount = ((ListGrid) selectionEvent.getSource()).getSelection().length;
+ tableInfo.setContents("Total: " + listGrid.getTotalRows() + " (" + selectedCount + " selected)");
+ removeButton.setDisabled(selectedCount == 0);
+ }
+ });
+
+
+ addMember(gridHolder);
+
+
+ listGrid.addDataArrivedHandler(new DataArrivedHandler() {
+ public void onDataArrived(DataArrivedEvent dataArrivedEvent) {
+ int selectedCount = ((ListGrid) dataArrivedEvent.getSource()).getSelection().length;
+ tableInfo.setContents("Total: " + listGrid.getTotalRows() + " (" + selectedCount + " selected)");
+ }
+ });
+ }
+
+
+
+ // -------- Static Utility loaders ------------
+
+
+ public static ConfigurationHistoryView getHistoryOf(int resourceId) {
+ return new ConfigurationHistoryView(new Criteria("resourceId",String.valueOf(resourceId)));
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/operation/OperationWizard.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/operation/OperationWizard.java
new file mode 100644
index 0000000..26f7108
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/operation/OperationWizard.java
@@ -0,0 +1,69 @@
+/*
+ * 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.client.inventory.resource.detail.operation;
+
+import org.rhq.core.domain.resource.Resource;
+
+import com.smartgwt.client.widgets.Window;
+import com.smartgwt.client.widgets.events.CloseClickHandler;
+import com.smartgwt.client.widgets.events.CloseClientEvent;
+import com.smartgwt.client.widgets.layout.VLayout;
+
+/**
+ * @author Greg Hinkle
+ */
+public class OperationWizard extends VLayout{
+
+ private Resource resource;
+ private String operation;
+
+ public OperationWizard(Resource resource, String operation) {
+ this.resource = resource;
+ this.operation = operation;
+ }
+
+
+ @Override
+ protected void onDraw() {
+ super.onDraw();
+
+ }
+
+
+
+ public static void startPopupOperationWizard(Resource resource, String operation) {
+ final Window dialog = new Window();
+ dialog.setTitle("Execute Operation");
+ dialog.setWidth(800);
+ dialog.setHeight(800);
+ dialog.setIsModal(true);
+ dialog.setShowModalMask(true);
+ dialog.setCanDragResize(true);
+ dialog.setShowResizer(true);
+ dialog.centerInPage();
+ dialog.addCloseClickHandler(new CloseClickHandler() {
+ public void onCloseClick(CloseClientEvent closeClientEvent) {
+ dialog.destroy();
+ }
+ });
+ dialog.addItem(new OperationWizard(resource, operation));
+ dialog.show();
+
+ }
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/menu/MenuBarView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/menu/MenuBarView.java
index b09fac8..91c46f5 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/menu/MenuBarView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/menu/MenuBarView.java
@@ -23,6 +23,7 @@ import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.VerticalAlignment;
import com.smartgwt.client.widgets.Img;
import com.smartgwt.client.widgets.layout.HLayout;
+import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.menu.Menu;
import com.smartgwt.client.widgets.menu.MenuBar;
import org.rhq.enterprise.gui.coregui.client.components.AboutModalWindow;
@@ -91,54 +92,38 @@ public class MenuBarView extends HLayout {
});
addMember(logo);
+ VLayout right = new VLayout();
+
+
+
+ HLayout links = new HLayout(25);
+
Hyperlink dashboardLink = new Hyperlink("Dashboard", "Dashboard");
dashboardLink.setStylePrimaryName("TopSectionLink");
dashboardLink.setStyleName("TopSectionLink");
- addMember(dashboardLink);
+ links.addMember(dashboardLink);
Hyperlink demoLink = new Hyperlink("Demo", "Demo");
demoLink.setStylePrimaryName("TopSectionLink");
- addMember(demoLink);
+ links.addMember(demoLink);
Hyperlink resourcesLink = new Hyperlink("Resources", "Resources");
resourcesLink.setStylePrimaryName("TopSectionLink");
- addMember(resourcesLink);
+ links.addMember(resourcesLink);
Hyperlink bundlesLink = new Hyperlink("Bundles", "Bundles");
bundlesLink.setStylePrimaryName("TopSectionLink");
- addMember(bundlesLink);
+ links.addMember(bundlesLink);
Hyperlink adminLink = new Hyperlink("Administration", "Administration");
adminLink.setStylePrimaryName("TopSectionLink");
- addMember(adminLink);
+ links.addMember(adminLink);
+
+
+ right.addMember(links);
+ right.addMember(new SearchBarPane());
-
-//
-// LinkItem demoLink = new LinkItem("Demo");
-// demoLink.setShowTitle(false);
-// demoLink.setLinkTitle("Demo");
-// demoLink.addClickHandler(new ClickHandler() {
-// public void onClick(ClickEvent clickEvent) {
-// CoreGUI.setContent(new DemoCanvas());
-// }
-// });
-//
-//
-// LinkItem adminLink = new LinkItem("Administration");
-// adminLink.setShowTitle(false);
-// adminLink.setLinkTitle("Administration");
-//
-// demoLink.addClickHandler(new ClickHandler() {
-// public void onClick(ClickEvent clickEvent) {
-// CoreGUI.setContent(new AdministrationView());
-// }
-// });
-//
-// DynamicForm form = new DynamicForm();
-//
-// form.setItems(demoLink, adminLink);
-//
-// addMember(form);
+ addMember(right);
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/menu/SearchBarPane.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/menu/SearchBarPane.java
new file mode 100644
index 0000000..2cd3d35
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/menu/SearchBarPane.java
@@ -0,0 +1,73 @@
+/*
+ * 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.client.menu;
+
+import com.google.gwt.user.client.ui.TextBox;
+import com.smartgwt.client.widgets.form.DynamicForm;
+import com.smartgwt.client.widgets.form.fields.SelectItem;
+import com.smartgwt.client.widgets.form.fields.TextItem;
+import com.smartgwt.client.widgets.layout.HLayout;
+import com.smartgwt.client.widgets.menu.Menu;
+import com.smartgwt.client.widgets.menu.MenuButton;
+import com.smartgwt.client.widgets.menu.MenuItem;
+import com.smartgwt.client.widgets.menu.MenuItemSeparator;
+
+import java.util.LinkedHashMap;
+
+/**
+ * @author Greg Hinkle
+ */
+public class SearchBarPane extends HLayout {
+
+ public SearchBarPane() {
+ super();
+ setWidth100();
+ setHeight(45);
+ }
+
+ @Override
+ protected void onInit() {
+ super.onInit();
+
+ DynamicForm form = new DynamicForm();
+ form.setNumCols(3);
+ form.setWidth100();
+
+
+ LinkedHashMap<String, String> values = new LinkedHashMap<String, String>();
+ values.put("Resources", "Resources");
+ values.put("Resources Groups", "Resources Groups");
+ values.put("Bundles", "Bundles");
+ values.put("Packages", "Package");
+ values.put("Users", "Users");
+ values.put("Roles", "Roles");
+
+ SelectItem searchType = new SelectItem("searchType", "Search");
+ searchType.setValueMap(values);
+
+
+ TextItem query = new TextItem("query");
+ query.setWidth("100%");
+ query.setShowTitle(false);
+
+ form.setItems(searchType, query);
+
+ addMember(form);
+ }
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
index f484c29..197f8a0 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
@@ -18,9 +18,12 @@
*/
package org.rhq.enterprise.gui.coregui.client.util;
+import org.rhq.core.domain.authz.Role;
+import org.rhq.core.domain.configuration.ResourceConfigurationUpdate;
import org.rhq.core.domain.criteria.ResourceCriteria;
import org.rhq.core.domain.util.OrderingField;
import org.rhq.core.domain.util.PageControl;
+import org.rhq.core.domain.util.PageList;
import org.rhq.core.domain.util.PageOrdering;
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
@@ -29,13 +32,16 @@ import com.smartgwt.client.data.DSResponse;
import com.smartgwt.client.data.DataSource;
import com.smartgwt.client.types.DSDataFormat;
import com.smartgwt.client.types.DSProtocol;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
import java.util.List;
/**
+ * Base GWT-RPC oriented DataSource class.
+ *
* @author Greg Hinkle
*/
-public abstract class RPCDataSource extends DataSource {
+public abstract class RPCDataSource<T> extends DataSource {
public RPCDataSource() {
setClientOnly(false);
@@ -52,8 +58,6 @@ public abstract class RPCDataSource extends DataSource {
}
-
-
@Override
protected Object transformRequest(DSRequest request) {
try {
@@ -115,8 +119,39 @@ public abstract class RPCDataSource extends DataSource {
}
+
+
+ public ListGridRecord[] buildRecords(PageList<T> list) {
+ if (list == null) {
+ return null;
+ }
+
+ ListGridRecord[] records = new ListGridRecord[list.size()];
+ int i = 0;
+ for (T item : list) {
+ records[i++] = copyValues(item);
+ }
+ return records;
+ }
+
+
+ /**
+ * Extensions should implement this method to retrieve data. Paging solutions should use
+ * @see getPageControl(). All implementations should call processResponse whether they
+ * fail or succeed. Data should be set on the request via setData. Implementations can use
+ * buildRecords to get the list of records.
+ *
+ * @param request
+ * @param response
+ */
protected abstract void executeFetch(final DSRequest request, final DSResponse response);
+
+ public abstract T copyValues(ListGridRecord from);
+
+ public abstract ListGridRecord copyValues(T from);
+
+
/**
* Executed on <code>REMOVE</code> operation. <code>processResponse (requestId, response)</code>
* should be called when operation completes (either successful or failure).
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/preferences/UserPreferences.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/preferences/UserPreferences.java
index 93a7743..2b935e5 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/preferences/UserPreferences.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/preferences/UserPreferences.java
@@ -43,7 +43,7 @@ public class UserPreferences {
public UserPreferences(Subject subject) {
this.subject = subject;
- subject.getUserConfiguration();
+ this.userConfiguration = subject.getUserConfiguration();
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ConfigurationGWTServiceImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ConfigurationGWTServiceImpl.java
index 7887501..d4d9386 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ConfigurationGWTServiceImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ConfigurationGWTServiceImpl.java
@@ -3,7 +3,11 @@ package org.rhq.enterprise.gui.coregui.server.gwt;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.RawConfiguration;
+import org.rhq.core.domain.configuration.ResourceConfigurationUpdate;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
+import org.rhq.core.domain.util.PageControl;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.core.domain.util.PageOrdering;
import org.rhq.enterprise.gui.coregui.client.gwt.ConfigurationGWTService;
import org.rhq.enterprise.gui.coregui.server.util.SerialUtility;
import org.rhq.enterprise.server.configuration.ConfigurationManagerLocal;
@@ -14,9 +18,10 @@ import com.google.gwt.user.server.rpc.RemoteServiceServlet;
public class ConfigurationGWTServiceImpl extends AbstractGWTServiceImpl implements ConfigurationGWTService {
+ private ConfigurationManagerLocal configurationManager = LookupUtil.getConfigurationManager();
+
public Configuration getPluginConfiguration(int resourceId) {
- ConfigurationManagerLocal configurationManager = LookupUtil.getConfigurationManager();
Configuration configuration = configurationManager.getPluginConfiguration(getSessionSubject(), resourceId);
@@ -24,7 +29,6 @@ public class ConfigurationGWTServiceImpl extends AbstractGWTServiceImpl implemen
}
public ConfigurationDefinition getPluginConfigurationDefinition(int resourceTypeId) {
- ConfigurationManagerLocal configurationManager = LookupUtil.getConfigurationManager();
ConfigurationDefinition definition = configurationManager.getPluginConfigurationDefinitionForResourceType(getSessionSubject(), resourceTypeId);
return SerialUtility.prepare(definition, "PluginDefinition");
@@ -33,19 +37,29 @@ public class ConfigurationGWTServiceImpl extends AbstractGWTServiceImpl implemen
public Configuration getResourceConfiguration(int resourceId) {
- ConfigurationManagerLocal configurationManager = LookupUtil.getConfigurationManager();
-
Configuration configuration = configurationManager.getResourceConfiguration(getSessionSubject(), resourceId);
return SerialUtility.prepare(configuration, "ResourceConfiguration");
}
public ConfigurationDefinition getResourceConfigurationDefinition(int resourceTypeId) {
- ConfigurationManagerLocal configurationManager = LookupUtil.getConfigurationManager();
ConfigurationDefinition definition = configurationManager.getResourceConfigurationDefinitionWithTemplatesForResourceType(getSessionSubject(), resourceTypeId);
return SerialUtility.prepare(definition, "ResourceDefinition");
}
+ public PageList<ResourceConfigurationUpdate> findResourceConfigurationUpdates(int resourceId) {
+ PageList<ResourceConfigurationUpdate> result;
+
+ PageControl pc = PageControl.getUnlimitedInstance();
+ pc.initDefaultOrderingField("cu.id", PageOrdering.DESC);
+
+ // TODO GH: I'd prefer a criteria based solution here
+ result = configurationManager.findResourceConfigurationUpdates(getSessionSubject(), resourceId, null, null, false, pc);
+
+ return SerialUtility.prepare(result,"ConfigurationService.findResourceConfigurationUpdates");
+ }
+
+
public RawConfiguration dummy(RawConfiguration config) {
System.out.println(config.getPath());
return new RawConfiguration();
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java
index 778abd6..f933d5f 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/configuration/ConfigurationManagerBean.java
@@ -847,9 +847,9 @@ public class ConfigurationManagerBean implements ConfigurationManagerLocal, Conf
public PageList<ResourceConfigurationUpdate> findResourceConfigurationUpdates(Subject subject, Integer resourceId,
Long beginDate, Long endDate, boolean suppressOldest, PageControl pc) {
- if (!authorizationManager.canViewResource(subject, resourceId)) {
+ if (!authorizationManager.hasResourcePermission(subject, Permission.CONFIGURE, resourceId)) {
throw new PermissionException("User [" + subject.getName()
- + "] does not have permission to view resource[id=" + resourceId + "]");
+ + "] does not have permission to manage configuration for resource[id=" + resourceId + "]");
}
Resource resource = entityManager.find(Resource.class, resourceId);
14 years, 3 months
[rhq] 90 commits - .classpath etc/eclipse-tools etc/modules etc/samples modules/common modules/core modules/enterprise modules/plugins
by mazz
.classpath | 5
etc/eclipse-tools/RHQ | 38
etc/eclipse-tools/maven/RHQ | 11
etc/modules/base-perspective-war/pom.xml | 233 -----
etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java | 38
etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java | 49 -
etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java | 41
etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java | 161 ---
etc/modules/base-perspective-war/src/main/resources/seam.properties | 3
etc/modules/base-perspective-war/src/main/webapp/WEB-INF/components.xml | 16
etc/modules/base-perspective-war/src/main/webapp/WEB-INF/faces-config.xml | 28
etc/modules/base-perspective-war/src/main/webapp/WEB-INF/includes/pageControls.xhtml | 103 --
etc/modules/base-perspective-war/src/main/webapp/WEB-INF/jboss-web.xml | 20
etc/modules/base-perspective-war/src/main/webapp/WEB-INF/templates/mainTemplate.xhtml | 68 -
etc/modules/base-perspective-war/src/main/webapp/WEB-INF/web.xml | 108 --
etc/modules/base-perspective-war/src/main/webapp/index.xhtml | 36
etc/samples/perspectives/sample-perspective/app/pom.xml | 36
etc/samples/perspectives/sample-perspective/perspective/pom.xml | 2
modules/common/filetemplate-bundle/pom.xml | 37
modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/CommandRecipeCommand.java | 56 +
modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java | 85 ++
modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/FileRecipeCommand.java | 85 ++
modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RealizeRecipeCommand.java | 74 +
modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeCommand.java | 43 +
modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java | 270 ++++++
modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java | 249 +++++
modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ScriptRecipeCommand.java | 51 +
modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java | 204 ++++
modules/common/pom.xml | 1
modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleAgentService.java | 7
modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleScheduleRequest.java | 56 +
modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleScheduleResponse.java | 66 +
modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleUpdateRequest.java | 31
modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleUpdateResponse.java | 31
modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/PluginMetadataParser.java | 16
modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleServerService.java | 27
modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleStatusUpdate.java | 33
modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleUpdateComplete.java | 31
modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml | 1
modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml | 17
modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java | 60 +
modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleDeployDefinition.java | 8
modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleFile.java | 16
modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java | 57 -
modules/core/domain/src/main/java/org/rhq/core/domain/content/InstalledPackage.java | 2
modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java | 76 +
modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleVersionCriteria.java | 86 ++
modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementBaseline.java | 6
modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceType.java | 8
modules/core/domain/src/test/java/org/rhq/core/domain/bundle/test/BundleTest.java | 42
modules/core/gui/src/main/java/org/rhq/core/gui/table/model/PagedListDataModel.java | 5
modules/core/gui/src/main/java/org/rhq/core/gui/table/renderer/AllRowsSelectorRenderer.java | 3
modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java | 90 +-
modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployRequest.java | 89 ++
modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployResult.java | 64 +
modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleFacet.java | 1
modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleManagerProvider.java | 52 +
modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/util/ResponseTimeLogParser.java | 154 ++-
modules/core/plugin-container/src/main/java/org/rhq/core/pc/ServerServices.java | 57 -
modules/core/plugin-container/src/main/java/org/rhq/core/pc/bundle/BundleManager.java | 199 ++++
modules/core/plugin-container/src/main/java/org/rhq/core/pc/content/ContentManager.java | 20
modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginValidator.java | 94 +-
modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java | 3
modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/ServiceContainer.java | 2
modules/enterprise/gui/base-perspective-jar/pom.xml | 199 ++++
modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java | 41
modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java | 49 +
modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java | 41
modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java | 161 +++
modules/enterprise/gui/base-perspective-jar/src/main/resources/seam.properties | 3
modules/enterprise/gui/base-perspective-war/pom.xml | 67 +
modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/components.xml | 16
modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/faces-config.xml | 28
modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/includes/pageControls.xhtml | 103 ++
modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/jboss-web.xml | 20
modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/templates/mainTemplate.xhtml | 70 +
modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/web.xml | 108 ++
modules/enterprise/gui/base-perspective-war/src/main/webapp/index.xhtml | 36
modules/enterprise/gui/pom.xml | 3
modules/enterprise/gui/portal-war/src/main/webapp/rhq/perspective/main.xhtml | 2
modules/enterprise/pom.xml | 2
modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClientProxy.java | 23
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java | 425 +++++++++-
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerHelper.java | 34
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java | 129 ++-
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerRemote.java | 19
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java | 47 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java | 61 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java | 24
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java | 1
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/bundle/BundleServerPluginContainer.java | 5
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/bundle/BundleServerPluginFacet.java | 31
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/bundle/BundleServerPluginManager.java | 54 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginManager.java | 34
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java | 40
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java | 18
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java | 312 ++++++-
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/TestBundleServerPluginService.java | 202 ++++
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/TestBundleServerPluginServiceMBean.java | 24
modules/enterprise/server/plugins/filetemplate-bundle/pom.xml | 37
modules/enterprise/server/plugins/filetemplate-bundle/src/main/java/org/rhq/enterprise/server/plugins/filetemplate/BundleServerPluginComponent.java | 52 +
modules/enterprise/server/plugins/filetemplate-bundle/src/main/resources/META-INF/rhq-serverplugin.xml | 2
modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml | 6
modules/enterprise/server/plugins/perspectives/policy/app/pom.xml | 94 ++
modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundleDetailsUIBean.java | 157 +++
modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundleVersionDetailsUIBean.java | 163 +++
modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java | 119 ++
modules/enterprise/server/plugins/perspectives/policy/app/src/main/resources/seam.properties | 3
modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/WEB-INF/components.xml | 16
modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundleDetails.xhtml | 108 ++
modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundleVersionDetails.xhtml | 120 ++
modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml | 87 ++
modules/enterprise/server/plugins/perspectives/policy/perspective/pom.xml | 156 +++
modules/enterprise/server/plugins/perspectives/policy/perspective/src/main/resources/META-INF/rhq-serverplugin.xml | 30
modules/enterprise/server/plugins/perspectives/policy/pom.xml | 28
modules/enterprise/server/plugins/pom.xml | 2
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheIfModuleDirectoryComponent.java | 5
modules/plugins/apache/src/main/resources/META-INF/rhq-plugin.xml | 2
modules/plugins/filetemplate-bundle/pom.xml | 13
modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java | 28
modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java | 278 ++++++
modules/plugins/filetemplate-bundle/src/main/resources/META-INF/rhq-plugin.xml | 2
modules/plugins/filetemplate-bundle/src/test/java/org/rhq/plugins/filetemplate/ProcessingRecipeContextTest.java | 248 +++++
modules/plugins/virt/src/main/java/org/rhq/plugins/virt/VirtualizationNetworkComponent.java | 7
124 files changed, 6458 insertions(+), 1398 deletions(-)
New commits:
commit d9d58661d22bf1698c11ea8fbb33b17ad0e38bac
Merge: b98aefb... 9092141...
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Wed Mar 3 20:52:29 2010 -0500
Merge branch 'bundle-copy' into bundle
commit 90921416205a3f3ab2bdd6aa7f32142053b6ed67
Merge: ac72b22... eea8401...
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Wed Mar 3 20:52:11 2010 -0500
Merge branch 'master' into bundle-copy
commit b98aefb0383974059cfa56b7212f4c7a0f4792ff
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Wed Mar 3 20:20:22 2010 -0500
plugin validator caught this error - the service resource had createDeletePolicy set to both but the resource component's parent did not have create-child facet implemented and its delete facet method was empty (so it wasn't really implemented either). removing createDeletePolicy
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheIfModuleDirectoryComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheIfModuleDirectoryComponent.java
index cc8cb16..7a86201 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheIfModuleDirectoryComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheIfModuleDirectoryComponent.java
@@ -42,7 +42,7 @@ import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.plugins.apache.mapping.ApacheAugeasMapping;
import org.rhq.plugins.apache.util.AugeasNodeSearch;
-public class ApacheIfModuleDirectoryComponent implements ResourceComponent<ApacheDirectoryComponent>, ConfigurationFacet, DeleteResourceFacet{
+public class ApacheIfModuleDirectoryComponent implements ResourceComponent<ApacheDirectoryComponent>, ConfigurationFacet {
private ResourceContext<ApacheDirectoryComponent> context;
private List<String> position;
@@ -102,9 +102,6 @@ public class ApacheIfModuleDirectoryComponent implements ResourceComponent<Apach
report.setStatus(ConfigurationUpdateStatus.FAILURE);
}
}
- public void deleteResource() throws Exception {
-
- }
private AugeasNode getNode(AugeasNode virtualHost) {
List<AugeasNode> directories = AugeasNodeSearch.getNodeByParentParams(virtualHost, IFMODULE_DIRECTIVE_NAME, position);
diff --git a/modules/plugins/apache/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/apache/src/main/resources/META-INF/rhq-plugin.xml
index 930f3fc..0668ccb 100644
--- a/modules/plugins/apache/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/apache/src/main/resources/META-INF/rhq-plugin.xml
@@ -707,7 +707,7 @@
&UseCanonicalName;
&UseCanonicalPhysicalPort;
</resource-configuration>
- <service name="IfModule Parameters" discovery="ApacheIfModuleDirectoryDiscoveryComponent" class="ApacheIfModuleDirectoryComponent" createDeletePolicy="both">
+ <service name="IfModule Parameters" discovery="ApacheIfModuleDirectoryDiscoveryComponent" class="ApacheIfModuleDirectoryComponent">
<resource-configuration>
&IfModulePosition;
&Order;
commit ac72b22b34f6ccf523e434f29c5b972f855a7b11
Merge: 091f599... d882f20...
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Wed Mar 3 19:26:22 2010 -0500
Merge branch 'bundle' into master-copy
Conflicts:
.classpath
modules/core/dbutils/pom.xml
modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java
modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java
modules/enterprise/server/ear/pom.xml
modules/enterprise/server/plugins/pom.xml
diff --cc .classpath
index fe06650,1a35400..04464c1
--- a/.classpath
+++ b/.classpath
@@@ -1,9 -1,8 +1,10 @@@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="modules/common/jboss-as/src/main/java"/>
+ <classpathentry kind="src" path="modules/common/filetemplate-bundle/src/main/java"/>
+ <classpathentry kind="src" path="modules/common/filetemplate-bundle/src/test/java"/>
+ <classpathentry kind="src" path="modules/enterprise/gui/base-perspective-jar/src/main/java"/>
+ <classpathentry kind="src" path="modules/plugins/nss/src/main/java"/>
- <classpathentry kind="src" path="etc/modules/base-perspective-war/src/main/java"/>
<classpathentry kind="src" path="modules/enterprise/server/plugins/jboss-software/src/test/java"/>
<classpathentry kind="src" path="modules/enterprise/server/plugins/jboss-software/src/main/java"/>
<classpathentry kind="src" path="modules/enterprise/remoting/client-api/src/main/java"/>
diff --cc modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
index 8169695,b2b3b11..74c6038
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@@ -3157,30 -3182,77 +3182,88 @@@
FOREIGN KEY (BUNDLE_DEPLOY_ID)
REFERENCES RHQ_BUNDLE_DEPLOY (ID)
</statement>
- </schema-directSQL>
+ </schema-directSQL>
<schema-addColumn table="RHQ_BUNDLE_DEPLOY_HIST" column="SUBJECT_NAME" columnType="VARCHAR2" precision="255" />
<schema-addColumn table="RHQ_BUNDLE_DEPLOY_HIST" column="AUDIT_TIME" columnType="LONG" />
- <schema-alterColumn table="RHQ_BUNDLE_DEPLOY_HIST" column="AUDIT_TIME" nullable="FALSE" />
+ <schema-alterColumn table="RHQ_BUNDLE_DEPLOY_HIST" column="AUDIT_TIME" nullable="FALSE" />
<schema-addColumn table="RHQ_BUNDLE_DEPLOY_HIST" column="AUDIT_ACTION" columnType="VARCHAR2" precision="50" />
<schema-alterColumn table="RHQ_BUNDLE_DEPLOY_HIST" column="AUDIT_ACTION" nullable="FALSE" />
- <schema-addColumn table="RHQ_BUNDLE_DEPLOY_HIST" column="AUDIT_MESSAGE" columnType="LONGVARCHAR" />
-
+ <schema-addColumn table="RHQ_BUNDLE_DEPLOY_HIST" column="AUDIT_MESSAGE" columnType="LONGVARCHAR" />
+
<!-- Changes to RHQ_BUNDLE_FILE -->
- <schema-alterColumn table="RHQ_BUNDLE_FILE" column="PACKAGE_VERSION_ID" nullable="FALSE" />
-
+ <schema-alterColumn table="RHQ_BUNDLE_FILE" column="PACKAGE_VERSION_ID" nullable="FALSE" />
</schemaSpec>
-
+
+ <schemaSpec version="2.78.1">
+ <schema-addColumn table="RHQ_BUNDLE" column="REPO_ID" columnType="INTEGER" />
+ <schema-directSQL>
+ <statement desc="Creating RHQ_BUNDLE foreign key relation to RHQ_REPO">
+ ALTER TABLE RHQ_BUNDLE
+ ADD CONSTRAINT RHQ_REPO_ID_FK
+ FOREIGN KEY (REPO_ID)
+ REFERENCES RHQ_REPO (ID)
+ </statement>
+ </schema-directSQL>
+ </schemaSpec>
+
+ <schemaSpec version="2.79">
+ <schema-directSQL>
+ <statement desc="Normalizing resource group descriptions">
+ UPDATE RHQ_RESOURCE_GROUP SET DESCRIPTION = NULL WHERE DESCRIPTION = ''
+ </statement>
+ </schema-directSQL>
+ </schemaSpec>
+
+ <schemaSpec version="2.82">
+ <schema-directSQL>
+ <statement desc="Creating table RHQ_SAVED_SEARCH">
+ CREATE TABLE RHQ_SAVED_SEARCH ( ID INTEGER )
+ </statement>
+ </schema-directSQL>
+ <schema-directSQL>
+ <statement desc="Creating primary key for RHQ_AFFINITY_GROUP">
+ ALTER TABLE RHQ_SAVED_SEARCH ADD PRIMARY KEY ( ID )
+ </statement>
+ </schema-directSQL>
+ <schema-addColumn table="RHQ_SAVED_SEARCH" column="CONTEXT" columnType="VARCHAR2" precision="25" />
+ <schema-alterColumn table="RHQ_SAVED_SEARCH" column="CONTEXT" nullable="FALSE" />
+
+ <schema-addColumn table="RHQ_SAVED_SEARCH" column="NAME" columnType="VARCHAR2" precision="200" />
+ <schema-addColumn table="RHQ_SAVED_SEARCH" column="DESCRIPTION" columnType="VARCHAR2" precision="500" />
+ <schema-addColumn table="RHQ_SAVED_SEARCH" column="PATTERN" columnType="VARCHAR2" precision="1000" />
+ <schema-alterColumn table="RHQ_SAVED_SEARCH" column="PATTERN" nullable="FALSE" />
+
+ <schema-addColumn table="RHQ_SAVED_SEARCH" column="JPQL_TRANSLATION" columnType="VARCHAR2" precision="4000" />
+ <schema-addColumn table="RHQ_SAVED_SEARCH" column="LAST_COMPUTE_TIME" columnType="LONG" />
+ <schema-alterColumn table="RHQ_SAVED_SEARCH" column="LAST_COMPUTE_TIME" nullable="FALSE" />
+ <schema-addColumn table="RHQ_SAVED_SEARCH" column="RESULT_COUNT" columnType="LONG" />
+
+ <schema-addColumn table="RHQ_SAVED_SEARCH" column="SUBJECT_ID" columnType="INTEGER" />
+ <schema-alterColumn table="RHQ_SAVED_SEARCH" column="SUBJECT_ID" nullable="FALSE" />
+ <schema-addColumn table="RHQ_SAVED_SEARCH" column="GLOBAL" columnType="BOOLEAN" />
+ <schema-alterColumn table="RHQ_SAVED_SEARCH" column="GLOBAL" nullable="FALSE" />
+
+ <schema-directSQL>
+ <statement targetDBVendor="postgresql" desc="Inserting global default saved search 'Downed Platforms'">
+ INSERT INTO rhq_saved_search (id, context, name, description, pattern, last_compute_time, subject_id, global)
+ VALUES (1, 'Resource', 'Downed Platforms', 'All downed machines across the entire enterprise', 'down platform', 0, 1, true)
+ </statement>
+ <statement targetDBVendor="oracle" desc="Inserting global default saved search 'Downed Platforms'">
+ INSERT INTO rhq_saved_search (id, context, name, description, pattern, last_compute_time, subject_id, global)
+ VALUES (1, 'Resource', 'Downed Platforms', 'All downed machines across the entire enterprise', 'down platform', 0, 1, 1)
+ </statement>
+ </schema-directSQL>
+ <schema-directSQL>
+ <statement targetDBVendor="postgresql" desc="Inserting global default saved search 'Downed Servers'">
+ INSERT INTO rhq_saved_search (id, context, name, description, pattern, last_compute_time, subject_id, global)
+ VALUES (2, 'Resource', 'Downed Servers', 'All downed servers across the entire enterprise', 'down server', 0, 1, true)
+ </statement>
+ <statement targetDBVendor="oracle" desc="Inserting global default saved search 'Downed Servers'">
+ INSERT INTO rhq_saved_search (id, context, name, description, pattern, last_compute_time, subject_id, global)
+ VALUES (2, 'Resource', 'Downed Servers', 'All downed servers across the entire enterprise', 'down server', 0, 1, 1)
+ </statement>
+ </schema-directSQL>
+ </schemaSpec>
</dbupgrade>
</target>
</project>
diff --cc modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java
index 573e9c0,27a1375..4732698
--- a/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java
+++ b/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java
@@@ -348,60 -343,35 +348,60 @@@ public class SystemInfoFactory
public static TemplateEngine fetchTemplateEngine() {
- try{
- SystemInfo systemInfo = createSystemInfo();
-
- Map<String, String> tokens = new HashMap<String, String>();
- tokens.put(TOKEN_PREFIX+"hostname", systemInfo.getHostname());
-
- tokens.put(TOKEN_PREFIX+"os.name", systemInfo.getOperatingSystemName());
- tokens.put(TOKEN_PREFIX+"os.version", systemInfo.getOperatingSystemVersion());
- tokens.put(TOKEN_PREFIX+"os.type", systemInfo.getOperatingSystemType().toString());
- tokens.put(TOKEN_PREFIX+"cpu.count", Integer.toString(systemInfo.getNumberOfCpus()));
- tokens.put(TOKEN_PREFIX+"architecture", systemInfo.getSystemArchitecture());
-
- for (NetworkAdapterInfo networkAdapter : systemInfo.getAllNetworkAdapters()) {
- String key = TOKEN_PREFIX+"interfaces." + networkAdapter.getName();
- tokens.put(key + ".mac", networkAdapter.getMacAddressString());
- tokens.put(key + ".type", networkAdapter.getType());
- tokens.put(key + ".flags", networkAdapter.getAllFlags());
-
- if (!networkAdapter.getUnicastAddresses().isEmpty()) {
- tokens.put(key + ".address", networkAdapter.getUnicastAddresses().get(0).getHostAddress());
+ try {
+ SystemInfo systemInfo = createSystemInfo();
+
+ Map<String, String> tokens = new HashMap<String, String>();
+ tokens.put(TOKEN_PREFIX + "hostname", systemInfo.getHostname());
+
+ tokens.put(TOKEN_PREFIX + "os.name", systemInfo.getOperatingSystemName());
+ tokens.put(TOKEN_PREFIX + "os.version", systemInfo.getOperatingSystemVersion());
+ tokens.put(TOKEN_PREFIX + "os.type", systemInfo.getOperatingSystemType().toString());
+ tokens.put(TOKEN_PREFIX + "architecture", systemInfo.getSystemArchitecture());
+ try {
+ tokens.put(TOKEN_PREFIX + "cpu.count", Integer.toString(systemInfo.getNumberOfCpus()));
+ } catch (Exception e) {
+ tokens.put(TOKEN_PREFIX + "cpu.count", "?");
}
- if (!networkAdapter.getMulticastAddresses().isEmpty()) {
- tokens.put(key + ".multicast.address", networkAdapter.getMulticastAddresses().get(0).getHostAddress());
+
+ List<NetworkAdapterInfo> allNetworkAdapters = null;
+ try {
+ allNetworkAdapters = systemInfo.getAllNetworkAdapters();
+ } catch (Exception e) {
}
- }
- TemplateEngine templateEngine = new TemplateEngine(tokens);
- return templateEngine;
- }catch(Exception e){
- return new TemplateEngine(new HashMap());
+ if (allNetworkAdapters != null) {
+ for (NetworkAdapterInfo networkAdapter : allNetworkAdapters) {
+ String key = TOKEN_PREFIX + "interfaces." + networkAdapter.getName();
+ tokens.put(key + ".mac", networkAdapter.getMacAddressString());
+ tokens.put(key + ".type", networkAdapter.getType());
+ tokens.put(key + ".flags", networkAdapter.getAllFlags());
+
+ if (!networkAdapter.getUnicastAddresses().isEmpty()) {
+ tokens.put(key + ".address", networkAdapter.getUnicastAddresses().get(0).getHostAddress());
+ }
+ if (!networkAdapter.getMulticastAddresses().isEmpty()) {
+ tokens.put(key + ".multicast.address", networkAdapter.getMulticastAddresses().get(0)
+ .getHostAddress());
+ }
+ }
+ }
+
+ // create a base IP address - this one is known to java and should always exist no matter what platform we are on
+ try {
+ try {
+ tokens.put(TOKEN_PREFIX + "interfaces.java.address", InetAddress
+ .getByName(systemInfo.getHostname()).getHostAddress());
+ } catch (Exception e) {
+ tokens.put(TOKEN_PREFIX + "interfaces.java.address", InetAddress.getLocalHost().getHostAddress());
+ }
+ } catch (Exception e2) {
+ }
+
+ TemplateEngine templateEngine = new TemplateEngine(tokens);
+ return templateEngine;
+ } catch (Exception e) {
+ // some rare exception occurred that we didn't expect, rather than blow up entirely, just don't provide any values
+ return new TemplateEngine(new HashMap<String, String>());
}
}
--}
++}
commit 091f59945e654da8e2d140cc017d433331b1af7c
Merge: bc2d729... 966bc00...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Mar 3 17:45:15 2010 -0500
Merge branch 'bundle' into bundle-jay
commit bc2d7299246cc4a83411254c6d2b9a0c04123b28
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Mar 3 17:43:38 2010 -0500
added:
createBundleDeployDefinition
getBundleVersionFilenames
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleDeployDefinition.java b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleDeployDefinition.java
index b83c576..7c88e96 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleDeployDefinition.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleDeployDefinition.java
@@ -83,7 +83,7 @@ public class BundleDeployDefinition implements Serializable {
private Long mtime = System.currentTimeMillis();
@JoinColumn(name = "CONFIG_ID", referencedColumnName = "ID", nullable = true)
- @OneToOne(fetch = FetchType.LAZY, optional = true)
+ @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, optional = true)
private Configuration configuration;
@Column(name = "ENFORCE_POLICY", nullable = false)
@@ -107,6 +107,12 @@ public class BundleDeployDefinition implements Serializable {
// for JPA use
}
+ public BundleDeployDefinition(BundleVersion bundleVersion, String name) {
+ this.bundleVersion = bundleVersion;
+ this.name = name;
+ this.enforcePolicy = false;
+ }
+
public int getId() {
return id;
}
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 29b25cf..c9a3261 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
@@ -20,8 +20,10 @@ package org.rhq.enterprise.server.bundle;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
+import java.util.HashSet;
import java.util.List;
import java.util.Random;
+import java.util.Set;
import java.util.UUID;
import javax.ejb.EJB;
@@ -33,6 +35,7 @@ import javax.persistence.Query;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.rhq.core.clientapi.agent.configuration.ConfigurationUtility;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.bundle.Bundle;
@@ -41,6 +44,8 @@ import org.rhq.core.domain.bundle.BundleDeployment;
import org.rhq.core.domain.bundle.BundleFile;
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.definition.ConfigurationDefinition;
import org.rhq.core.domain.content.Architecture;
import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageType;
@@ -115,6 +120,44 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
@RequiredPermission(Permission.MANAGE_INVENTORY)
+ public BundleDeployDefinition createBundleDeployDefinition(Subject subject, int bundleVersionId, String name,
+ String description, Configuration configuration, boolean enforcePolicy, int enforcementInterval,
+ boolean pinToBundle) throws Exception {
+
+ if (null == name || "".equals(name.trim())) {
+ throw new IllegalArgumentException("Invalid bundleDeployDefinitionName: " + name);
+ }
+ BundleVersion bundleVersion = entityManager.find(BundleVersion.class, bundleVersionId);
+ if (null == bundleVersion) {
+ throw new IllegalArgumentException("Invalid bundleVersionId: " + bundleVersionId);
+ }
+ ConfigurationDefinition configDef = bundleVersion.getConfigurationDefinition();
+ if (null != configDef) {
+ if (null == configuration) {
+ throw new IllegalArgumentException(
+ "Missing Configuration. Configuration is required when the specified BundleVersion defines Configuration Properties.");
+ }
+ List<String> errors = ConfigurationUtility.validateConfiguration(configuration, configDef);
+ if (null != errors && !errors.isEmpty()) {
+ throw new IllegalArgumentException("Invalid Configuration: " + errors.toString());
+ }
+ }
+
+ BundleDeployDefinition deployDef = new BundleDeployDefinition(bundleVersion, name);
+ deployDef.setDescription(description);
+ deployDef.setConfiguration(configuration);
+ deployDef.setEnforcePolicy(enforcePolicy);
+ deployDef.setEnforcementInterval(enforcementInterval);
+ if (pinToBundle) {
+ deployDef.setBundle(bundleVersion.getBundle());
+ }
+
+ entityManager.persist(deployDef);
+
+ return deployDef;
+ }
+
+ @RequiredPermission(Permission.MANAGE_INVENTORY)
public BundleType createBundleType(Subject subject, String name, int resourceTypeId) throws Exception {
if (null == name || "".equals(name.trim())) {
throw new IllegalArgumentException("Invalid bundleTypeName: " + name);
@@ -283,6 +326,46 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
return (PackageType) packageTypeQuery.getSingleResult();
}
+ @RequiredPermission(Permission.MANAGE_INVENTORY)
+ public Set<String> getBundleVersionFilenames(Subject subject, int bundleVersionId, boolean withoutBundleFileOnly)
+ throws Exception {
+
+ BundleVersion bundleVersion = entityManager.find(BundleVersion.class, bundleVersionId);
+ if (null == bundleVersion) {
+ throw new IllegalArgumentException("Invalid bundleVersionId: " + bundleVersionId);
+ }
+
+ // parse the recipe (validation occurs here) and get the config def and list of files
+ BundleType bundleType = bundleVersion.getBundle().getBundleType();
+ BundleServerPluginFacet bp = BundleManagerHelper.getPluginContainer().getBundleServerPluginManager()
+ .getBundleServerPluginFacet(bundleType.getName());
+ RecipeParseResults parseResults = bp.parseRecipe(bundleVersion.getRecipe());
+
+ Set<String> result = parseResults.getBundleFileNames();
+
+ if (withoutBundleFileOnly) {
+ List<BundleFile> bundleFiles = bundleVersion.getBundleFiles();
+ Set<String> allFilenames = result;
+ result = new HashSet<String>(allFilenames.size() - bundleFiles.size());
+ for (String filename : allFilenames) {
+ boolean found = false;
+ for (BundleFile bundleFile : bundleFiles) {
+ String name = bundleFile.getPackageVersion().getGeneralPackage().getName();
+ if (name.equals(filename)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ result.add(filename);
+ }
+ }
+ }
+
+ return result;
+
+ }
+
@SuppressWarnings("unchecked")
public List<BundleType> getAllBundleTypes(Subject subject) {
// the list of types will be small, no need to support paging
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
index ec3b73b..22880be 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
@@ -20,6 +20,7 @@ package org.rhq.enterprise.server.bundle;
import java.io.InputStream;
import java.util.List;
+import java.util.Set;
import javax.ejb.Local;
@@ -30,6 +31,7 @@ import org.rhq.core.domain.bundle.BundleDeployment;
import org.rhq.core.domain.bundle.BundleFile;
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.content.Architecture;
import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleDeployDefinitionCriteria;
@@ -95,6 +97,24 @@ public interface BundleManagerLocal {
Bundle createBundle(Subject subject, String name, int bundleTypeId) throws Exception;
/**
+ * @param subject must be InventoryManager
+ * @param BundleVersionId the BundleVersion being deployed by this definition
+ * @param name a name for this definition. not null or empty
+ * @param description an optional longer description describing this deploy def
+ * @param configuration a Configuration (pojo) to be associated with this deploy def. Although
+ * it is not enforceable
+ * must be that of the associated BundleVersion.
+ * @param enforcePolicy if true enforce policy on deployments made with this deploy def
+ * @param enforceInterval if enforcePolicy is true check policy at this interval (in seconds), otherwise ignored
+ * @param pinToBundle if true this deploy def is disabled if a newer BundleVersion is generated for the Bundle
+ * @return
+ * @throws Exception
+ */
+ BundleDeployDefinition createBundleDeployDefinition(Subject subject, int bundleVersionId, String name,
+ String description, Configuration configuration, boolean enforcePolicy, int enforcementInterval,
+ boolean pinToBundle) throws Exception;
+
+ /**
* Not generally called. For use by Server Side Plugins when registering a Bundle Plugin.
*
* @param subject must be InventoryManager
@@ -114,6 +134,20 @@ public interface BundleManagerLocal {
BundleVersion createBundleVersion(Subject subject, int bundleId, String name, String bundleVersion, String recipe)
throws Exception;
+ /**
+ * 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 bundleVersionId the BundleVersion being queried
+ * @param withoutBundleFileOnly if true omit any filenames that already have a corresponding BundleFile for
+ * the BundleVersion.
+ * @return The List of filenames.
+ * @throws Exception
+ */
+ Set<String> getBundleVersionFilenames(Subject subject, int bundleVersionId, boolean withoutBundleFileOnly)
+ throws Exception;
+
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
// The remaining methods are shared with the Remote Interface.
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
index 24c6dae..45e946f 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
@@ -21,6 +21,7 @@ package org.rhq.enterprise.server.bundle;
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
import javax.persistence.EntityManager;
import javax.persistence.Query;
@@ -33,9 +34,12 @@ import org.testng.annotations.Test;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.Bundle;
+import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleFile;
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.Package;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
@@ -109,6 +113,12 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
for (Object removeMe : doomed) {
em.remove(em.getReference(BundleFile.class, ((BundleFile) removeMe).getId()));
}
+ // remove any orphaned bdds
+ q = em.createQuery("SELECT bdd FROM BundleDeployDefinition bdd WHERE bdd.name LIKE '" + TEST_PREFIX + "%'");
+ doomed = q.getResultList();
+ for (Object removeMe : doomed) {
+ em.remove(em.getReference(BundleDeployDefinition.class, ((BundleDeployDefinition) removeMe).getId()));
+ }
// remove packages which cascade remove packageversions
q = em.createQuery("SELECT p FROM Package p WHERE p.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
@@ -216,6 +226,47 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
}
@Test(enabled = TESTS_ENABLED)
+ public void testCreateBundleDeploymentDef() throws Exception {
+ Bundle b1 = createBundle("one");
+ assertNotNull(b1);
+ BundleVersion bv1 = createBundleVersion(b1.getName() + "-1", null, b1);
+ assertNotNull(bv1);
+ Configuration config = new Configuration();
+ BundleDeployDefinition bdd1;
+ try {
+ bdd1 = createDeployDefinition("one", bv1, config);
+ fail("Bad config was accepted");
+ } catch (Exception e) {
+ System.out.println("EXPECTED EXCEPTION: " + e);
+ // expected due to bad config
+ }
+ config.put(new PropertySimple("bundletest.property", "bundletest.property value"));
+ bdd1 = createDeployDefinition("one", bv1, config);
+ assertNotNull(bdd1);
+ }
+
+ @Test(enabled = TESTS_ENABLED)
+ public void testGetBundleFilenames() throws Exception {
+ Bundle b1 = createBundle("one");
+ assertNotNull(b1);
+ BundleVersion bv1 = createBundleVersion(b1.getName(), "1.0", b1);
+ assertNotNull(bv1);
+ Set<String> filenames = bundleManager.getBundleVersionFilenames(getOverlord(), bv1.getId(), true);
+ assertNotNull(filenames);
+ assertEquals(2, filenames.size());
+ BundleFile bf1 = bundleManager.addBundleFileViaByteArray(getOverlord(), bv1.getId(), TEST_PREFIX
+ + "-bundlefile-1", "1.0", null, "Test Bundle File # 1".getBytes(), false);
+ filenames = bundleManager.getBundleVersionFilenames(getOverlord(), bv1.getId(), true);
+ assertNotNull(filenames);
+ assertEquals(1, filenames.size());
+ BundleFile bf2 = bundleManager.addBundleFileViaByteArray(getOverlord(), bv1.getId(), TEST_PREFIX
+ + "-bundlefile-2", "1.0", null, "Test Bundle File # 2".getBytes(), false);
+ filenames = bundleManager.getBundleVersionFilenames(getOverlord(), bv1.getId(), true);
+ assertNotNull(filenames);
+ assertEquals(0, filenames.size());
+ }
+
+ @Test(enabled = TESTS_ENABLED)
public void testfindBundlesByCriteria() throws Exception {
Bundle b1 = createBundle("one");
Bundle b2 = createBundle("two");
@@ -343,6 +394,17 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
return bv;
}
+ private BundleDeployDefinition createDeployDefinition(String name, BundleVersion bv, Configuration config)
+ throws Exception {
+ final String fullName = TEST_PREFIX + "-bundledeploydef-" + name;
+ BundleDeployDefinition bdd = bundleManager.createBundleDeployDefinition(getOverlord(), bv.getId(), fullName,
+ fullName, config, false, -1, false);
+
+ assert bdd.getId() > 0;
+ assert bdd.getName().endsWith(fullName);
+ return bdd;
+ }
+
private ResourceType createResourceType(String name) throws Exception {
final String fullName = TEST_PREFIX + "-resourcetype-" + name;
ResourceType rt = new ResourceType(fullName, "BundleManagerBeanTest", ResourceCategory.PLATFORM, null);
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 dc43f97..3833955 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
@@ -188,13 +188,13 @@ public class TestBundleServerPluginService extends ServerPluginService implement
ConfigurationDefinition configDef;
Set<String> bundleFileNames;
- configDef = new ConfigurationDefinition("SampleBundle", "Stubbed ConfigDef for Sample Bundle");
- configDef.put(new PropertyDefinitionSimple("sample.bundle.deploy.directory",
- "Stubbed Property for deploy directory (must already exist on target platform)", true,
- PropertySimpleType.STRING));
+ configDef = new ConfigurationDefinition("bundletest-configdef", "Test Config Def for testing BundleVersion");
+ configDef.put(new PropertyDefinitionSimple("bundletest.property",
+ "Test property for BundleVersion Config Def testing", true, PropertySimpleType.STRING));
bundleFileNames = new HashSet<String>();
- bundleFileNames.add("sample-bundle.war");
+ bundleFileNames.add("bundletest-bundlefile-1");
+ bundleFileNames.add("bundletest-bundlefile-2");
return new RecipeParseResults(configDef, bundleFileNames);
}
commit 966bc00b7d6234614635ca5fd319cb57b8a2f12c
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Wed Mar 3 15:49:43 2010 -0500
add shell command recipe support
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/CommandRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/CommandRecipeCommand.java
new file mode 100644
index 0000000..e5db71d
--- /dev/null
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/CommandRecipeCommand.java
@@ -0,0 +1,56 @@
+/*
+ * 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, 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.bundle.filetemplate.recipe;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Declares that an existing script or shell command is to be invoked.
+ *
+ * @author John Mazzitelli
+ */
+public class CommandRecipeCommand implements RecipeCommand {
+
+ public String getName() {
+ return "command";
+ }
+
+ public void parse(RecipeParser parser, RecipeContext context, String[] args) {
+
+ if (args == null || args.length == 0) {
+ throw new IllegalArgumentException("Missing the command to execute");
+ }
+
+ String exe = args[0];
+ List<String> exeArgs = new ArrayList<String>(args.length - 1);
+ for (int i = 1; i < args.length; i++) {
+ exeArgs.add(args[i]);
+ }
+
+ context.addCommand(exe, exeArgs);
+
+ return;
+ }
+}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
index cb76a80..bc8932f 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
@@ -48,6 +48,7 @@ public class RecipeContext {
private final Set<String> replacementVariables;
private Configuration replacementVariableValues;
private final List<Script> scripts;
+ private final List<Command> commands;
public RecipeContext(String recipe) {
this.recipe = recipe;
@@ -56,6 +57,7 @@ public class RecipeContext {
this.realizedFiles = new HashSet<String>();
this.replacementVariables = new HashSet<String>();
this.scripts = new ArrayList<Script>();
+ this.commands = new ArrayList<Command>();
}
/**
@@ -190,8 +192,8 @@ public class RecipeContext {
}
class Script {
- private final List<String> args;
private final String exe;
+ private final List<String> args;
public Script(String exe, List<String> args) {
this.exe = exe;
@@ -207,10 +209,38 @@ public class RecipeContext {
}
}
+ /**
+ * Adds a command that the recipe wants invoked. This command refers to an existing
+ * executable or shell command.
+ *
+ * @param cmd the main executable that this command wants to execute
+ * @param exeArgs the arguments to pass to the command executable
+ */
+ public void addCommand(String exe, List<String> exeArgs) {
+ this.commands.add(new Command(exe, exeArgs));
+ }
+
+ class Command {
+ private final String exe;
+ private final List<String> args;
+
+ public Command(String exe, List<String> args) {
+ this.exe = exe;
+ this.args = args;
+ }
+
+ public String getExecutable() {
+ return exe;
+ }
+
+ public List<String> getArguments() {
+ return args;
+ }
+ }
+
@Override
public String toString() {
StringBuilder str = new StringBuilder("RecipeContext:\n");
- str.append("Recipe Text:\n").append(getRecipe()).append("\n");
str.append("Deploy Files: ").append(getDeployFiles()).append("\n");
str.append("Replacement Vars: ").append(getReplacementVariables()).append("\n");
@@ -227,6 +257,14 @@ public class RecipeContext {
for (Script script : this.scripts) {
str.append("* ").append(script.getExecutable()).append(" ").append(script.getArguments()).append("\n");
}
+
+ str.append("Commands: ").append("\n");
+ for (Command cmd : this.commands) {
+ str.append("* ").append(cmd.getExecutable()).append(" ").append(cmd.getArguments()).append("\n");
+ }
+
+ str.append("Recipe Text:\n-----------\n").append(getRecipe()).append("\n");
+
return str.toString();
}
}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
index 98f26f6..f22c04c 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
@@ -129,6 +129,7 @@ public class RecipeParser {
HashMap<String, RecipeCommand> commands = new HashMap<String, RecipeCommand>();
RecipeCommand[] knownCommands = new RecipeCommand[] { new ScriptRecipeCommand(), //
+ new CommandRecipeCommand(), //
new FileRecipeCommand(), //
new RealizeRecipeCommand(), //
new DeployRecipeCommand() //
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
index 3682c18..f4cb102 100644
--- a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
@@ -177,6 +177,22 @@ public class ProcessingRecipeContext extends RecipeContext {
}
}
+ @Override
+ public void addCommand(String exe, List<String> exeArgs) {
+ super.addCommand(exe, exeArgs);
+
+ ProcessExecution pe = new ProcessExecution(exe);
+ pe.setArguments(exeArgs);
+ pe.setWaitForCompletion(30 * 60 * 1000L);
+ pe.setCheckExecutableExists(false);
+ pe.setWorkingDirectory(this.baseWorkingDirectory);
+
+ ProcessExecutionResults results = this.systemInfo.executeProcess(pe);
+ if (results.getError() != null) {
+ throw new RuntimeException("Could not execute command [" + pe + "]: " + results, results.getError());
+ }
+ }
+
private void ensureExecutable(File scriptFile) {
boolean success;
diff --git a/modules/plugins/filetemplate-bundle/src/test/java/org/rhq/plugins/filetemplate/ProcessingRecipeContextTest.java b/modules/plugins/filetemplate-bundle/src/test/java/org/rhq/plugins/filetemplate/ProcessingRecipeContextTest.java
index 47b721f..188e127 100644
--- a/modules/plugins/filetemplate-bundle/src/test/java/org/rhq/plugins/filetemplate/ProcessingRecipeContextTest.java
+++ b/modules/plugins/filetemplate-bundle/src/test/java/org/rhq/plugins/filetemplate/ProcessingRecipeContextTest.java
@@ -40,6 +40,7 @@ import org.rhq.bundle.filetemplate.recipe.RecipeContext;
import org.rhq.bundle.filetemplate.recipe.RecipeParser;
import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.pluginapi.util.FileUtils;
+import org.rhq.core.system.OperatingSystemType;
import org.rhq.core.system.SystemInfo;
import org.rhq.core.system.SystemInfoFactory;
import org.rhq.core.util.stream.StreamUtil;
@@ -140,6 +141,24 @@ public class ProcessingRecipeContextTest {
assert echoOutputContent.trim().equals("hello");
}
+ public void testCommandRecipe() throws Exception {
+ File testDir = getTestDir("testcommand");
+ File echoOutput = new File(testDir, "out.txt");
+ echoOutput.getParentFile().mkdirs();
+
+ SystemInfo sysinfo = SystemInfoFactory.createSystemInfo();
+ if (sysinfo.getOperatingSystemType() == OperatingSystemType.WINDOWS) {
+ addRecipeCommand("command cmd /C \"echo helloWorld > '" + echoOutput.getAbsolutePath() + "'\"");
+ } else {
+ addRecipeCommand("command sh -c \"echo helloWorld > '" + echoOutput.getAbsolutePath() + "'\"");
+ }
+
+ RecipeContext context = parseRecipeNow(testDir);
+
+ String echoOutputContent = readFile(echoOutput);
+ assert echoOutputContent.trim().equals("helloWorld");
+ }
+
private ProcessingRecipeContext parseRecipeNow(File testDir) throws Exception {
ProcessingRecipeContext context = createRecipeContext(testDir);
return parseRecipeNow(context);
commit bd69d0afa634444ad62151d89d3a3f5daf7e4869
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Wed Mar 3 14:29:29 2010 -0500
get the script recipe command to work
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployRequest.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployRequest.java
index 2dd6e6d..741efc3 100644
--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployRequest.java
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployRequest.java
@@ -19,9 +19,12 @@
package org.rhq.core.pluginapi.bundle;
+import java.io.File;
import java.io.Serializable;
+import java.util.Map;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
+import org.rhq.core.domain.content.PackageVersion;
/**
* A request to deploy a bundle.
@@ -31,11 +34,44 @@ import org.rhq.core.domain.bundle.BundleDeployDefinition;
public class BundleDeployRequest implements Serializable {
private static final long serialVersionUID = 1L;
+ private File bundleFilesLocation;
private BundleDeployDefinition bundleDeployDefinition;
- private BundleManagerProvider bundleManager;
+ private BundleManagerProvider bundleManagerProvider;
+ private Map<PackageVersion, File> packageVersionFiles;
+
+ public BundleDeployRequest() {
+ }
+
+ /**
+ * This returns the location where the plugin container has downloaded the bundle files.
+ *
+ * @return the location where the bundle files have been downloaded
+ */
+ public File getBundleFilesLocation() {
+ return this.bundleFilesLocation;
+ }
+
+ public void setBundleFilesLocation(File bundleFilesLocation) {
+ this.bundleFilesLocation = bundleFilesLocation;
+ }
+
+ /**
+ * Maps all the package versions associated with the bundle and the locations
+ * where the package version contents can be found. These will all be located
+ * somewhere under the {@link #getBundleFilesLocation() bundle files location}.
+ *
+ * @return packages and their locations on the local file system
+ */
+ public Map<PackageVersion, File> getPackageVersionFiles() {
+ return this.packageVersionFiles;
+ }
+
+ public void setPackageVersionFiles(Map<PackageVersion, File> packageVersionFiles) {
+ this.packageVersionFiles = packageVersionFiles;
+ }
public BundleDeployDefinition getBundleDeployDefinition() {
- return bundleDeployDefinition;
+ return this.bundleDeployDefinition;
}
public void setBundleDeployDefinition(BundleDeployDefinition bundleDeployDefinition) {
@@ -43,11 +79,11 @@ public class BundleDeployRequest implements Serializable {
}
public BundleManagerProvider getBundleManagerProvider() {
- return bundleManager;
+ return this.bundleManagerProvider;
}
public void setBundleManagerProvider(BundleManagerProvider provider) {
- this.bundleManager = provider;
+ this.bundleManagerProvider = provider;
}
}
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 5db906f..4475be4 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
@@ -22,8 +22,13 @@
*/
package org.rhq.core.pc.bundle;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.OutputStream;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
@@ -45,12 +50,14 @@ import org.rhq.core.pc.PluginContainer;
import org.rhq.core.pc.PluginContainerConfiguration;
import org.rhq.core.pc.agent.AgentService;
import org.rhq.core.pc.inventory.InventoryManager;
+import org.rhq.core.pc.inventory.ResourceContainer;
import org.rhq.core.pc.util.ComponentUtil;
import org.rhq.core.pc.util.FacetLockType;
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.util.MessageDigestGenerator;
/**
* Manages the bundle subsystem, which allows bundles of content to be installed.
@@ -78,15 +85,26 @@ public class BundleManager extends AgentService implements BundleAgentService, B
public void shutdown() {
}
+ public List<PackageVersion> getAllBundleVersionPackageVersions(BundleVersion bundleVersion) throws Exception {
+ int bvId = bundleVersion.getId();
+ List<PackageVersion> pvs = getBundleServerService().getAllBundleVersionPackageVersions(bvId);
+ return pvs;
+ }
+
+ public long getFileContent(PackageVersion packageVersion, OutputStream outputStream) throws Exception {
+ long size = getBundleServerService().downloadPackageBits(packageVersion, outputStream);
+ return size;
+ }
+
public BundleScheduleResponse schedule(BundleScheduleRequest request) {
BundleScheduleResponse response = new BundleScheduleResponse();
try {
- BundleDeployDefinition bundleDef = request.getBundleDeployDefinition();
+ BundleDeployDefinition bundleDeployDef = request.getBundleDeployDefinition();
// find the resource that will handle the bundle processing
InventoryManager im = PluginContainer.getInstance().getInventoryManager();
- BundleType bundleType = bundleDef.getBundleVersion().getBundle().getBundleType();
+ BundleType bundleType = bundleDeployDef.getBundleVersion().getBundle().getBundleType();
ResourceType resourceType = bundleType.getResourceType();
Set<Resource> resources = im.getResourcesWithType(resourceType);
if (resources.isEmpty()) {
@@ -94,6 +112,12 @@ public class BundleManager extends AgentService implements BundleAgentService, B
}
int bundleHandlerResourceId = resources.iterator().next().getId();
+ // pull down the bundle files that the plugin will need in order to process the bundle
+ ResourceContainer resourceContainer = im.getResourceContainer(bundleHandlerResourceId);
+ File pluginTmpDir = resourceContainer.getResourceContext().getTemporaryDirectory();
+ File bundleFilesDir = new File(pluginTmpDir, "" + bundleDeployDef.getBundleVersion().getId());
+ Map<PackageVersion, File> downloadedFiles = downloadBundleFiles(bundleDeployDef, bundleFilesDir);
+
// get the bundle facet object that will process the bundle
int facetMethodTimeout = 4 * 60 * 60 * 1000; // 4 hours is given to the bundle plugin to do its thing
BundleFacet bundlePluginComponent = getBundleFacet(bundleHandlerResourceId, facetMethodTimeout);
@@ -102,6 +126,8 @@ public class BundleManager extends AgentService implements BundleAgentService, B
BundleDeployRequest deployRequest = new BundleDeployRequest();
deployRequest.setBundleManagerProvider(this);
deployRequest.setBundleDeployDefinition(request.getBundleDeployDefinition());
+ deployRequest.setBundleFilesLocation(bundleFilesDir);
+ deployRequest.setPackageVersionFiles(downloadedFiles);
BundleDeployResult result = bundlePluginComponent.deployBundle(deployRequest);
if (!result.isSuccess()) {
response.setErrorMessage(result.getErrorMessage());
@@ -114,15 +140,91 @@ public class BundleManager extends AgentService implements BundleAgentService, B
return response;
}
- public List<PackageVersion> getAllBundleVersionPackageVersions(BundleVersion bundleVersion) throws Exception {
- int bvId = bundleVersion.getId();
- List<PackageVersion> pvs = getBundleServerService().getAllBundleVersionPackageVersions(bvId);
- return pvs;
+ /**
+ * Downloads the bundle's files into the bundle plugin's tmp directory and returns that tmp directory.
+ *
+ * @param bundleDeployDef bundle deployment information, including what bundle files need to be downloaded
+ * @param downloadDir location where the bundle files should be downloaded
+ * @return map of the package versions to their files that were downloaded
+ * @throws Exception
+ */
+ private Map<PackageVersion, File> downloadBundleFiles(BundleDeployDefinition bundleDeployDef, File downloadDir)
+ throws Exception {
+
+ BundleVersion bundleVersion = bundleDeployDef.getBundleVersion();
+
+ // download all the bundle files to the bundle plugin's tmp directory
+ Map<PackageVersion, File> packageVersionFiles = new HashMap<PackageVersion, File>();
+ List<PackageVersion> packageVersions = getAllBundleVersionPackageVersions(bundleVersion);
+ for (PackageVersion packageVersion : packageVersions) {
+ File packageFile = new File(downloadDir, packageVersion.getFileName());
+
+ try {
+ verifyHash(packageVersion, packageFile);
+ } catch (Exception e) {
+ // file either doesn't exist or it hash doesn't match, download a new copy
+ packageFile.getParentFile().mkdirs();
+ FileOutputStream fos = new FileOutputStream(packageFile);
+ try {
+ long size = getFileContent(packageVersion, fos);
+ if (packageVersion.getFileSize() != null && size != packageVersion.getFileSize().longValue()) {
+ log.warn("Downloaded bundle file [" + packageVersion + "] but its size was [" + size
+ + "] when it was expected to be [" + packageVersion.getFileSize() + "].");
+ }
+ } finally {
+ fos.close();
+ }
+
+ // now try to verify it again, if this throws an exception, that is very bad and we need to abort
+ verifyHash(packageVersion, packageFile);
+ }
+
+ packageVersionFiles.put(packageVersion, packageFile);
+ }
+
+ return packageVersionFiles;
}
- public long getFileContent(PackageVersion packageVersion, OutputStream outputStream) throws Exception {
- long size = getBundleServerService().downloadPackageBits(packageVersion, outputStream);
- return size;
+ /**
+ * Checks to see if the package file's hash matches that of the given package version.
+ * If the file doesn't exist or the hash doesn't match, an exception is thrown.
+ * This method returns normally if the hash matches the file.
+ * If there is no known hash in the package version, this method returns normally.
+ *
+ * @param packageVersion contains the hash that is expected
+ * @param packageFile the local file whose hash is to be checked
+ * @throws Exception if the file does not match the hash or the file doesn't exist
+ */
+ private void verifyHash(PackageVersion packageVersion, File packageFile) throws Exception {
+ if (!packageFile.exists()) {
+ throw new Exception("Package version [" + packageVersion + "] does not exist, cannot check hash");
+ }
+
+ if (packageVersion.getMD5() != null) {
+ String realMD5 = MessageDigestGenerator.getDigestString(packageFile);
+ if (!packageVersion.getMD5().equals(realMD5)) {
+ throw new Exception("Package version [" + packageVersion + "] failed MD5 check. expected=["
+ + packageVersion.getMD5() + "], actual=[" + realMD5 + "]");
+ }
+ } else if (packageVersion.getSHA256() != null) {
+ FileInputStream is = new FileInputStream(packageFile);
+ try {
+ MessageDigestGenerator gen = new MessageDigestGenerator("SHA256");
+ gen.add(is);
+ String realSHA256 = gen.getDigestString();
+ if (!packageVersion.getSHA256().equals(realSHA256)) {
+ throw new Exception("Package version [" + packageVersion + "] failed SHA256 check. expected=["
+ + packageVersion.getSHA256() + "], actual=[" + realSHA256 + "]");
+ }
+ } finally {
+ is.close();
+ }
+
+ } else {
+ log.debug("Package version [" + packageVersion + "] has no MD5/SHA256 hash - not verifying it");
+ }
+
+ return;
}
/**
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
index cee69db..9536665 100644
--- a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
@@ -18,28 +18,18 @@
*/
package org.rhq.plugins.filetemplate;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rhq.bundle.filetemplate.recipe.RecipeParser;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleVersion;
-import org.rhq.core.domain.content.PackageVersion;
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.util.MessageDigestGenerator;
/**
* @author John Mazzitelli
@@ -68,42 +58,12 @@ public class FileTemplateBundlePluginServerComponent implements ResourceComponen
BundleDeployDefinition bundleDeployDef = request.getBundleDeployDefinition();
BundleVersion bundleVersion = bundleDeployDef.getBundleVersion();
- // download all the bundle files to our tmp directory
- Map<PackageVersion, File> packageVersionFiles = new HashMap<PackageVersion, File>();
- File tmpDir = new File(this.resourceContext.getTemporaryDirectory(), "" + bundleVersion.getId());
- BundleManagerProvider bundleManager = request.getBundleManagerProvider();
- List<PackageVersion> packageVersions = bundleManager.getAllBundleVersionPackageVersions(bundleVersion);
- for (PackageVersion packageVersion : packageVersions) {
- File packageFile = new File(tmpDir, packageVersion.getFileName());
-
- try {
- verifyHash(packageVersion, packageFile);
- } catch (Exception e) {
- // file either doesn't exist or it hash doesn't match, download a new copy
- packageFile.getParentFile().mkdirs();
- FileOutputStream fos = new FileOutputStream(packageFile);
- try {
- long size = bundleManager.getFileContent(packageVersion, fos);
- if (packageVersion.getFileSize() != null && size != packageVersion.getFileSize().longValue()) {
- log.warn("Downloaded bundle file [" + packageVersion + "] but its size was [" + size
- + "] when it was expected to be [" + packageVersion.getFileSize() + "].");
- }
- } finally {
- fos.close();
- }
-
- // now try to verify it again, if this throws an exception, that is very bad and we need to abort
- verifyHash(packageVersion, packageFile);
- }
-
- packageVersionFiles.put(packageVersion, packageFile);
- }
-
// process the recipe
String recipe = bundleVersion.getRecipe();
RecipeParser parser = new RecipeParser();
- ProcessingRecipeContext recipeContext = new ProcessingRecipeContext(recipe, packageVersionFiles,
- this.resourceContext.getSystemInformation(), tmpDir.getAbsolutePath());
+ ProcessingRecipeContext recipeContext = new ProcessingRecipeContext(recipe, request
+ .getPackageVersionFiles(), this.resourceContext.getSystemInformation(), request
+ .getBundleFilesLocation().getAbsolutePath());
recipeContext.setReplacementVariableValues(bundleDeployDef.getConfiguration());
parser.setReplaceReplacementVariables(true);
parser.parseRecipe(recipeContext);
@@ -114,46 +74,4 @@ public class FileTemplateBundlePluginServerComponent implements ResourceComponen
}
return result;
}
-
- /**
- * Checks to see if the package file's hash matches that of the given package version.
- * If the file doesn't exist or the hash doesn't match, an exception is thrown.
- * This method returns normally if the hash matches the file.
- * If there is no known hash in the package version, this method returns normally.
- *
- * @param packageVersion contains the hash that is expected
- * @param packageFile the local file whose hash is to be checked
- * @throws Exception if the file does not match the hash or the file doesn't exist
- */
- private void verifyHash(PackageVersion packageVersion, File packageFile) throws Exception {
- if (!packageFile.exists()) {
- throw new Exception("Package version [" + packageVersion + "] does not exist, cannot check hash");
- }
-
- if (packageVersion.getMD5() != null) {
- String realMD5 = MessageDigestGenerator.getDigestString(packageFile);
- if (!packageVersion.getMD5().equals(realMD5)) {
- throw new Exception("Package version [" + packageVersion + "] failed MD5 check. expected=["
- + packageVersion.getMD5() + "], actual=[" + realMD5 + "]");
- }
- } else if (packageVersion.getSHA256() != null) {
- FileInputStream is = new FileInputStream(packageFile);
- try {
- MessageDigestGenerator gen = new MessageDigestGenerator("SHA256");
- gen.add(is);
- String realSHA256 = gen.getDigestString();
- if (!packageVersion.getSHA256().equals(realSHA256)) {
- throw new Exception("Package version [" + packageVersion + "] failed SHA256 check. expected=["
- + packageVersion.getSHA256() + "], actual=[" + realSHA256 + "]");
- }
- } finally {
- is.close();
- }
-
- } else {
- log.debug("Package version [" + packageVersion + "] has no MD5/SHA256 hash - not verifying it");
- }
-
- return;
- }
}
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
index 26199d3..3682c18 100644
--- a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
@@ -23,6 +23,7 @@ import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -31,6 +32,7 @@ import java.util.Set;
import org.rhq.bundle.filetemplate.recipe.RecipeContext;
import org.rhq.bundle.filetemplate.recipe.RecipeParser;
import org.rhq.core.domain.content.PackageVersion;
+import org.rhq.core.system.OperatingSystemType;
import org.rhq.core.system.ProcessExecution;
import org.rhq.core.system.ProcessExecutionResults;
import org.rhq.core.system.SystemInfo;
@@ -162,6 +164,8 @@ public class ProcessingRecipeContext extends RecipeContext {
File scriptFile = new File(this.baseWorkingDirectory, exe);
+ ensureExecutable(scriptFile);
+
ProcessExecution pe = new ProcessExecution(scriptFile.getAbsolutePath());
pe.setArguments(exeArgs);
pe.setWaitForCompletion(30 * 60 * 1000L);
@@ -173,6 +177,35 @@ public class ProcessingRecipeContext extends RecipeContext {
}
}
+ private void ensureExecutable(File scriptFile) {
+ boolean success;
+
+ try {
+ Method m = File.class.getMethod("setExecutable", Boolean.TYPE, Boolean.TYPE);
+ Boolean r = (Boolean) m.invoke(scriptFile, Boolean.TRUE, Boolean.TRUE);
+ success = r.booleanValue();
+ } catch (Exception e) {
+ // Oh, if only we'd just stop dilly-dallying and move to JDK6 already
+ if (this.systemInfo.getOperatingSystemType() != OperatingSystemType.WINDOWS) {
+ ProcessExecution pe = new ProcessExecution("chmod");
+ pe.setArguments(new String[] { "u+x", scriptFile.getAbsolutePath() });
+ pe.setWaitForCompletion(30000L);
+ pe.setCheckExecutableExists(false);
+ pe.setWorkingDirectory(scriptFile.getParent());
+ ProcessExecutionResults chmodResults = this.systemInfo.executeProcess(pe);
+ success = (chmodResults.getExitCode() != null && chmodResults.getExitCode().intValue() == 0);
+ } else {
+ success = true; // assume we can execute it on windows
+ }
+ }
+
+ if (!success) {
+ throw new RuntimeException("Cannot ensure that script [" + scriptFile + "] is executable");
+ }
+
+ return;
+ }
+
private ProcessExecution getUnzipExecution(File file, String directory) {
String exe;
List<String> args = null;
diff --git a/modules/plugins/filetemplate-bundle/src/test/java/org/rhq/plugins/filetemplate/ProcessingRecipeContextTest.java b/modules/plugins/filetemplate-bundle/src/test/java/org/rhq/plugins/filetemplate/ProcessingRecipeContextTest.java
index 1099481..47b721f 100644
--- a/modules/plugins/filetemplate-bundle/src/test/java/org/rhq/plugins/filetemplate/ProcessingRecipeContextTest.java
+++ b/modules/plugins/filetemplate-bundle/src/test/java/org/rhq/plugins/filetemplate/ProcessingRecipeContextTest.java
@@ -122,18 +122,22 @@ public class ProcessingRecipeContextTest {
assert zippedFileContent.equals("zipped file content");
}
- @Test(enabled = false)
public void testScriptRecipe() throws Exception {
File testDir = getTestDir("testscript");
+ File testOutDir = getTestDir("testscript-out");
+ File echoOutput = new File(testOutDir, "out.txt");
+ echoOutput.getParentFile().mkdirs();
+ File script = writeFile("echo hello > \"" + echoOutput.getAbsolutePath() + "\"\n", testDir, "bin/test.sh");
- addRecipeCommand("script echo hello");
+ addRecipeCommand("script bin/test.sh");
RecipeContext context = parseRecipeNow(testDir);
Set<String> scripts = context.getScriptFiles();
assert scripts.size() == 1 : scripts;
- assert scripts.contains("run-me.sh") : scripts;
- assert scripts.contains("lots-o-params.sh") : scripts;
+ assert scripts.contains("bin/test.sh") : scripts;
+ String echoOutputContent = readFile(echoOutput);
+ assert echoOutputContent.trim().equals("hello");
}
private ProcessingRecipeContext parseRecipeNow(File testDir) throws Exception {
commit 062ce6a3fdeb4613a5c8e5dfb654d6b314718b10
Merge: 3a9c7df... 1dd05b6...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Mar 3 12:38:10 2010 -0500
Merge branch 'bundle' into bundle-jay
commit 3a9c7dfc0edc71be7c00f67db4d65737e5de3614
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Mar 3 12:37:58 2010 -0500
git forced commit
diff --git a/etc/eclipse-tools/RHQ Remote Debugging - Test.launch b/etc/eclipse-tools/RHQ Remote Debugging - Test.launch
index 821c398..e4e88fc 100644
--- a/etc/eclipse-tools/RHQ Remote Debugging - Test.launch
+++ b/etc/eclipse-tools/RHQ Remote Debugging - Test.launch
@@ -1,19 +1,19 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<launchConfiguration type="org.eclipse.jdt.launching.remoteJavaApplication">
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/rhq"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
-<listEntry value="4"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
-<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
-</listAttribute>
-<booleanAttribute key="org.eclipse.jdt.launching.ALLOW_TERMINATE" value="true"/>
-<mapAttribute key="org.eclipse.jdt.launching.CONNECT_MAP">
-<mapEntry key="port" value="8797"/>
-<mapEntry key="hostname" value="localhost"/>
-</mapAttribute>
-<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="rhq"/>
-<stringAttribute key="org.eclipse.jdt.launching.VM_CONNECTOR_ID" value="org.eclipse.jdt.launching.socketAttachConnector"/>
-</launchConfiguration>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.jdt.launching.remoteJavaApplication">
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+<listEntry value="/rhq"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+<listEntry value="4"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
+<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
+</listAttribute>
+<booleanAttribute key="org.eclipse.jdt.launching.ALLOW_TERMINATE" value="true"/>
+<mapAttribute key="org.eclipse.jdt.launching.CONNECT_MAP">
+<mapEntry key="port" value="8797"/>
+<mapEntry key="hostname" value="localhost"/>
+</mapAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="rhq"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_CONNECTOR_ID" value="org.eclipse.jdt.launching.socketAttachConnector"/>
+</launchConfiguration>
commit 1dd05b6d50a662d89c6aaf62c5e68a060df2bf5d
Merge: 95178af... f7bb4c6...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Mar 3 12:30:56 2010 -0500
Merge branch 'bundle' of ssh://git.fedorahosted.org/git/rhq/rhq into bundle
commit 95178af531e8185e90062e7122908ed4cc7f6597
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Mar 3 12:30:03 2010 -0500
git forced LT commit
diff --git a/etc/eclipse-tools/RHQ Remote Debugging - Test.launch b/etc/eclipse-tools/RHQ Remote Debugging - Test.launch
index 821c398..e4e88fc 100644
--- a/etc/eclipse-tools/RHQ Remote Debugging - Test.launch
+++ b/etc/eclipse-tools/RHQ Remote Debugging - Test.launch
@@ -1,19 +1,19 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<launchConfiguration type="org.eclipse.jdt.launching.remoteJavaApplication">
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/rhq"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
-<listEntry value="4"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
-<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
-</listAttribute>
-<booleanAttribute key="org.eclipse.jdt.launching.ALLOW_TERMINATE" value="true"/>
-<mapAttribute key="org.eclipse.jdt.launching.CONNECT_MAP">
-<mapEntry key="port" value="8797"/>
-<mapEntry key="hostname" value="localhost"/>
-</mapAttribute>
-<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="rhq"/>
-<stringAttribute key="org.eclipse.jdt.launching.VM_CONNECTOR_ID" value="org.eclipse.jdt.launching.socketAttachConnector"/>
-</launchConfiguration>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.jdt.launching.remoteJavaApplication">
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+<listEntry value="/rhq"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+<listEntry value="4"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
+<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
+</listAttribute>
+<booleanAttribute key="org.eclipse.jdt.launching.ALLOW_TERMINATE" value="true"/>
+<mapAttribute key="org.eclipse.jdt.launching.CONNECT_MAP">
+<mapEntry key="port" value="8797"/>
+<mapEntry key="hostname" value="localhost"/>
+</mapAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="rhq"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_CONNECTOR_ID" value="org.eclipse.jdt.launching.socketAttachConnector"/>
+</launchConfiguration>
commit 7104751dfca528c2cd03fefb4ad78427c2919220
Merge: a310714... 845e3c0...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Mar 3 12:29:38 2010 -0500
Merge branch 'bundle-jay' into bundle
commit 845e3c0f4782ff87ca0ecdc9d1d252841b3b5fe1
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Mar 3 12:29:25 2010 -0500
checkin of stable code
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleFile.java b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleFile.java
index dfd1b45..fcc7389 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleFile.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleFile.java
@@ -52,7 +52,7 @@ import org.rhq.core.domain.content.PackageVersion;
@NamedQuery(name = BundleFile.QUERY_FIND_ALL, query = "SELECT bf FROM BundleFile bf"), //
@NamedQuery(name = BundleFile.QUERY_FIND_BY_BUNDLE_VERSION_ID, query = "SELECT bf FROM BundleFile bf WHERE bf.bundleVersion.id = :id") //
})
-@SequenceGenerator(name = "SEQ", sequenceName = "RHQ_BUNDLE_CONFIG_ID_SEQ")
+@SequenceGenerator(name = "SEQ", sequenceName = "RHQ_BUNDLE_FILE_ID_SEQ")
@Table(name = "RHQ_BUNDLE_FILE")
@XmlAccessorType(XmlAccessType.FIELD)
public class BundleFile implements Serializable {
@@ -72,7 +72,7 @@ public class BundleFile implements Serializable {
@JoinColumn(name = "PACKAGE_ID", referencedColumnName = "ID", nullable = true)
@ManyToOne(fetch = FetchType.LAZY)
- private Package pkg;
+ private Package generalPackage;
@JoinColumn(name = "PACKAGE_VERSION_ID", referencedColumnName = "ID", nullable = false)
@ManyToOne(fetch = FetchType.LAZY)
@@ -99,11 +99,11 @@ public class BundleFile implements Serializable {
}
public Package getPackage() {
- return pkg;
+ return generalPackage;
}
public void setPackage(Package pkg) {
- this.pkg = pkg;
+ this.generalPackage = pkg;
}
public PackageVersion getPackageVersion() {
@@ -124,7 +124,7 @@ public class BundleFile implements Serializable {
final int prime = 31;
int result = 1;
result = prime * result + ((bundleVersion == null) ? 0 : bundleVersion.hashCode());
- result = prime * result + ((pkg == null) ? 0 : pkg.hashCode());
+ result = prime * result + ((generalPackage == null) ? 0 : generalPackage.hashCode());
result = prime * result + ((packageVersion == null) ? 0 : packageVersion.hashCode());
return result;
}
@@ -148,11 +148,11 @@ public class BundleFile implements Serializable {
return false;
}
- if (pkg == null) {
- if (other.pkg != null) {
+ if (generalPackage == null) {
+ if (other.generalPackage != null) {
return false;
}
- } else if (!pkg.equals(other.pkg)) {
+ } else if (!generalPackage.equals(other.generalPackage)) {
return false;
}
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceType.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceType.java
index f4582d0..69e8175 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceType.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceType.java
@@ -188,7 +188,7 @@ import org.rhq.core.domain.util.serial.ExternalizableStrategy;
+ "GROUP BY rt.name " //
+ " HAVING COUNT(rt.name) > 1"), //
@NamedQuery(name = ResourceType.QUERY_DYNAMIC_CONFIG_WITH_PLUGIN, query = "" //
- + "SELECT rt.plugin || ' - ' || rt.name, rt.plugin || '-' || rt.name FROM ResourceType rt" ) //
+ + "SELECT rt.plugin || ' - ' || rt.name, rt.plugin || '-' || rt.name FROM ResourceType rt") //
})
@NamedNativeQueries( {
// TODO: Add authz conditions to the below query.
@@ -236,14 +236,14 @@ import org.rhq.core.domain.util.serial.ExternalizableStrategy;
+ "WHERE rtp2.resource_type_id = crt2.id) " + "AND crt2.category = ? " +
// "ORDER BY crt2.name" +
")) ORDER BY name", resultSetMapping = ResourceType.MAPPING_FIND_CHILDREN_BY_CATEGORY) //
- })
+})
@SqlResultSetMapping(name = ResourceType.MAPPING_FIND_CHILDREN_BY_CATEGORY, entities = { @EntityResult(entityClass = ResourceType.class) })
// @Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
public class ResourceType implements Externalizable, Comparable<ResourceType> {
private static final long serialVersionUID = 2L;
public static final String TABLE_NAME = "RHQ_RESOURCE_TYPE";
-
+
public static final ResourceType ANY_PLATFORM_TYPE = null;
public static final String QUERY_FIND_BY_NAME = "ResourceType.findByName";
@@ -379,7 +379,7 @@ public class ResourceType implements Externalizable, Comparable<ResourceType> {
@OneToMany(mappedBy = "resourceType", cascade = CascadeType.ALL)
private Set<ProductVersion> productVersions;
- @OneToOne(mappedBy = "resourceType", fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE }, optional = true)
+ @OneToOne(mappedBy = "resourceType", fetch = FetchType.LAZY, cascade = CascadeType.ALL, optional = true)
private BundleType bundleType;
@Transient
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java
index ba53759..d9b77af 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java
@@ -19,12 +19,9 @@
package org.rhq.enterprise.server.bundle;
-import java.util.HashSet;
import java.util.Set;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
-import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
-import org.rhq.core.domain.configuration.definition.PropertySimpleType;
/**
* This class is general to all Bundle handling server side plugins. It is returned by the SSP when parsing
@@ -46,14 +43,6 @@ public class RecipeParseResults {
}
public ConfigurationDefinition getConfigDef() {
-
- // stub out a test ConfigDef here until we actual parse the recipe
- System.out.println("!!!!!! REMOVE THIS TEST CODE !!!!!!!!");
- configDef = new ConfigurationDefinition("SampleBundle", "Stubbed ConfigDef for Sample Bundle");
- configDef.put(new PropertyDefinitionSimple("sample.bundle.deploy.directory",
- "Stubbed Property for deploy directory (must already exist on target platform)", true,
- PropertySimpleType.STRING));
-
return configDef;
}
@@ -62,12 +51,6 @@ public class RecipeParseResults {
}
public Set<String> getBundleFileNames() {
- // stub out a test set of BundleFiles here until we actual parse the recipe. For now lets just deploy
- // a war file into an existing app server dir.
- System.out.println("!!!!!! REMOVE THIS TEST CODE !!!!!!!!");
- bundleFileNames = new HashSet<String>();
- bundleFileNames.add("sample-bundle.war");
-
return bundleFileNames;
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
index 1ca01c8..24c6dae 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
@@ -36,7 +36,9 @@ import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleFile;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageType;
+import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.content.Repo;
import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleVersionCriteria;
@@ -54,9 +56,9 @@ import org.rhq.enterprise.server.util.LookupUtil;
@Test
public class BundleManagerBeanTest extends AbstractEJB3Test {
- private static final String TEST_PREFIX = "bundletest";
+ private static final boolean TESTS_ENABLED = true;
- private static final boolean ENABLED = true;
+ private static final String TEST_PREFIX = "bundletest";
private BundleManagerLocal bundleManager;
@@ -65,7 +67,8 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
@BeforeMethod
public void beforeMethod() {
- super.startTest();
+ // try and clean up any junk that may be lying around from a failed run
+ cleanupDatabase();
this.ps = new TestBundleServerPluginService();
prepareCustomServerPluginService(this.ps);
@@ -76,6 +79,13 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
@AfterMethod(alwaysRun = true)
public void afterMethod() throws Exception {
+ cleanupDatabase();
+
+ unprepareServerPluginService();
+ this.ps = null;
+ }
+
+ private void cleanupDatabase() {
EntityManager em = null;
try {
@@ -86,42 +96,63 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
List doomed;
// clean up any tests that don't already clean up after themselves
- q = em.createQuery("SELECT bv FROM BundleVersion bv WHERE bv.bundle.name LIKE '" + TEST_PREFIX + "%'");
+
+ // remove bundleversions which cascade remove bundlefiles and bundledeploydefs
+ q = em.createQuery("SELECT bv FROM BundleVersion bv WHERE bv.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
for (Object removeMe : doomed) {
em.remove(em.getReference(BundleVersion.class, ((BundleVersion) removeMe).getId()));
}
-
+ // remove any orphaned bfs
+ q = em.createQuery("SELECT bf FROM BundleFile bf WHERE bf.generalPackage.name LIKE '" + TEST_PREFIX + "%'");
+ doomed = q.getResultList();
+ for (Object removeMe : doomed) {
+ em.remove(em.getReference(BundleFile.class, ((BundleFile) removeMe).getId()));
+ }
+ // remove packages which cascade remove packageversions
+ q = em.createQuery("SELECT p FROM Package p WHERE p.name LIKE '" + TEST_PREFIX + "%'");
+ doomed = q.getResultList();
+ for (Object removeMe : doomed) {
+ em.remove(em.getReference(Package.class, ((Package) removeMe).getId()));
+ }
+ // remove any orphaned pvs
+ q = em.createQuery("SELECT pv FROM PackageVersion pv WHERE pv.generalPackage.name LIKE '" + TEST_PREFIX
+ + "%'");
+ doomed = q.getResultList();
+ for (Object removeMe : doomed) {
+ em.remove(em.getReference(PackageVersion.class, ((PackageVersion) removeMe).getId()));
+ }
+ // remove bundles which cascade remove repos
q = em.createQuery("SELECT b FROM Bundle b WHERE b.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
for (Object removeMe : doomed) {
em.remove(em.getReference(Bundle.class, ((Bundle) removeMe).getId()));
}
-
+ // remove any orphaned repos
q = em.createQuery("SELECT r FROM Repo r WHERE r.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
for (Object removeMe : doomed) {
em.remove(em.getReference(Repo.class, ((Repo) removeMe).getId()));
}
-
+ // remove ResourceTypes which cascade remove BundleTypes and PackageTypes
+ q = em.createQuery("SELECT rt FROM ResourceType rt WHERE rt.name LIKE '" + TEST_PREFIX + "%'");
+ doomed = q.getResultList();
+ for (Object removeMe : doomed) {
+ em.remove(em.getReference(ResourceType.class, ((ResourceType) removeMe).getId()));
+ }
+ // remove any orphaned BundleTypes
q = em.createQuery("SELECT bt FROM BundleType bt WHERE bt.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
for (Object removeMe : doomed) {
em.remove(em.getReference(BundleType.class, ((BundleType) removeMe).getId()));
}
-
+ // remove any orphaned packagetypes
q = em.createQuery("SELECT pt FROM PackageType pt WHERE pt.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
for (Object removeMe : doomed) {
em.remove(em.getReference(PackageType.class, ((PackageType) removeMe).getId()));
}
- q = em.createQuery("SELECT rt FROM ResourceType rt WHERE rt.name LIKE '" + TEST_PREFIX + "%'");
- doomed = q.getResultList();
- for (Object removeMe : doomed) {
- em.remove(em.getReference(ResourceType.class, ((ResourceType) removeMe).getId()));
- }
-
getTransactionManager().commit();
em.close();
em = null;
@@ -136,14 +167,9 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
em.close();
}
}
-
- unprepareServerPluginService();
- this.ps = null;
-
- super.endTest();
}
- @Test(enabled = ENABLED)
+ @Test(enabled = TESTS_ENABLED)
public void testGetBundleTypes() throws Exception {
BundleType bt1 = createBundleType("one");
BundleType bt2 = createBundleType("two");
@@ -159,13 +185,13 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
assert btNames.contains(bt2.getName());
}
- @Test(enabled = ENABLED)
+ @Test(enabled = TESTS_ENABLED)
public void testCreateBundle() throws Exception {
Bundle b1 = createBundle("one");
assertNotNull(b1);
}
- @Test(enabled = ENABLED)
+ @Test(enabled = TESTS_ENABLED)
public void testCreateBundleVersion() throws Exception {
Bundle b1 = createBundle("one");
assertNotNull(b1);
@@ -177,7 +203,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
assertEquals("1.1", bv2.getVersion());
}
- @Test(enabled = ENABLED)
+ @Test(enabled = TESTS_ENABLED)
public void testAddBundleFiles() throws Exception {
Bundle b1 = createBundle("one");
assertNotNull(b1);
@@ -189,7 +215,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
+ "-bundlefile-2", "1.0", null, "Test Bundle File # 2".getBytes(), false);
}
- @Test(enabled = ENABLED)
+ @Test(enabled = TESTS_ENABLED)
public void testfindBundlesByCriteria() throws Exception {
Bundle b1 = createBundle("one");
Bundle b2 = createBundle("two");
@@ -246,7 +272,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
assertEquals(b.getName(), r.getName());
}
- @Test(enabled = ENABLED)
+ @Test(enabled = TESTS_ENABLED)
public void testfindBundleVersionsByCriteria() throws Exception {
Bundle b1 = createBundle("one");
BundleVersion bv1 = createBundleVersion(b1.getName(), "1.0", b1);
@@ -331,7 +357,8 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
}
private PackageType createPackageType(String name, ResourceType rt) throws Exception {
- final String fullName = TEST_PREFIX + "-packagetype-" + name;
+ // the package type is named the same as the bundle type
+ final String fullName = TEST_PREFIX + "-type-" + name;
PackageType pt = new PackageType(fullName, rt);
TransactionManager txMgr = getTransactionManager();
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 64bd5af..dc43f97 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
@@ -22,11 +22,15 @@ import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
+import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
+import org.rhq.core.domain.configuration.definition.PropertySimpleType;
import org.rhq.core.domain.plugin.PluginKey;
import org.rhq.core.domain.plugin.PluginStatusType;
import org.rhq.core.domain.plugin.ServerPlugin;
@@ -40,6 +44,7 @@ import org.rhq.enterprise.server.plugin.pc.ServerPluginManager;
import org.rhq.enterprise.server.plugin.pc.ServerPluginService;
import org.rhq.enterprise.server.plugin.pc.ServerPluginType;
import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginFacet;
import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginManager;
import org.rhq.enterprise.server.xmlschema.ServerPluginDescriptorMetadataParser;
import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType;
@@ -165,5 +170,33 @@ public class TestBundleServerPluginService extends ServerPluginService implement
components.put(environment.getPluginKey().getPluginName(), component);
return component;
}
+
+ @Override
+ public BundleServerPluginFacet getBundleServerPluginFacet(String bundleTypeName) {
+
+ return new TestBundlePluginComponent();
+ }
+ }
+
+ class TestBundlePluginComponent implements BundleServerPluginFacet {
+
+ public TestBundlePluginComponent() {
+ };
+
+ public RecipeParseResults parseRecipe(String recipe) throws Exception {
+
+ ConfigurationDefinition configDef;
+ Set<String> bundleFileNames;
+
+ configDef = new ConfigurationDefinition("SampleBundle", "Stubbed ConfigDef for Sample Bundle");
+ configDef.put(new PropertyDefinitionSimple("sample.bundle.deploy.directory",
+ "Stubbed Property for deploy directory (must already exist on target platform)", true,
+ PropertySimpleType.STRING));
+
+ bundleFileNames = new HashSet<String>();
+ bundleFileNames.add("sample-bundle.war");
+
+ return new RecipeParseResults(configDef, bundleFileNames);
+ }
}
}
\ No newline at end of file
commit a310714100956e5a1c6cd9fb452f5c94cdba35d5
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Mar 3 12:23:11 2010 -0500
Back to steady state - tests passing
notable changes:
- fixed sequence decl for BundleFile and changed pkg field to generalPackage for consistency
- took out test stub code from RecipeParseResults
- added test impl of BundleServerPluginFacet
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleFile.java b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleFile.java
index dfd1b45..fcc7389 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleFile.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleFile.java
@@ -52,7 +52,7 @@ import org.rhq.core.domain.content.PackageVersion;
@NamedQuery(name = BundleFile.QUERY_FIND_ALL, query = "SELECT bf FROM BundleFile bf"), //
@NamedQuery(name = BundleFile.QUERY_FIND_BY_BUNDLE_VERSION_ID, query = "SELECT bf FROM BundleFile bf WHERE bf.bundleVersion.id = :id") //
})
-@SequenceGenerator(name = "SEQ", sequenceName = "RHQ_BUNDLE_CONFIG_ID_SEQ")
+@SequenceGenerator(name = "SEQ", sequenceName = "RHQ_BUNDLE_FILE_ID_SEQ")
@Table(name = "RHQ_BUNDLE_FILE")
@XmlAccessorType(XmlAccessType.FIELD)
public class BundleFile implements Serializable {
@@ -72,7 +72,7 @@ public class BundleFile implements Serializable {
@JoinColumn(name = "PACKAGE_ID", referencedColumnName = "ID", nullable = true)
@ManyToOne(fetch = FetchType.LAZY)
- private Package pkg;
+ private Package generalPackage;
@JoinColumn(name = "PACKAGE_VERSION_ID", referencedColumnName = "ID", nullable = false)
@ManyToOne(fetch = FetchType.LAZY)
@@ -99,11 +99,11 @@ public class BundleFile implements Serializable {
}
public Package getPackage() {
- return pkg;
+ return generalPackage;
}
public void setPackage(Package pkg) {
- this.pkg = pkg;
+ this.generalPackage = pkg;
}
public PackageVersion getPackageVersion() {
@@ -124,7 +124,7 @@ public class BundleFile implements Serializable {
final int prime = 31;
int result = 1;
result = prime * result + ((bundleVersion == null) ? 0 : bundleVersion.hashCode());
- result = prime * result + ((pkg == null) ? 0 : pkg.hashCode());
+ result = prime * result + ((generalPackage == null) ? 0 : generalPackage.hashCode());
result = prime * result + ((packageVersion == null) ? 0 : packageVersion.hashCode());
return result;
}
@@ -148,11 +148,11 @@ public class BundleFile implements Serializable {
return false;
}
- if (pkg == null) {
- if (other.pkg != null) {
+ if (generalPackage == null) {
+ if (other.generalPackage != null) {
return false;
}
- } else if (!pkg.equals(other.pkg)) {
+ } else if (!generalPackage.equals(other.generalPackage)) {
return false;
}
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceType.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceType.java
index f4582d0..69e8175 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceType.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/ResourceType.java
@@ -188,7 +188,7 @@ import org.rhq.core.domain.util.serial.ExternalizableStrategy;
+ "GROUP BY rt.name " //
+ " HAVING COUNT(rt.name) > 1"), //
@NamedQuery(name = ResourceType.QUERY_DYNAMIC_CONFIG_WITH_PLUGIN, query = "" //
- + "SELECT rt.plugin || ' - ' || rt.name, rt.plugin || '-' || rt.name FROM ResourceType rt" ) //
+ + "SELECT rt.plugin || ' - ' || rt.name, rt.plugin || '-' || rt.name FROM ResourceType rt") //
})
@NamedNativeQueries( {
// TODO: Add authz conditions to the below query.
@@ -236,14 +236,14 @@ import org.rhq.core.domain.util.serial.ExternalizableStrategy;
+ "WHERE rtp2.resource_type_id = crt2.id) " + "AND crt2.category = ? " +
// "ORDER BY crt2.name" +
")) ORDER BY name", resultSetMapping = ResourceType.MAPPING_FIND_CHILDREN_BY_CATEGORY) //
- })
+})
@SqlResultSetMapping(name = ResourceType.MAPPING_FIND_CHILDREN_BY_CATEGORY, entities = { @EntityResult(entityClass = ResourceType.class) })
// @Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
public class ResourceType implements Externalizable, Comparable<ResourceType> {
private static final long serialVersionUID = 2L;
public static final String TABLE_NAME = "RHQ_RESOURCE_TYPE";
-
+
public static final ResourceType ANY_PLATFORM_TYPE = null;
public static final String QUERY_FIND_BY_NAME = "ResourceType.findByName";
@@ -379,7 +379,7 @@ public class ResourceType implements Externalizable, Comparable<ResourceType> {
@OneToMany(mappedBy = "resourceType", cascade = CascadeType.ALL)
private Set<ProductVersion> productVersions;
- @OneToOne(mappedBy = "resourceType", fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE }, optional = true)
+ @OneToOne(mappedBy = "resourceType", fetch = FetchType.LAZY, cascade = CascadeType.ALL, optional = true)
private BundleType bundleType;
@Transient
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java
index ba53759..d9b77af 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java
@@ -19,12 +19,9 @@
package org.rhq.enterprise.server.bundle;
-import java.util.HashSet;
import java.util.Set;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
-import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
-import org.rhq.core.domain.configuration.definition.PropertySimpleType;
/**
* This class is general to all Bundle handling server side plugins. It is returned by the SSP when parsing
@@ -46,14 +43,6 @@ public class RecipeParseResults {
}
public ConfigurationDefinition getConfigDef() {
-
- // stub out a test ConfigDef here until we actual parse the recipe
- System.out.println("!!!!!! REMOVE THIS TEST CODE !!!!!!!!");
- configDef = new ConfigurationDefinition("SampleBundle", "Stubbed ConfigDef for Sample Bundle");
- configDef.put(new PropertyDefinitionSimple("sample.bundle.deploy.directory",
- "Stubbed Property for deploy directory (must already exist on target platform)", true,
- PropertySimpleType.STRING));
-
return configDef;
}
@@ -62,12 +51,6 @@ public class RecipeParseResults {
}
public Set<String> getBundleFileNames() {
- // stub out a test set of BundleFiles here until we actual parse the recipe. For now lets just deploy
- // a war file into an existing app server dir.
- System.out.println("!!!!!! REMOVE THIS TEST CODE !!!!!!!!");
- bundleFileNames = new HashSet<String>();
- bundleFileNames.add("sample-bundle.war");
-
return bundleFileNames;
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
index 1ca01c8..24c6dae 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
@@ -36,7 +36,9 @@ import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleFile;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageType;
+import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.content.Repo;
import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleVersionCriteria;
@@ -54,9 +56,9 @@ import org.rhq.enterprise.server.util.LookupUtil;
@Test
public class BundleManagerBeanTest extends AbstractEJB3Test {
- private static final String TEST_PREFIX = "bundletest";
+ private static final boolean TESTS_ENABLED = true;
- private static final boolean ENABLED = true;
+ private static final String TEST_PREFIX = "bundletest";
private BundleManagerLocal bundleManager;
@@ -65,7 +67,8 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
@BeforeMethod
public void beforeMethod() {
- super.startTest();
+ // try and clean up any junk that may be lying around from a failed run
+ cleanupDatabase();
this.ps = new TestBundleServerPluginService();
prepareCustomServerPluginService(this.ps);
@@ -76,6 +79,13 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
@AfterMethod(alwaysRun = true)
public void afterMethod() throws Exception {
+ cleanupDatabase();
+
+ unprepareServerPluginService();
+ this.ps = null;
+ }
+
+ private void cleanupDatabase() {
EntityManager em = null;
try {
@@ -86,42 +96,63 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
List doomed;
// clean up any tests that don't already clean up after themselves
- q = em.createQuery("SELECT bv FROM BundleVersion bv WHERE bv.bundle.name LIKE '" + TEST_PREFIX + "%'");
+
+ // remove bundleversions which cascade remove bundlefiles and bundledeploydefs
+ q = em.createQuery("SELECT bv FROM BundleVersion bv WHERE bv.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
for (Object removeMe : doomed) {
em.remove(em.getReference(BundleVersion.class, ((BundleVersion) removeMe).getId()));
}
-
+ // remove any orphaned bfs
+ q = em.createQuery("SELECT bf FROM BundleFile bf WHERE bf.generalPackage.name LIKE '" + TEST_PREFIX + "%'");
+ doomed = q.getResultList();
+ for (Object removeMe : doomed) {
+ em.remove(em.getReference(BundleFile.class, ((BundleFile) removeMe).getId()));
+ }
+ // remove packages which cascade remove packageversions
+ q = em.createQuery("SELECT p FROM Package p WHERE p.name LIKE '" + TEST_PREFIX + "%'");
+ doomed = q.getResultList();
+ for (Object removeMe : doomed) {
+ em.remove(em.getReference(Package.class, ((Package) removeMe).getId()));
+ }
+ // remove any orphaned pvs
+ q = em.createQuery("SELECT pv FROM PackageVersion pv WHERE pv.generalPackage.name LIKE '" + TEST_PREFIX
+ + "%'");
+ doomed = q.getResultList();
+ for (Object removeMe : doomed) {
+ em.remove(em.getReference(PackageVersion.class, ((PackageVersion) removeMe).getId()));
+ }
+ // remove bundles which cascade remove repos
q = em.createQuery("SELECT b FROM Bundle b WHERE b.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
for (Object removeMe : doomed) {
em.remove(em.getReference(Bundle.class, ((Bundle) removeMe).getId()));
}
-
+ // remove any orphaned repos
q = em.createQuery("SELECT r FROM Repo r WHERE r.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
for (Object removeMe : doomed) {
em.remove(em.getReference(Repo.class, ((Repo) removeMe).getId()));
}
-
+ // remove ResourceTypes which cascade remove BundleTypes and PackageTypes
+ q = em.createQuery("SELECT rt FROM ResourceType rt WHERE rt.name LIKE '" + TEST_PREFIX + "%'");
+ doomed = q.getResultList();
+ for (Object removeMe : doomed) {
+ em.remove(em.getReference(ResourceType.class, ((ResourceType) removeMe).getId()));
+ }
+ // remove any orphaned BundleTypes
q = em.createQuery("SELECT bt FROM BundleType bt WHERE bt.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
for (Object removeMe : doomed) {
em.remove(em.getReference(BundleType.class, ((BundleType) removeMe).getId()));
}
-
+ // remove any orphaned packagetypes
q = em.createQuery("SELECT pt FROM PackageType pt WHERE pt.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
for (Object removeMe : doomed) {
em.remove(em.getReference(PackageType.class, ((PackageType) removeMe).getId()));
}
- q = em.createQuery("SELECT rt FROM ResourceType rt WHERE rt.name LIKE '" + TEST_PREFIX + "%'");
- doomed = q.getResultList();
- for (Object removeMe : doomed) {
- em.remove(em.getReference(ResourceType.class, ((ResourceType) removeMe).getId()));
- }
-
getTransactionManager().commit();
em.close();
em = null;
@@ -136,14 +167,9 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
em.close();
}
}
-
- unprepareServerPluginService();
- this.ps = null;
-
- super.endTest();
}
- @Test(enabled = ENABLED)
+ @Test(enabled = TESTS_ENABLED)
public void testGetBundleTypes() throws Exception {
BundleType bt1 = createBundleType("one");
BundleType bt2 = createBundleType("two");
@@ -159,13 +185,13 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
assert btNames.contains(bt2.getName());
}
- @Test(enabled = ENABLED)
+ @Test(enabled = TESTS_ENABLED)
public void testCreateBundle() throws Exception {
Bundle b1 = createBundle("one");
assertNotNull(b1);
}
- @Test(enabled = ENABLED)
+ @Test(enabled = TESTS_ENABLED)
public void testCreateBundleVersion() throws Exception {
Bundle b1 = createBundle("one");
assertNotNull(b1);
@@ -177,7 +203,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
assertEquals("1.1", bv2.getVersion());
}
- @Test(enabled = ENABLED)
+ @Test(enabled = TESTS_ENABLED)
public void testAddBundleFiles() throws Exception {
Bundle b1 = createBundle("one");
assertNotNull(b1);
@@ -189,7 +215,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
+ "-bundlefile-2", "1.0", null, "Test Bundle File # 2".getBytes(), false);
}
- @Test(enabled = ENABLED)
+ @Test(enabled = TESTS_ENABLED)
public void testfindBundlesByCriteria() throws Exception {
Bundle b1 = createBundle("one");
Bundle b2 = createBundle("two");
@@ -246,7 +272,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
assertEquals(b.getName(), r.getName());
}
- @Test(enabled = ENABLED)
+ @Test(enabled = TESTS_ENABLED)
public void testfindBundleVersionsByCriteria() throws Exception {
Bundle b1 = createBundle("one");
BundleVersion bv1 = createBundleVersion(b1.getName(), "1.0", b1);
@@ -331,7 +357,8 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
}
private PackageType createPackageType(String name, ResourceType rt) throws Exception {
- final String fullName = TEST_PREFIX + "-packagetype-" + name;
+ // the package type is named the same as the bundle type
+ final String fullName = TEST_PREFIX + "-type-" + name;
PackageType pt = new PackageType(fullName, rt);
TransactionManager txMgr = getTransactionManager();
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 64bd5af..dc43f97 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
@@ -22,11 +22,15 @@ import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
+import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
+import org.rhq.core.domain.configuration.definition.PropertySimpleType;
import org.rhq.core.domain.plugin.PluginKey;
import org.rhq.core.domain.plugin.PluginStatusType;
import org.rhq.core.domain.plugin.ServerPlugin;
@@ -40,6 +44,7 @@ import org.rhq.enterprise.server.plugin.pc.ServerPluginManager;
import org.rhq.enterprise.server.plugin.pc.ServerPluginService;
import org.rhq.enterprise.server.plugin.pc.ServerPluginType;
import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginFacet;
import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginManager;
import org.rhq.enterprise.server.xmlschema.ServerPluginDescriptorMetadataParser;
import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType;
@@ -165,5 +170,33 @@ public class TestBundleServerPluginService extends ServerPluginService implement
components.put(environment.getPluginKey().getPluginName(), component);
return component;
}
+
+ @Override
+ public BundleServerPluginFacet getBundleServerPluginFacet(String bundleTypeName) {
+
+ return new TestBundlePluginComponent();
+ }
+ }
+
+ class TestBundlePluginComponent implements BundleServerPluginFacet {
+
+ public TestBundlePluginComponent() {
+ };
+
+ public RecipeParseResults parseRecipe(String recipe) throws Exception {
+
+ ConfigurationDefinition configDef;
+ Set<String> bundleFileNames;
+
+ configDef = new ConfigurationDefinition("SampleBundle", "Stubbed ConfigDef for Sample Bundle");
+ configDef.put(new PropertyDefinitionSimple("sample.bundle.deploy.directory",
+ "Stubbed Property for deploy directory (must already exist on target platform)", true,
+ PropertySimpleType.STRING));
+
+ bundleFileNames = new HashSet<String>();
+ bundleFileNames.add("sample-bundle.war");
+
+ return new RecipeParseResults(configDef, bundleFileNames);
+ }
}
}
\ No newline at end of file
commit f7bb4c6924ea155514a7818223737aa89b2aaa04
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Wed Mar 3 01:51:39 2010 -0500
add agent bundle plugin unit tests
diff --git a/.classpath b/.classpath
index c6a1ed2..fe06650 100644
--- a/.classpath
+++ b/.classpath
@@ -126,6 +126,7 @@
<classpathentry kind="src" path="modules/plugins/augeas/src/main/java"/>
<classpathentry kind="src" path="modules/plugins/augeas/src/test/java"/>
<classpathentry kind="src" path="modules/plugins/filetemplate-bundle/src/main/java"/>
+ <classpathentry kind="src" path="modules/plugins/filetemplate-bundle/src/test/java"/>
<classpathentry kind="src" path="modules/helpers/rtfilter/src/main/java"/>
<classpathentry kind="src" path="modules/helpers/pluginAnnotations/src/main/java"/>
<classpathentry kind="src" path="modules/helpers/pluginGen/src/main/java"/>
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
index ffe24f2..26199d3 100644
--- a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
@@ -34,6 +34,7 @@ import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.system.ProcessExecution;
import org.rhq.core.system.ProcessExecutionResults;
import org.rhq.core.system.SystemInfo;
+import org.rhq.core.util.file.FileUtil;
/**
* A recipe context that processes the recipe as it adds stuff to the context
@@ -61,7 +62,7 @@ public class ProcessingRecipeContext extends RecipeContext {
File existingFile = new File(this.baseWorkingDirectory, filename);
- ProcessExecution pe = getUnzipExecution(filename, directory);
+ ProcessExecution pe = getUnzipExecution(existingFile, directory);
if (pe != null) {
ProcessExecutionResults results = this.systemInfo.executeProcess(pe);
if (results.getError() != null) {
@@ -69,7 +70,7 @@ public class ProcessingRecipeContext extends RecipeContext {
} else if (results.getExitCode() == null || results.getExitCode().intValue() > 0) {
throw new RuntimeException("Failed to unbundle file [" + pe + "]: " + results);
}
- existingFile.delete();
+ // existingFile.delete(); WOULD WE WANT TO REMOVE THE COMPRESSED FILE?
} else {
// not a zipped format - just move the file to the directory as-is
File newFile = new File(directory, filename);
@@ -80,21 +81,27 @@ public class ProcessingRecipeContext extends RecipeContext {
}
@Override
- public void addFile(String filename, String directory) {
- super.addDeployFile(filename, directory);
+ public void addFile(String source, String destination) {
+ super.addFile(source, destination);
- File existingFile = new File(this.baseWorkingDirectory, filename);
- File newFile = new File(directory, filename);
- if (!existingFile.renameTo(newFile)) {
- throw new RuntimeException("Failed to move file [" + existingFile + "] to [" + newFile + "]");
+ File sourceFile = new File(this.baseWorkingDirectory, source);
+ File destinationFile = new File(destination);
+
+ try {
+ destinationFile.getParentFile().mkdirs();
+ FileUtil.copyFile(sourceFile, destinationFile);
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to copy file [" + sourceFile + "] to [" + destinationFile + "]", e);
}
+
+ return;
}
@Override
public void addRealizedFile(String file) {
super.addRealizedFile(file);
- File trueFile = new File(file);
+ File trueFile = new File(this.baseWorkingDirectory, file);
RecipeParser parser = getParser();
File realizedTmpFile = null;
FileWriter realizedTmpFileWriter = null;
@@ -166,42 +173,44 @@ public class ProcessingRecipeContext extends RecipeContext {
}
}
- private ProcessExecution getUnzipExecution(String filename, String directory) {
+ private ProcessExecution getUnzipExecution(File file, String directory) {
String exe;
List<String> args = null;
- if (filename.endsWith(".tar")) {
+ String filepath = file.getAbsolutePath();
+
+ if (filepath.endsWith(".tar")) {
exe = "tar";
args = new ArrayList<String>();
args.add("xf");
- args.add(filename);
+ args.add(filepath);
args.add("-C");
args.add(directory);
- } else if (filename.endsWith(".tar.bz2") || filename.endsWith(".tbz2") || filename.endsWith(".tbz")) {
+ } else if (filepath.endsWith(".tar.bz2") || filepath.endsWith(".tbz2") || filepath.endsWith(".tbz")) {
exe = "tar";
args = new ArrayList<String>();
args.add("xfj");
- args.add(filename);
+ args.add(filepath);
args.add("-C");
args.add(directory);
- } else if (filename.endsWith(".tar.gz") || filename.endsWith(".tgz")) {
+ } else if (filepath.endsWith(".tar.gz") || filepath.endsWith(".tgz")) {
exe = "tar";
args = new ArrayList<String>();
args.add("xfz");
- args.add(filename);
+ args.add(filepath);
args.add("-C");
args.add(directory);
- } else if (filename.endsWith(".zip")) {
+ } else if (filepath.endsWith(".zip")) {
exe = "unzip";
args = new ArrayList<String>();
- args.add(filename);
+ args.add(filepath);
args.add("-d");
args.add(directory);
- } else if (filename.endsWith(".rpm")) {
+ } else if (filepath.endsWith(".rpm")) {
exe = "rpm";
args = new ArrayList<String>();
args.add("-i");
- args.add(filename);
+ args.add(filepath);
if (directory != null && directory.length() > 0) {
args.add("--prefix");
args.add(directory);
@@ -213,6 +222,7 @@ public class ProcessingRecipeContext extends RecipeContext {
ProcessExecution pe = new ProcessExecution(exe);
pe.setArguments(args);
pe.setWaitForCompletion(30 * 60 * 1000L);
+ pe.setCheckExecutableExists(false);
pe.setWorkingDirectory(this.baseWorkingDirectory);
return pe;
}
diff --git a/modules/plugins/filetemplate-bundle/src/test/java/org/rhq/plugins/filetemplate/ProcessingRecipeContextTest.java b/modules/plugins/filetemplate-bundle/src/test/java/org/rhq/plugins/filetemplate/ProcessingRecipeContextTest.java
new file mode 100644
index 0000000..1099481
--- /dev/null
+++ b/modules/plugins/filetemplate-bundle/src/test/java/org/rhq/plugins/filetemplate/ProcessingRecipeContextTest.java
@@ -0,0 +1,225 @@
+/*
+ * 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, 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.filetemplate;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Map;
+import java.util.Set;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import org.rhq.bundle.filetemplate.recipe.RecipeContext;
+import org.rhq.bundle.filetemplate.recipe.RecipeParser;
+import org.rhq.core.domain.content.PackageVersion;
+import org.rhq.core.pluginapi.util.FileUtils;
+import org.rhq.core.system.SystemInfo;
+import org.rhq.core.system.SystemInfoFactory;
+import org.rhq.core.util.stream.StreamUtil;
+
+@Test
+public class ProcessingRecipeContextTest {
+ private StringBuilder recipe;
+
+ @BeforeMethod
+ public void cleanRecipeBeforeMethod() {
+ cleanRecipe();
+ }
+
+ @AfterClass
+ public void afterClass() throws IOException {
+ FileUtils.purge(getTmpDir(), true);
+ }
+
+ public void testRealizeRecipe() throws Exception {
+ File testDir = getTestDir("testrealize");
+ File file = writeFile("a b c\nhello<% var %>world\na b c\n", testDir, "config.txt");
+
+ addRecipeCommand("realize --file=" + file.getName());
+
+ ProcessingRecipeContext context = createRecipeContext(testDir);
+ context.addReplacementVariableValue("var", "BOO");
+ context = parseRecipeNow(context);
+
+ Set<String> files = context.getRealizedFiles();
+ assert files.size() == 1 : files;
+ assert files.contains(file.getName()) : files;
+
+ String realizedContent = readFile(file);
+ assert realizedContent.equals("a b c\nhelloBOOworld\na b c\n") : realizedContent;
+ }
+
+ public void testFileRecipe() throws Exception {
+ File testDir = getTestDir("testfile");
+ File testDestDir = getTestDir("testfile-dest");
+ File runme = writeFile("runme script", testDir, "run-me.sh");
+ File runmeDest = new File(testDestDir, "run-me.sh");
+ File another = writeFile("<wotgorilla/>", testDir, "META-INF/another.xml");
+ File anotherDest = new File(testDestDir, "/OTHER/another.xml");
+
+ addRecipeCommand("file --source=run-me.sh \"--destination=" + runmeDest + "\"");
+ addRecipeCommand("file -s META-INF/another.xml -d \"" + anotherDest + "\"");
+
+ RecipeContext context = parseRecipeNow(testDir);
+
+ Map<String, String> files = context.getFiles();
+ assert files.size() == 2 : files;
+ assert files.get("run-me.sh") != null : files;
+ assert files.get("run-me.sh").equals(runmeDest.getPath()) : files;
+ assert files.get("META-INF/another.xml") != null : files;
+ assert files.get("META-INF/another.xml").equals(anotherDest.getPath()) : files;
+
+ String runmeContent = readFile(runme);
+ String runmeDestContent = readFile(runmeDest);
+ assert runmeContent.equals(runmeDestContent) : runmeDestContent;
+ String anotherContent = readFile(another);
+ String anotherDestContent = readFile(anotherDest);
+ assert anotherContent.equals(anotherDestContent) : anotherDestContent;
+ }
+
+ public void testDeployRecipe() throws Exception {
+ File testDir = getTestDir("testdeploy");
+ File testDestDir = getTestDir("testdeploy-dest");
+ File unzippedFile = new File(testDestDir, "zipped-file.txt");
+ File zipFile = createZip("zipped file content", testDir, "deploy-test.zip", unzippedFile.getName());
+
+ addRecipeCommand("deploy -f " + zipFile.getName() + " -d \"" + testDestDir + "\"");
+
+ RecipeContext context = parseRecipeNow(testDir);
+
+ Map<String, String> files = context.getDeployFiles();
+ assert files.size() == 1 : files;
+ assert files.get(zipFile.getName()) != null;
+
+ String zippedFileContent = readFile(unzippedFile);
+ assert zippedFileContent.equals("zipped file content");
+ }
+
+ @Test(enabled = false)
+ public void testScriptRecipe() throws Exception {
+ File testDir = getTestDir("testscript");
+
+ addRecipeCommand("script echo hello");
+
+ RecipeContext context = parseRecipeNow(testDir);
+
+ Set<String> scripts = context.getScriptFiles();
+ assert scripts.size() == 1 : scripts;
+ assert scripts.contains("run-me.sh") : scripts;
+ assert scripts.contains("lots-o-params.sh") : scripts;
+ }
+
+ private ProcessingRecipeContext parseRecipeNow(File testDir) throws Exception {
+ ProcessingRecipeContext context = createRecipeContext(testDir);
+ return parseRecipeNow(context);
+ }
+
+ private ProcessingRecipeContext createRecipeContext(File testDir) {
+ Map<PackageVersion, File> packageVersionFiles = null; // TODO not used yet
+ SystemInfo sysinfo = SystemInfoFactory.createSystemInfo();
+ String cwd = testDir.getAbsolutePath();
+ ProcessingRecipeContext context = new ProcessingRecipeContext(getRecipe(), packageVersionFiles, sysinfo, cwd);
+ return context;
+ }
+
+ private ProcessingRecipeContext parseRecipeNow(ProcessingRecipeContext context) throws Exception {
+ RecipeParser parser = new RecipeParser();
+ parser.setReplaceReplacementVariables(true);
+ parser.parseRecipe(context);
+ return context;
+ }
+
+ private File getTestDir(String subdir) {
+ return new File(getTmpDir(), subdir);
+ }
+
+ private File getTmpDir() {
+ File tmpdir = new File(System.getProperty("java.io.tmpdir"), "processing-recipe-test");
+ tmpdir.mkdirs();
+ return tmpdir;
+ }
+
+ private void cleanRecipe() {
+ this.recipe = new StringBuilder();
+ }
+
+ private void addRecipeCommand(String commandLine) {
+ this.recipe.append(commandLine).append("\n");
+ }
+
+ private String getRecipe() {
+ return this.recipe.toString();
+ }
+
+ private String readFile(File file) throws Exception {
+ return new String(StreamUtil.slurp(new FileInputStream(file)));
+ }
+
+ private File writeFile(String content, File destDir, String fileName) throws Exception {
+ FileOutputStream out = null;
+
+ try {
+ File destFile = new File(destDir, fileName);
+ destFile.getParentFile().mkdirs();
+ out = new FileOutputStream(destFile);
+ out.write(content.getBytes());
+ return destFile;
+ } finally {
+ if (out != null) {
+ out.close();
+ }
+ }
+ }
+
+ private File createZip(String content, File destDir, String zipName, String entryName) throws Exception {
+ FileOutputStream stream = null;
+ ZipOutputStream out = null;
+
+ try {
+ destDir.mkdirs();
+ File zipFile = new File(destDir, zipName);
+ stream = new FileOutputStream(zipFile);
+ out = new ZipOutputStream(stream);
+
+ ZipEntry zipAdd = new ZipEntry(entryName);
+ zipAdd.setTime(System.currentTimeMillis());
+ out.putNextEntry(zipAdd);
+ out.write(content.getBytes());
+ return zipFile;
+ } finally {
+ if (out != null) {
+ out.close();
+ }
+ if (stream != null) {
+ stream.close();
+ }
+ }
+ }
+}
commit 150fa0766fb19d1fc6d7ce9918df5fab6848219e
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Wed Mar 3 01:50:55 2010 -0500
remove this broken link
diff --git a/dev-cli b/dev-cli
deleted file mode 120000
index 9e0363b..0000000
--- a/dev-cli
+++ /dev/null
@@ -1 +0,0 @@
-modules/enterprise/remoting/cli/target/rhq-remoting-cli-1.4.0-SNAPSHOT
\ No newline at end of file
commit 981a3c4c5c77774b62e1b4e37f6b341aea1e1f35
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Mar 2 20:30:39 2010 -0500
add realize recipe command
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java
index 5f14f2f..d73f871 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java
@@ -32,7 +32,7 @@ public class DeployRecipeCommand implements RecipeCommand {
return "deploy";
}
- public void parse(RecipeContext context, String[] args) {
+ public void parse(RecipeParser parser, RecipeContext context, String[] args) {
String sopts = ":f:d:";
LongOpt[] lopts = { new LongOpt("file", LongOpt.REQUIRED_ARGUMENT, null, 'f'),
new LongOpt("directory", LongOpt.REQUIRED_ARGUMENT, null, 'd') };
@@ -40,7 +40,7 @@ public class DeployRecipeCommand implements RecipeCommand {
String filename = null;
String directory = null;
- Getopt getopt = new Getopt(context.toString(), args, sopts, lopts);
+ Getopt getopt = new Getopt(getName(), args, sopts, lopts);
int code;
while ((code = getopt.getopt()) != -1) {
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/FileRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/FileRecipeCommand.java
index 3b74805..2984bab 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/FileRecipeCommand.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/FileRecipeCommand.java
@@ -32,7 +32,7 @@ public class FileRecipeCommand implements RecipeCommand {
return "file";
}
- public void parse(RecipeContext context, String[] args) {
+ public void parse(RecipeParser parser, RecipeContext context, String[] args) {
String sopts = ":s:d:";
LongOpt[] lopts = { new LongOpt("source", LongOpt.REQUIRED_ARGUMENT, null, 's'),
new LongOpt("destination", LongOpt.REQUIRED_ARGUMENT, null, 'd') };
@@ -40,7 +40,7 @@ public class FileRecipeCommand implements RecipeCommand {
String source = null;
String destination = null;
- Getopt getopt = new Getopt(context.toString(), args, sopts, lopts);
+ Getopt getopt = new Getopt(getName(), args, sopts, lopts);
int code;
while ((code = getopt.getopt()) != -1) {
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RealizeRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RealizeRecipeCommand.java
new file mode 100644
index 0000000..b187ed8
--- /dev/null
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RealizeRecipeCommand.java
@@ -0,0 +1,74 @@
+/*
+ * 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, 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.bundle.filetemplate.recipe;
+
+import gnu.getopt.Getopt;
+import gnu.getopt.LongOpt;
+
+public class RealizeRecipeCommand implements RecipeCommand {
+
+ public String getName() {
+ return "realize";
+ }
+
+ public void parse(RecipeParser parser, RecipeContext context, String[] args) {
+ String sopts = ":f:";
+ LongOpt[] lopts = { new LongOpt("file", LongOpt.REQUIRED_ARGUMENT, null, 'f') };
+
+ String file = null;
+
+ Getopt getopt = new Getopt(getName(), args, sopts, lopts);
+ int code;
+
+ while ((code = getopt.getopt()) != -1) {
+ switch (code) {
+ case ':':
+ case '?': {
+ throw new IllegalArgumentException("Bad recipe command.");
+ }
+
+ case 1: {
+ throw new IllegalArgumentException("Bad recipe command!");
+ }
+
+ case 'f': {
+ file = getopt.getOptarg();
+ break;
+ }
+
+ default: {
+ throw new IllegalArgumentException("Unexpected error in recipe command");
+ }
+
+ }
+ }
+
+ if (file == null) {
+ throw new IllegalArgumentException("Did not specify the file to realize");
+ }
+
+ context.addRealizedFile(file);
+ return;
+ }
+}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeCommand.java
index 7cfa964..01c1da3 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeCommand.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeCommand.java
@@ -34,9 +34,10 @@ public interface RecipeCommand {
/**
* Parses this recipe command and optionally puts information in the context.
- *
+ *
+ * @param parser the parser that is invoking this command
* @param context information where the parser can store information regarding the command that was processed
* @param args arguments passed to the command.
*/
- void parse(RecipeContext context, String[] args);
+ void parse(RecipeParser recipeParser, RecipeContext context, String[] args);
}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
index dcea274..cb76a80 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
@@ -34,15 +34,17 @@ import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
/**
- * Contains information that is gleened from a recipe after it is parsed.
+ * Contains information that is gleened from a recipe during and after it is parsed.
*
* @author John Mazzitelli
*/
public class RecipeContext {
+ private RecipeParser parser;
private final String recipe;
private final Map<String, String> deployFiles;
private final Map<String, String> files;
+ private final Set<String> realizedFiles;
private final Set<String> replacementVariables;
private Configuration replacementVariableValues;
private final List<Script> scripts;
@@ -51,11 +53,24 @@ public class RecipeContext {
this.recipe = recipe;
this.deployFiles = new HashMap<String, String>();
this.files = new HashMap<String, String>();
+ this.realizedFiles = new HashSet<String>();
this.replacementVariables = new HashSet<String>();
this.scripts = new ArrayList<Script>();
}
/**
+ * If this context is currently in use by a parser, this will be the reference to that parser.
+ * @return parser currently using this context
+ */
+ public RecipeParser getParser() {
+ return parser;
+ }
+
+ public void setParser(RecipeParser parser) {
+ this.parser = parser;
+ }
+
+ /**
* The full recipe that this context represents.
*
* @return the actual recipe text
@@ -95,6 +110,20 @@ public class RecipeContext {
}
/**
+ * Returns the pathnames of all files that are to be realized (meaning, those that should
+ * have replacement variables replaced).
+ *
+ * @return set of all realized files
+ */
+ public Set<String> getRealizedFiles() {
+ return this.realizedFiles;
+ }
+
+ public void addRealizedFile(String file) {
+ this.realizedFiles.add(file);
+ }
+
+ /**
* The names of all replacement variables that are found in the recipe.
*
* @return the replacement variables
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
index 13644e6..98f26f6 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
@@ -77,17 +77,22 @@ public class RecipeParser {
public void parseRecipe(RecipeContext context) throws Exception {
- BufferedReader recipeReader = new BufferedReader(new StringReader(context.getRecipe()));
- String line = recipeReader.readLine();
- while (line != null) {
- parseRecipeCommandLine(context, line);
- line = recipeReader.readLine();
+ context.setParser(this);
+ try {
+ BufferedReader recipeReader = new BufferedReader(new StringReader(context.getRecipe()));
+ String line = recipeReader.readLine();
+ while (line != null) {
+ parseRecipeCommandLine(context, line);
+ line = recipeReader.readLine();
+ }
+ } finally {
+ context.setParser(null);
}
return;
}
- public void parseRecipeCommandLine(RecipeContext context, String line) throws Exception {
+ protected void parseRecipeCommandLine(RecipeContext context, String line) throws Exception {
// ignore blank lines or comment lines that start with #
if (line == null || line.trim().length() == 0 || line.startsWith("#")) {
return;
@@ -112,7 +117,7 @@ public class RecipeParser {
}
try {
- recipeCommand.parse(context, arguments);
+ recipeCommand.parse(this, context, arguments);
} catch (Exception e) {
throw new Exception("Error in recipe, line [" + line + "]", e);
}
@@ -125,6 +130,7 @@ public class RecipeParser {
RecipeCommand[] knownCommands = new RecipeCommand[] { new ScriptRecipeCommand(), //
new FileRecipeCommand(), //
+ new RealizeRecipeCommand(), //
new DeployRecipeCommand() //
};
@@ -156,14 +162,9 @@ public class RecipeParser {
return replacementVariables;
}
- protected String replaceReplacementVariables(RecipeContext context, String input) {
+ public String replaceReplacementVariables(RecipeContext context, String input) {
- // don't bother if we have no values to replace them with
Configuration replacementValues = context.getReplacementVariableValues();
- if (replacementValues == null) {
- return input;
- }
-
TemplateEngine templateEngine = null;
StringBuffer buffer = new StringBuffer();
Matcher matcher = this.replacementVariableDeclarationPattern.matcher(input);
@@ -172,7 +173,7 @@ public class RecipeParser {
Matcher nameMatcher = this.replacementVariableNamePattern.matcher(next);
if (nameMatcher.find()) {
String key = nameMatcher.group();
- String value = replacementValues.getSimpleValue(key, null);
+ String value = (replacementValues != null) ? replacementValues.getSimpleValue(key, null) : null;
if (value == null) {
// our replacement values don't know how to replace the key, see if our system info template engine can
if (templateEngine == null) {
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ScriptRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ScriptRecipeCommand.java
index 2173c06..99a0c7c 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ScriptRecipeCommand.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ScriptRecipeCommand.java
@@ -32,7 +32,7 @@ public class ScriptRecipeCommand implements RecipeCommand {
return "script";
}
- public void parse(RecipeContext context, String[] args) {
+ public void parse(RecipeParser parser, RecipeContext context, String[] args) {
if (args == null || args.length == 0) {
throw new IllegalArgumentException("Missing the script command to execute");
diff --git a/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
index 7d5abef..bfa58e6 100644
--- a/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
+++ b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
@@ -40,6 +40,16 @@ public class RecipeParserTest {
cleanRecipe();
}
+ public void testRealizeRecipe() throws Exception {
+ addRecipeCommand("realize --file=<%opt.dir%>/config.ini");
+ RecipeParser parser = new RecipeParser();
+ RecipeContext context = new RecipeContext(getRecipe());
+ parser.parseRecipe(context);
+ Set<String> files = context.getRealizedFiles();
+ assert files.size() == 1 : files;
+ assert files.contains("<%opt.dir%>/config.ini") : files;
+ }
+
public void testFileRecipe() throws Exception {
addRecipeCommand("file --source=run-me.sh --destination=/opt/run.sh");
addRecipeCommand("file -s META-INF/another.xml -d /etc/another.xml");
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
index b0ae578..ffe24f2 100644
--- a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
@@ -19,13 +19,17 @@
package org.rhq.plugins.filetemplate;
+import java.io.BufferedReader;
import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.rhq.bundle.filetemplate.recipe.RecipeContext;
+import org.rhq.bundle.filetemplate.recipe.RecipeParser;
import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.system.ProcessExecution;
import org.rhq.core.system.ProcessExecutionResults;
@@ -87,6 +91,60 @@ public class ProcessingRecipeContext extends RecipeContext {
}
@Override
+ public void addRealizedFile(String file) {
+ super.addRealizedFile(file);
+
+ File trueFile = new File(file);
+ RecipeParser parser = getParser();
+ File realizedTmpFile = null;
+ FileWriter realizedTmpFileWriter = null;
+ BufferedReader reader = null;
+
+ try {
+
+ realizedTmpFile = File.createTempFile("rhq-realize-", ".tmp", trueFile.getParentFile());
+ realizedTmpFileWriter = new FileWriter(realizedTmpFile);
+
+ reader = new BufferedReader(new FileReader(trueFile));
+ String line = reader.readLine();
+ while (line != null) {
+ line = parser.replaceReplacementVariables(this, line);
+ realizedTmpFileWriter.write(line);
+ realizedTmpFileWriter.write("\n");
+ line = reader.readLine();
+ }
+
+ realizedTmpFileWriter.close();
+ realizedTmpFileWriter = null;
+ reader.close();
+ reader = null;
+
+ trueFile.delete(); // remove the one with the replacement variables in it
+ if (!realizedTmpFile.renameTo(trueFile)) {
+ throw new RuntimeException("Failed to rename realized tmp file [" + realizedTmpFile + "]");
+ }
+ } catch (Exception e) {
+ throw new RuntimeException("Cannot realize file [" + file + "]", e);
+ } finally {
+ if (realizedTmpFileWriter != null) {
+ try {
+ realizedTmpFileWriter.close();
+ } catch (Exception e) {
+ }
+ }
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (Exception e) {
+ }
+ }
+ if (realizedTmpFile != null && realizedTmpFile.exists()) {
+ realizedTmpFile.delete();
+ }
+ }
+ }
+
+ @Override
public void addReplacementVariables(Set<String> replacementVariables) {
super.addReplacementVariables(replacementVariables);
}
commit 3c52854a359fa4fb4fae21fc4d0b9323d0ee800b
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Mar 2 19:03:52 2010 -0500
support the file recipe command
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/FileRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/FileRecipeCommand.java
new file mode 100644
index 0000000..3b74805
--- /dev/null
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/FileRecipeCommand.java
@@ -0,0 +1,85 @@
+/*
+ * 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, 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.bundle.filetemplate.recipe;
+
+import gnu.getopt.Getopt;
+import gnu.getopt.LongOpt;
+
+public class FileRecipeCommand implements RecipeCommand {
+
+ public String getName() {
+ return "file";
+ }
+
+ public void parse(RecipeContext context, String[] args) {
+ String sopts = ":s:d:";
+ LongOpt[] lopts = { new LongOpt("source", LongOpt.REQUIRED_ARGUMENT, null, 's'),
+ new LongOpt("destination", LongOpt.REQUIRED_ARGUMENT, null, 'd') };
+
+ String source = null;
+ String destination = null;
+
+ Getopt getopt = new Getopt(context.toString(), args, sopts, lopts);
+ int code;
+
+ while ((code = getopt.getopt()) != -1) {
+ switch (code) {
+ case ':':
+ case '?': {
+ throw new IllegalArgumentException("Bad recipe command.");
+ }
+
+ case 1: {
+ throw new IllegalArgumentException("Bad recipe command!");
+ }
+
+ case 's': {
+ source = getopt.getOptarg();
+ break;
+ }
+
+ case 'd': {
+ destination = getopt.getOptarg();
+ break;
+ }
+
+ default: {
+ throw new IllegalArgumentException("Unexpected error in recipe command");
+ }
+
+ }
+ }
+
+ if (source == null) {
+ throw new IllegalArgumentException("Did not specify the source file to copy");
+ }
+
+ if (destination == null) {
+ throw new IllegalArgumentException("Did not specify the destination where the file should be copied");
+ }
+
+ context.addFile(source, destination);
+ return;
+ }
+}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
index fb911f3..dcea274 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
@@ -42,6 +42,7 @@ public class RecipeContext {
private final String recipe;
private final Map<String, String> deployFiles;
+ private final Map<String, String> files;
private final Set<String> replacementVariables;
private Configuration replacementVariableValues;
private final List<Script> scripts;
@@ -49,6 +50,7 @@ public class RecipeContext {
public RecipeContext(String recipe) {
this.recipe = recipe;
this.deployFiles = new HashMap<String, String>();
+ this.files = new HashMap<String, String>();
this.replacementVariables = new HashSet<String>();
this.scripts = new ArrayList<Script>();
}
@@ -77,6 +79,22 @@ public class RecipeContext {
}
/**
+ * Returns all the files that are strictly to be copied to some location.
+ * The key is the bundle file's name, the value is the full path and filename where
+ * the file should be copied to. No processing of these files will occur other than
+ * they are copied.
+ *
+ * @return map of all files to be deployed and the location where they are to be deployed
+ */
+ public Map<String, String> getFiles() {
+ return this.files;
+ }
+
+ public void addFile(String source, String destination) {
+ this.files.put(source, destination);
+ }
+
+ /**
* The names of all replacement variables that are found in the recipe.
*
* @return the replacement variables
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
index d18fd4b..13644e6 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
@@ -111,7 +111,11 @@ public class RecipeParser {
context.addReplacementVariables(replacementVars);
}
- recipeCommand.parse(context, arguments);
+ try {
+ recipeCommand.parse(context, arguments);
+ } catch (Exception e) {
+ throw new Exception("Error in recipe, line [" + line + "]", e);
+ }
return;
}
@@ -120,6 +124,7 @@ public class RecipeParser {
HashMap<String, RecipeCommand> commands = new HashMap<String, RecipeCommand>();
RecipeCommand[] knownCommands = new RecipeCommand[] { new ScriptRecipeCommand(), //
+ new FileRecipeCommand(), //
new DeployRecipeCommand() //
};
diff --git a/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
index 40bc7fb..7d5abef 100644
--- a/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
+++ b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
@@ -40,6 +40,20 @@ public class RecipeParserTest {
cleanRecipe();
}
+ public void testFileRecipe() throws Exception {
+ addRecipeCommand("file --source=run-me.sh --destination=/opt/run.sh");
+ addRecipeCommand("file -s META-INF/another.xml -d /etc/another.xml");
+ RecipeParser parser = new RecipeParser();
+ RecipeContext context = new RecipeContext(getRecipe());
+ parser.parseRecipe(context);
+ Map<String, String> files = context.getFiles();
+ assert files.size() == 2 : files;
+ assert files.get("run-me.sh") != null : files;
+ assert files.get("run-me.sh").equals("/opt/run.sh") : files;
+ assert files.get("META-INF/another.xml") != null : files;
+ assert files.get("META-INF/another.xml").equals("/etc/another.xml") : files;
+ }
+
public void testScriptRecipe() throws Exception {
addRecipeCommand("script run-me.sh");
addRecipeCommand("script lots-o-params.sh -d /opt/jboss -- foo.txt \"hello world\"");
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
index 2e0d1dc..b0ae578 100644
--- a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
@@ -76,6 +76,17 @@ public class ProcessingRecipeContext extends RecipeContext {
}
@Override
+ public void addFile(String filename, String directory) {
+ super.addDeployFile(filename, directory);
+
+ File existingFile = new File(this.baseWorkingDirectory, filename);
+ File newFile = new File(directory, filename);
+ if (!existingFile.renameTo(newFile)) {
+ throw new RuntimeException("Failed to move file [" + existingFile + "] to [" + newFile + "]");
+ }
+ }
+
+ @Override
public void addReplacementVariables(Set<String> replacementVariables) {
super.addReplacementVariables(replacementVariables);
}
commit 31cdbfd2db0c5220319665482b41984419dd4cbc
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Mar 2 18:14:44 2010 -0500
add script recipe command
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java
deleted file mode 100644
index 26d1b82..0000000
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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, 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.bundle.filetemplate.recipe;
-
-import gnu.getopt.Getopt;
-import gnu.getopt.LongOpt;
-
-/**
- * @deprecated I think this command will not be used - probably should delete it
- * @author mazz
- */
-public class ConfigdefRecipeCommand implements RecipeCommand {
-
- public String getName() {
- return "configdef";
- }
-
- public void parse(RecipeContext context, String[] args) {
- String sopts = ":f:";
- LongOpt[] lopts = { new LongOpt("file", LongOpt.REQUIRED_ARGUMENT, null, 'f') };
-
- String filename = null;
-
- Getopt getopt = new Getopt(context.toString(), args, sopts, lopts);
- int code;
-
- while ((code = getopt.getopt()) != -1) {
- switch (code) {
- case ':':
- case '?': {
- throw new IllegalArgumentException("Bad recipe argument.");
- }
-
- case 1: {
- throw new IllegalArgumentException("Bad recipe argument!");
- }
-
- case 'f': {
- filename = getopt.getOptarg();
- break;
- }
-
- default: {
- throw new IllegalArgumentException("Unexpected error in recipe command");
- }
- }
- }
-
- if (filename == null) {
- throw new IllegalArgumentException("Missing the -f argument to indicate what the config def filename is");
- }
-
- // TODO: what to do? can I delete this command entirely?
-
- return;
- }
-}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
index 43f0df1..fb911f3 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
@@ -23,8 +23,10 @@
package org.rhq.bundle.filetemplate.recipe;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -42,11 +44,13 @@ public class RecipeContext {
private final Map<String, String> deployFiles;
private final Set<String> replacementVariables;
private Configuration replacementVariableValues;
+ private final List<Script> scripts;
public RecipeContext(String recipe) {
this.recipe = recipe;
this.deployFiles = new HashMap<String, String>();
this.replacementVariables = new HashSet<String>();
+ this.scripts = new ArrayList<Script>();
}
/**
@@ -114,4 +118,68 @@ public class RecipeContext {
}
values.put(new PropertySimple(name, value));
}
+
+ /**
+ * Returns a set of all the names of scripts found in the recipe.
+ *
+ * @return script names
+ */
+ public Set<String> getScriptFiles() {
+ Set<String> scriptFiles = new HashSet<String>();
+ for (Script script : this.scripts) {
+ scriptFiles.add(script.getExecutable());
+ }
+ return scriptFiles;
+ }
+
+ /**
+ * Adds a script that the recipe wants invoked.
+ *
+ * @param exe the script executable
+ * @param exeArgs the arguments to pass to the script
+ */
+ public void addScript(String exe, List<String> exeArgs) {
+ this.scripts.add(new Script(exe, exeArgs));
+ }
+
+ class Script {
+ private final List<String> args;
+ private final String exe;
+
+ public Script(String exe, List<String> args) {
+ this.exe = exe;
+ this.args = args;
+ }
+
+ public String getExecutable() {
+ return exe;
+ }
+
+ public List<String> getArguments() {
+ return args;
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder str = new StringBuilder("RecipeContext:\n");
+ str.append("Recipe Text:\n").append(getRecipe()).append("\n");
+ str.append("Deploy Files: ").append(getDeployFiles()).append("\n");
+ str.append("Replacement Vars: ").append(getReplacementVariables()).append("\n");
+
+ str.append("Replacement Values: ");
+ Configuration values = getReplacementVariableValues();
+ if (values == null) {
+ str.append("<none>");
+ } else {
+ str.append(values.getProperties());
+ }
+ str.append("\n");
+
+ str.append("Script Files: ").append(getScriptFiles()).append("\n");
+ for (Script script : this.scripts) {
+ str.append("* ").append(script.getExecutable()).append(" ").append(script.getArguments()).append("\n");
+ }
+ return str.toString();
+ }
}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
index f8db1c8..d18fd4b 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
@@ -119,7 +119,7 @@ public class RecipeParser {
protected HashMap<String, RecipeCommand> createRecipeCommands() {
HashMap<String, RecipeCommand> commands = new HashMap<String, RecipeCommand>();
- RecipeCommand[] knownCommands = new RecipeCommand[] { new ConfigdefRecipeCommand(), //
+ RecipeCommand[] knownCommands = new RecipeCommand[] { new ScriptRecipeCommand(), //
new DeployRecipeCommand() //
};
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ScriptRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ScriptRecipeCommand.java
new file mode 100644
index 0000000..2173c06
--- /dev/null
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ScriptRecipeCommand.java
@@ -0,0 +1,51 @@
+/*
+ * 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, 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.bundle.filetemplate.recipe;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ScriptRecipeCommand implements RecipeCommand {
+
+ public String getName() {
+ return "script";
+ }
+
+ public void parse(RecipeContext context, String[] args) {
+
+ if (args == null || args.length == 0) {
+ throw new IllegalArgumentException("Missing the script command to execute");
+ }
+
+ String exe = args[0];
+ List<String> exeArgs = new ArrayList<String>(args.length - 1);
+ for (int i = 1; i < args.length; i++) {
+ exeArgs.add(args[i]);
+ }
+
+ context.addScript(exe, exeArgs);
+
+ return;
+ }
+}
diff --git a/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
index b2efdaf..40bc7fb 100644
--- a/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
+++ b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
@@ -24,6 +24,7 @@
package org.rhq.bundle.filetemplate.recipe;
import java.util.Map;
+import java.util.Set;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@@ -39,6 +40,19 @@ public class RecipeParserTest {
cleanRecipe();
}
+ public void testScriptRecipe() throws Exception {
+ addRecipeCommand("script run-me.sh");
+ addRecipeCommand("script lots-o-params.sh -d /opt/jboss -- foo.txt \"hello world\"");
+ addRecipeCommand("script run-me.sh with params");
+ RecipeParser parser = new RecipeParser();
+ RecipeContext context = new RecipeContext(getRecipe());
+ parser.parseRecipe(context);
+ Set<String> scripts = context.getScriptFiles();
+ assert scripts.size() == 2 : scripts;
+ assert scripts.contains("run-me.sh") : scripts;
+ assert scripts.contains("lots-o-params.sh") : scripts;
+ }
+
public void testSimpleRecipeReplacementVariables() throws Exception {
addRecipeCommand("# <% ignored.inside.comment %>");
addRecipeCommand("deploy -f jboss.tar -d \"<% opt.dir %>/jboss\"");
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 34902c0..99b8504 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
@@ -76,6 +76,8 @@ public class BundleServerPluginComponent implements ServerPluginComponent, Bundl
Set<String> bundleFileNames = new HashSet<String>();
Map<String, String> deployFiles = recipeContext.getDeployFiles();
bundleFileNames.addAll(deployFiles.keySet());
+ Set<String> scriptFiles = recipeContext.getScriptFiles();
+ bundleFileNames.addAll(scriptFiles);
ConfigurationDefinition configDef = null;
if (recipeContext.getReplacementVariables() != null) {
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
index 7f76757..cee69db 100644
--- a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
@@ -75,42 +75,25 @@ public class FileTemplateBundlePluginServerComponent implements ResourceComponen
List<PackageVersion> packageVersions = bundleManager.getAllBundleVersionPackageVersions(bundleVersion);
for (PackageVersion packageVersion : packageVersions) {
File packageFile = new File(tmpDir, packageVersion.getFileName());
- packageFile.getParentFile().mkdirs();
- FileOutputStream fos = new FileOutputStream(packageFile);
- try {
- long size = bundleManager.getFileContent(packageVersion, fos);
- if (packageVersion.getFileSize() != null && size != packageVersion.getFileSize().longValue()) {
- log.warn("Downloaded bundle file [" + packageVersion + "] but its size was [" + size
- + "] when it was expected to be [" + packageVersion.getFileSize() + "].");
- }
- } finally {
- fos.close();
- }
- // verify the content
- if (packageVersion.getMD5() != null) {
- String realMD5 = MessageDigestGenerator.getDigestString(packageFile);
- if (!packageVersion.getMD5().equals(realMD5)) {
- throw new Exception("Package version [" + packageVersion + "] failed MD5 check. expected=["
- + packageVersion.getMD5() + "], actual=[" + realMD5 + "]");
- }
- } else if (packageVersion.getSHA256() != null) {
- FileInputStream is = new FileInputStream(packageFile);
+ try {
+ verifyHash(packageVersion, packageFile);
+ } catch (Exception e) {
+ // file either doesn't exist or it hash doesn't match, download a new copy
+ packageFile.getParentFile().mkdirs();
+ FileOutputStream fos = new FileOutputStream(packageFile);
try {
- MessageDigestGenerator gen = new MessageDigestGenerator("SHA256");
- gen.add(is);
- String realSHA256 = gen.getDigestString();
- if (!packageVersion.getSHA256().equals(realSHA256)) {
- throw new Exception("Package version [" + packageVersion
- + "] failed SHA256 check. expected=[" + packageVersion.getSHA256() + "], actual=["
- + realSHA256 + "]");
+ long size = bundleManager.getFileContent(packageVersion, fos);
+ if (packageVersion.getFileSize() != null && size != packageVersion.getFileSize().longValue()) {
+ log.warn("Downloaded bundle file [" + packageVersion + "] but its size was [" + size
+ + "] when it was expected to be [" + packageVersion.getFileSize() + "].");
}
} finally {
- is.close();
+ fos.close();
}
- } else {
- log.debug("Package version [" + packageVersion + "] has no MD5/SHA256 hash - not verifying it");
+ // now try to verify it again, if this throws an exception, that is very bad and we need to abort
+ verifyHash(packageVersion, packageFile);
}
packageVersionFiles.put(packageVersion, packageFile);
@@ -131,4 +114,46 @@ public class FileTemplateBundlePluginServerComponent implements ResourceComponen
}
return result;
}
+
+ /**
+ * Checks to see if the package file's hash matches that of the given package version.
+ * If the file doesn't exist or the hash doesn't match, an exception is thrown.
+ * This method returns normally if the hash matches the file.
+ * If there is no known hash in the package version, this method returns normally.
+ *
+ * @param packageVersion contains the hash that is expected
+ * @param packageFile the local file whose hash is to be checked
+ * @throws Exception if the file does not match the hash or the file doesn't exist
+ */
+ private void verifyHash(PackageVersion packageVersion, File packageFile) throws Exception {
+ if (!packageFile.exists()) {
+ throw new Exception("Package version [" + packageVersion + "] does not exist, cannot check hash");
+ }
+
+ if (packageVersion.getMD5() != null) {
+ String realMD5 = MessageDigestGenerator.getDigestString(packageFile);
+ if (!packageVersion.getMD5().equals(realMD5)) {
+ throw new Exception("Package version [" + packageVersion + "] failed MD5 check. expected=["
+ + packageVersion.getMD5() + "], actual=[" + realMD5 + "]");
+ }
+ } else if (packageVersion.getSHA256() != null) {
+ FileInputStream is = new FileInputStream(packageFile);
+ try {
+ MessageDigestGenerator gen = new MessageDigestGenerator("SHA256");
+ gen.add(is);
+ String realSHA256 = gen.getDigestString();
+ if (!packageVersion.getSHA256().equals(realSHA256)) {
+ throw new Exception("Package version [" + packageVersion + "] failed SHA256 check. expected=["
+ + packageVersion.getSHA256() + "], actual=[" + realSHA256 + "]");
+ }
+ } finally {
+ is.close();
+ }
+
+ } else {
+ log.debug("Package version [" + packageVersion + "] has no MD5/SHA256 hash - not verifying it");
+ }
+
+ return;
+ }
}
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
index 1dbad78..2e0d1dc 100644
--- a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
@@ -80,6 +80,23 @@ public class ProcessingRecipeContext extends RecipeContext {
super.addReplacementVariables(replacementVariables);
}
+ @Override
+ public void addScript(String exe, List<String> exeArgs) {
+ super.addScript(exe, exeArgs);
+
+ File scriptFile = new File(this.baseWorkingDirectory, exe);
+
+ ProcessExecution pe = new ProcessExecution(scriptFile.getAbsolutePath());
+ pe.setArguments(exeArgs);
+ pe.setWaitForCompletion(30 * 60 * 1000L);
+ pe.setWorkingDirectory(scriptFile.getParent());
+
+ ProcessExecutionResults results = this.systemInfo.executeProcess(pe);
+ if (results.getError() != null) {
+ throw new RuntimeException("Could not execute script [" + pe + "]: " + results, results.getError());
+ }
+ }
+
private ProcessExecution getUnzipExecution(String filename, String directory) {
String exe;
List<String> args = null;
commit 870834d52077aebf478fc8c4eb420d095756d2e9
Merge: 3c61acc... f6fd9c9...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Tue Mar 2 16:11:25 2010 -0500
Merge branch 'bundle-jay' into bundle
Conflicts:
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
diff --cc modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
index a7cf52d,9e56e1e..1ca01c8
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
@@@ -65,10 -67,14 +67,10 @@@ public class BundleManagerBeanTest exte
public void beforeMethod() {
super.startTest();
- if (null == ps) {
- ps = new TestBundleServerPluginService();
- pc = ps.createMasterPluginContainer();
- } else {
- pc.initialize(ps.masterConfig);
- }
-
+ this.ps = new TestBundleServerPluginService();
+ prepareCustomServerPluginService(this.ps);
- bundleManagerBean = LookupUtil.getBundleManager();
+ bundleManager = LookupUtil.getBundleManager();
+ this.ps.startMasterPluginContainer();
}
@AfterMethod(alwaysRun = true)
commit f6fd9c9a4684c2eec48ee16fe4923d50203d8a80
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Tue Mar 2 16:06:42 2010 -0500
added a few more tests
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
index e8ac546..9e56e1e 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
@@ -33,8 +33,10 @@ import org.testng.annotations.Test;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.Bundle;
+import org.rhq.core.domain.bundle.BundleFile;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.Repo;
import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleVersionCriteria;
@@ -56,7 +58,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
private static final boolean ENABLED = true;
- private BundleManagerLocal bundleManagerBean;
+ private BundleManagerLocal bundleManager;
private TestBundleServerPluginService ps;
private MasterServerPluginContainer pc;
@@ -72,7 +74,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
pc.initialize(ps.masterConfig);
}
- bundleManagerBean = LookupUtil.getBundleManager();
+ bundleManager = LookupUtil.getBundleManager();
}
@AfterMethod(alwaysRun = true)
@@ -112,6 +114,12 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
em.remove(em.getReference(BundleType.class, ((BundleType) removeMe).getId()));
}
+ q = em.createQuery("SELECT pt FROM PackageType pt WHERE pt.name LIKE '" + TEST_PREFIX + "%'");
+ doomed = q.getResultList();
+ for (Object removeMe : doomed) {
+ em.remove(em.getReference(PackageType.class, ((PackageType) removeMe).getId()));
+ }
+
q = em.createQuery("SELECT rt FROM ResourceType rt WHERE rt.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
for (Object removeMe : doomed) {
@@ -144,7 +152,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
public void testGetBundleTypes() throws Exception {
BundleType bt1 = createBundleType("one");
BundleType bt2 = createBundleType("two");
- List<BundleType> bts = bundleManagerBean.getAllBundleTypes(LookupUtil.getSubjectManager().getOverlord());
+ List<BundleType> bts = bundleManager.getAllBundleTypes(LookupUtil.getSubjectManager().getOverlord());
assert bts.size() >= 2 : "should have at least 2 bundle types";
List<String> btNames = new ArrayList<String>();
@@ -157,6 +165,36 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
}
@Test(enabled = ENABLED)
+ public void testCreateBundle() throws Exception {
+ Bundle b1 = createBundle("one");
+ assertNotNull(b1);
+ }
+
+ @Test(enabled = ENABLED)
+ public void testCreateBundleVersion() throws Exception {
+ Bundle b1 = createBundle("one");
+ assertNotNull(b1);
+ BundleVersion bv1 = createBundleVersion(b1.getName() + "-1", null, b1);
+ assertNotNull(bv1);
+ assertEquals("1.0", bv1.getVersion());
+ BundleVersion bv2 = createBundleVersion(b1.getName() + "-2", null, b1);
+ assertNotNull(bv2);
+ assertEquals("1.1", bv2.getVersion());
+ }
+
+ @Test(enabled = ENABLED)
+ public void testAddBundleFiles() throws Exception {
+ Bundle b1 = createBundle("one");
+ assertNotNull(b1);
+ BundleVersion bv1 = createBundleVersion(b1.getName(), "1.0", b1);
+ assertNotNull(bv1);
+ BundleFile bf1 = bundleManager.addBundleFileViaByteArray(getOverlord(), bv1.getId(), TEST_PREFIX
+ + "-bundlefile-1", "1.0", null, "Test Bundle File # 1".getBytes(), false);
+ BundleFile bf2 = bundleManager.addBundleFileViaByteArray(getOverlord(), bv1.getId(), TEST_PREFIX
+ + "-bundlefile-2", "1.0", null, "Test Bundle File # 2".getBytes(), false);
+ }
+
+ @Test(enabled = ENABLED)
public void testfindBundlesByCriteria() throws Exception {
Bundle b1 = createBundle("one");
Bundle b2 = createBundle("two");
@@ -168,7 +206,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
String name = null;
// return all with no optional data
- bundles = bundleManagerBean.findBundlesByCriteria(getOverlord(), c);
+ bundles = bundleManager.findBundlesByCriteria(getOverlord(), c);
assertNotNull(bundles);
assertEquals(2, bundles.size());
b = bundles.get(0);
@@ -197,7 +235,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
c.addFilterBundleTypeName(b.getName());
c.fetchBundleVersions(true);
c.fetchRepo(true);
- bundles = bundleManagerBean.findBundlesByCriteria(getOverlord(), c);
+ bundles = bundleManager.findBundlesByCriteria(getOverlord(), c);
assertNotNull(bundles);
assertEquals(1, bundles.size());
b = bundles.get(0);
@@ -224,7 +262,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
BundleVersion bv = null;
// return all with no optional data
- bvs = bundleManagerBean.findBundleVersionsByCriteria(getOverlord(), c);
+ bvs = bundleManager.findBundleVersionsByCriteria(getOverlord(), c);
bv = bvs.get(1);
assertNotNull(bvs);
assertEquals(3, bvs.size());
@@ -238,7 +276,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
c.fetchBundle(true);
c.fetchDistribution(true);
c.fetchBundleDeployDefinitions(true);
- bvs = bundleManagerBean.findBundleVersionsByCriteria(getOverlord(), c);
+ bvs = bundleManager.findBundleVersionsByCriteria(getOverlord(), c);
assertNotNull(bvs);
assertEquals(1, bvs.size());
bv = bvs.get(0);
@@ -251,7 +289,9 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
private BundleType createBundleType(String name) throws Exception {
final String fullName = TEST_PREFIX + "-type-" + name;
- BundleType bt = bundleManagerBean.createBundleType(getOverlord(), fullName, createResourceType(name).getId());
+ ResourceType rt = createResourceType(name);
+ PackageType pt = createPackageType(name, rt);
+ BundleType bt = bundleManager.createBundleType(getOverlord(), fullName, rt.getId());
assert bt.getId() > 0;
assert bt.getName().endsWith(fullName);
@@ -265,7 +305,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
private Bundle createBundle(String name, BundleType bt) throws Exception {
final String fullName = TEST_PREFIX + "-bundle-" + name;
- Bundle b = bundleManagerBean.createBundle(getOverlord(), fullName, bt.getId());
+ Bundle b = bundleManager.createBundle(getOverlord(), fullName, bt.getId());
assert b.getId() > 0;
assert b.getName().endsWith(fullName);
@@ -273,10 +313,9 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
}
private BundleVersion createBundleVersion(String name, String version, Bundle bundle) throws Exception {
- final String fullName = TEST_PREFIX + "-version-" + version + "-" + name;
+ final String fullName = TEST_PREFIX + "-bundleversion-" + version + "-" + name;
final String recipe = "deploy -f " + TEST_PREFIX + ".zip -d <% test.path %>";
- BundleVersion bv = bundleManagerBean.createBundleVersion(getOverlord(), bundle.getId(), fullName, version,
- recipe);
+ BundleVersion bv = bundleManager.createBundleVersion(getOverlord(), bundle.getId(), fullName, version, recipe);
assert bv.getId() > 0;
assert bv.getName().endsWith(fullName);
@@ -296,6 +335,19 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
return rt;
}
+ private PackageType createPackageType(String name, ResourceType rt) throws Exception {
+ final String fullName = TEST_PREFIX + "-packagetype-" + name;
+ PackageType pt = new PackageType(fullName, rt);
+
+ TransactionManager txMgr = getTransactionManager();
+ txMgr.begin();
+ EntityManager em = getEntityManager();
+ em.persist(pt);
+ em.close();
+ txMgr.commit();
+ return pt;
+ }
+
private Subject getOverlord() {
return LookupUtil.getSubjectManager().getOverlord();
}
commit 3c61acc239ef4eb7e4bdd086cb5f533ca845e1c8
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Mar 2 15:57:09 2010 -0500
fix bundle test so the mock PC is started properly
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
index e8ac546..a7cf52d 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
@@ -65,18 +65,14 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
public void beforeMethod() {
super.startTest();
- if (null == ps) {
- ps = new TestBundleServerPluginService();
- pc = ps.createMasterPluginContainer();
- } else {
- pc.initialize(ps.masterConfig);
- }
-
+ this.ps = new TestBundleServerPluginService();
+ prepareCustomServerPluginService(this.ps);
bundleManagerBean = LookupUtil.getBundleManager();
+ this.ps.startMasterPluginContainer();
}
@AfterMethod(alwaysRun = true)
- public void afterMethod() {
+ public void afterMethod() throws Exception {
EntityManager em = null;
@@ -133,9 +129,8 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
}
}
- if (null != pc) {
- pc.shutdown();
- }
+ unprepareServerPluginService();
+ this.ps = null;
super.endTest();
}
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 dcbc951..64bd5af 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
@@ -39,18 +39,15 @@ import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment;
import org.rhq.enterprise.server.plugin.pc.ServerPluginManager;
import org.rhq.enterprise.server.plugin.pc.ServerPluginService;
import org.rhq.enterprise.server.plugin.pc.ServerPluginType;
-import org.rhq.enterprise.server.plugin.pc.generic.GenericServerPluginContainer;
-import org.rhq.enterprise.server.plugin.pc.generic.TestGenericServerPluginServiceMBean;
+import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginManager;
import org.rhq.enterprise.server.xmlschema.ServerPluginDescriptorMetadataParser;
import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType;
/**
- * Used as a mock service for the generic server plugin container.
+ * Used as a mock service for the bundle server plugin container.
*/
-public class TestBundleServerPluginService extends ServerPluginService implements TestGenericServerPluginServiceMBean {
- public enum State {
- INITIALIZED, STARTED, STOPPED, UNINITIALIZED
- }
+public class TestBundleServerPluginService extends ServerPluginService implements TestBundleServerPluginServiceMBean {
// public so tests can directly set these
public TestMasterServerPluginContainer master;
@@ -105,9 +102,7 @@ public class TestBundleServerPluginService extends ServerPluginService implement
}
}
- public class TestBundleServerPluginContainer extends GenericServerPluginContainer {
- public State state = State.UNINITIALIZED;
-
+ public class TestBundleServerPluginContainer extends BundleServerPluginContainer {
public TestBundleServerPluginContainer(MasterServerPluginContainer master) {
super(master);
}
@@ -117,56 +112,12 @@ public class TestBundleServerPluginService extends ServerPluginService implement
TestBundlePluginManager pm = new TestBundlePluginManager(this);
return pm;
}
-
- @Override
- public synchronized void initialize() throws Exception {
- if (state == State.UNINITIALIZED) {
- state = State.INITIALIZED;
- } else {
- System.out.println("!!! PC LIFECYCLE WAS BAD - THIS IS A BUG !!!");
- throw new IllegalStateException("not uninitialized: " + state);
- }
- super.initialize();
- }
-
- @Override
- public synchronized void start() {
- if (state == State.INITIALIZED) {
- state = State.STARTED;
- } else {
- System.out.println("!!! PC LIFECYCLE WAS BAD - THIS IS A BUG !!!");
- throw new IllegalStateException("not initialized: " + state);
- }
- super.start();
- }
-
- @Override
- public synchronized void stop() {
- if (state == State.STARTED) {
- state = State.STOPPED;
- } else {
- System.out.println("!!! PC LIFECYCLE WAS BAD - THIS IS A BUG !!!");
- throw new IllegalStateException("not started: " + state);
- }
- super.stop();
- }
-
- @Override
- public synchronized void shutdown() {
- if (state == State.STOPPED) {
- state = State.UNINITIALIZED;
- } else {
- System.out.println("!!! PC LIFECYCLE WAS BAD - THIS IS A BUG !!!");
- throw new IllegalStateException("not stopped: " + state);
- }
- super.shutdown();
- }
}
/**
* The test plugin manager.
*/
- class TestBundlePluginManager extends ServerPluginManager {
+ class TestBundlePluginManager extends BundleServerPluginManager {
public final Map<String, ServerPluginComponent> components;
public TestBundlePluginManager(TestBundleServerPluginContainer pc) {
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/TestBundleServerPluginServiceMBean.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/TestBundleServerPluginServiceMBean.java
new file mode 100644
index 0000000..80b2d7f
--- /dev/null
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/TestBundleServerPluginServiceMBean.java
@@ -0,0 +1,24 @@
+/*
+ * 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.bundle;
+
+import org.rhq.enterprise.server.plugin.pc.ServerPluginServiceManagement;
+
+public interface TestBundleServerPluginServiceMBean extends ServerPluginServiceManagement {
+}
\ No newline at end of file
commit 3a19b87d9f21a5ffa2df1ed6ea2d06421310adb1
Merge: 85ce0d5... cdccd36...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Tue Mar 2 15:14:51 2010 -0500
Merge branch 'bundle' into bundle-jay
commit cdccd367c9fd398dffba8e7fe6df5fab88fa772a
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Mar 2 15:12:37 2010 -0500
opps.. forgot to use the new constructor
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
index 3fe2852..7f76757 100644
--- a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
@@ -112,12 +112,15 @@ public class FileTemplateBundlePluginServerComponent implements ResourceComponen
} else {
log.debug("Package version [" + packageVersion + "] has no MD5/SHA256 hash - not verifying it");
}
+
+ packageVersionFiles.put(packageVersion, packageFile);
}
// process the recipe
String recipe = bundleVersion.getRecipe();
RecipeParser parser = new RecipeParser();
- ProcessingRecipeContext recipeContext = new ProcessingRecipeContext(recipe);
+ ProcessingRecipeContext recipeContext = new ProcessingRecipeContext(recipe, packageVersionFiles,
+ this.resourceContext.getSystemInformation(), tmpDir.getAbsolutePath());
recipeContext.setReplacementVariableValues(bundleDeployDef.getConfiguration());
parser.setReplaceReplacementVariables(true);
parser.parseRecipe(recipeContext);
commit 967a5f2371cb77591801bfd8d3dd97e3eb44a355
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Mar 2 15:10:53 2010 -0500
more bundle processing stuff - this attempts to process the deploy command
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
index c895107..43f0df1 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
@@ -28,6 +28,9 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.PropertySimple;
+
/**
* Contains information that is gleened from a recipe after it is parsed.
*
@@ -38,6 +41,7 @@ public class RecipeContext {
private final String recipe;
private final Map<String, String> deployFiles;
private final Set<String> replacementVariables;
+ private Configuration replacementVariableValues;
public RecipeContext(String recipe) {
this.recipe = recipe;
@@ -81,4 +85,33 @@ public class RecipeContext {
this.replacementVariables.addAll(replacementVariables);
}
+ /**
+ * If known, the returned value will contain values that are to be used to replace
+ * replacement variables found in the recipe.
+ *
+ * @return the replacement variable values
+ */
+ public Configuration getReplacementVariableValues() {
+ return this.replacementVariableValues;
+ }
+
+ public void setReplacementVariableValues(Configuration configuration) {
+ this.replacementVariableValues = configuration;
+ }
+
+ /**
+ * Adds the given name/value pair to the set of replacement variable values associated
+ * with this context.
+ *
+ * @param name
+ * @param value
+ */
+ public void addReplacementVariableValue(String name, String value) {
+ Configuration values = getReplacementVariableValues();
+ if (values == null) {
+ values = new Configuration();
+ setReplacementVariableValues(values);
+ }
+ values.put(new PropertySimple(name, value));
+ }
}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
index df797f4..f8db1c8 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
@@ -37,6 +37,10 @@ import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.system.SystemInfoFactory;
+import org.rhq.core.template.TemplateEngine;
+
/**
* Parses the file template recipe.
*
@@ -46,27 +50,41 @@ import java.util.regex.Pattern;
public class RecipeParser {
private Map<String, RecipeCommand> recipeCommands;
- // note that we use the same as the core util's template engine
- // the native system replacement variable prefix is used by the agent-side fact variable names
- private final Pattern replacementVariableDeclarationPattern = Pattern.compile("<%\\s*(\\w+\\.?)+\\s*%>");
- private final Pattern replacementVariableNamePattern = Pattern.compile("(\\w+\\.?)+");
- private final String systemReplacementVariablePrefix = "rhq.system.";
+ private Pattern replacementVariableDeclarationPattern;
+ private Pattern replacementVariableNamePattern;
+ private String systemReplacementVariablePrefix;
+ private boolean replaceVariables = false;
public RecipeParser() {
- setupRecipeCommands();
+ this.recipeCommands = createRecipeCommands();
+ setupReplacementPatterns();
+ }
+
+ /**
+ * If the parser should replace replacement variables with their corresponding values (as found in
+ * the parser context), <code>true</code> is returned. If <code>false</code> then the replacement
+ * variables remain as is when they are passed to their command processor objects.
+ *
+ * @return flag
+ */
+ public boolean isReplaceReplacementVariables() {
+ return this.replaceVariables;
}
- public RecipeContext parseRecipe(String recipe) throws Exception {
- RecipeContext context = new RecipeContext(recipe);
+ public void setReplaceReplacementVariables(boolean flag) {
+ this.replaceVariables = flag;
+ }
+
+ public void parseRecipe(RecipeContext context) throws Exception {
- BufferedReader recipeReader = new BufferedReader(new StringReader(recipe));
+ BufferedReader recipeReader = new BufferedReader(new StringReader(context.getRecipe()));
String line = recipeReader.readLine();
while (line != null) {
parseRecipeCommandLine(context, line);
line = recipeReader.readLine();
}
- return context;
+ return;
}
public void parseRecipeCommandLine(RecipeContext context, String line) throws Exception {
@@ -75,11 +93,15 @@ public class RecipeParser {
return;
}
+ if (isReplaceReplacementVariables()) {
+ line = replaceReplacementVariables(context, line);
+ }
+
String[] commandLineArray = splitCommandLine(line);
String commandName = commandLineArray[0];
String[] arguments = extractArguments(commandLineArray);
- RecipeCommand recipeCommand = recipeCommands.get(commandName);
+ RecipeCommand recipeCommand = this.recipeCommands.get(commandName);
if (recipeCommand == null) {
throw new Exception("Unknown command in recipe: " + commandName);
}
@@ -94,28 +116,30 @@ public class RecipeParser {
return;
}
- private void setupRecipeCommands() {
- recipeCommands = new HashMap<String, RecipeCommand>();
+ protected HashMap<String, RecipeCommand> createRecipeCommands() {
+ HashMap<String, RecipeCommand> commands = new HashMap<String, RecipeCommand>();
RecipeCommand[] knownCommands = new RecipeCommand[] { new ConfigdefRecipeCommand(), //
new DeployRecipeCommand() //
};
for (RecipeCommand recipeCommand : knownCommands) {
- recipeCommands.put(recipeCommand.getName(), recipeCommand);
+ commands.put(recipeCommand.getName(), recipeCommand);
}
+
+ return commands;
}
- private Set<String> getReplacementVariables(String cmdLine) {
+ protected Set<String> getReplacementVariables(String cmdLine) {
Set<String> replacementVariables = null;
Matcher matcher = this.replacementVariableDeclarationPattern.matcher(cmdLine);
while (matcher.find()) {
String replacementDeclaration = matcher.group();
- Matcher matcherInner = this.replacementVariableNamePattern.matcher(replacementDeclaration);
- if (!matcherInner.find()) {
+ Matcher nameMatcher = this.replacementVariableNamePattern.matcher(replacementDeclaration);
+ if (!nameMatcher.find()) {
throw new IllegalArgumentException("Bad replacement declaration [" + replacementDeclaration + "]");
}
- String replacementVariable = matcherInner.group();
+ String replacementVariable = nameMatcher.group();
if (!replacementVariable.startsWith(this.systemReplacementVariablePrefix)) {
if (replacementVariables == null) {
replacementVariables = new HashSet<String>(1);
@@ -127,7 +151,43 @@ public class RecipeParser {
return replacementVariables;
}
- private String[] splitCommandLine(String cmdLine) {
+ protected String replaceReplacementVariables(RecipeContext context, String input) {
+
+ // don't bother if we have no values to replace them with
+ Configuration replacementValues = context.getReplacementVariableValues();
+ if (replacementValues == null) {
+ return input;
+ }
+
+ TemplateEngine templateEngine = null;
+ StringBuffer buffer = new StringBuffer();
+ Matcher matcher = this.replacementVariableDeclarationPattern.matcher(input);
+ while (matcher.find()) {
+ String next = matcher.group();
+ Matcher nameMatcher = this.replacementVariableNamePattern.matcher(next);
+ if (nameMatcher.find()) {
+ String key = nameMatcher.group();
+ String value = replacementValues.getSimpleValue(key, null);
+ if (value == null) {
+ // our replacement values don't know how to replace the key, see if our system info template engine can
+ if (templateEngine == null) {
+ templateEngine = SystemInfoFactory.fetchTemplateEngine();
+ }
+ value = templateEngine.replaceTokens(next);
+ }
+ if (value != null) {
+ next = value;
+ }
+ }
+
+ // If we didn't find a replacement for the key then leave the original value unchanged
+ matcher.appendReplacement(buffer, next);
+ }
+ matcher.appendTail(buffer);
+ return buffer.toString();
+ }
+
+ protected String[] splitCommandLine(String cmdLine) {
ByteArrayInputStream in = new ByteArrayInputStream(cmdLine.getBytes());
StreamTokenizer strtok = new StreamTokenizer(new InputStreamReader(in));
List<String> args = new ArrayList<String>();
@@ -163,11 +223,20 @@ public class RecipeParser {
return args.toArray(new String[args.size()]);
}
- private String[] extractArguments(String[] commandLine) {
+ protected String[] extractArguments(String[] commandLine) {
// strip the first element (the command name) from the array, leaving only the arguments
int newLength = commandLine.length - 1;
String[] argsOnly = new String[newLength];
System.arraycopy(commandLine, 1, argsOnly, 0, newLength);
return argsOnly;
}
+
+ private void setupReplacementPatterns() {
+ // note that we use the same as the core util's template engine
+ // the native system replacement variable prefix is used by the agent-side fact variable names
+ this.replacementVariableDeclarationPattern = Pattern.compile("<%\\s*(\\w+\\.?)+\\s*%>");
+ this.replacementVariableNamePattern = Pattern.compile("(\\w+\\.?)+");
+ this.systemReplacementVariablePrefix = SystemInfoFactory.TOKEN_PREFIX;
+ }
+
}
diff --git a/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
index 7d58b88..b2efdaf 100644
--- a/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
+++ b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
@@ -28,6 +28,8 @@ import java.util.Map;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
+import org.rhq.core.system.SystemInfoFactory;
+
@Test
public class RecipeParserTest {
private StringBuilder recipe;
@@ -43,7 +45,8 @@ public class RecipeParserTest {
addRecipeCommand("deploy -f tomcat.tar -d <%opt.dir%>/tomcat");
addRecipeCommand("deploy -f jboss.zip -d <%rhq.system.hostname%>/opt/tomcat"); // this is ignored, its an agent fact variable
RecipeParser parser = new RecipeParser();
- RecipeContext context = parser.parseRecipe(getRecipe());
+ RecipeContext context = new RecipeContext(getRecipe());
+ parser.parseRecipe(context);
Map<String, String> files = context.getDeployFiles();
assert files.containsKey("jboss.tar") : files;
assert files.get("jboss.tar").equals("<% opt.dir %>/jboss") : files;
@@ -55,11 +58,30 @@ public class RecipeParserTest {
assert context.getReplacementVariables().size() == 1 : context.getReplacementVariables();
}
+ public void testSimpleRecipeReplaceReplacementVariables() throws Exception {
+ addRecipeCommand("deploy -f jboss.tar -d <% opt.dir %>/jboss");
+ addRecipeCommand("deploy -f jboss2.tar -d <%unknown%>/jboss");
+ addRecipeCommand("deploy -f jboss3.tar -d <% rhq.system.hostname %>/jboss");
+ RecipeParser parser = new RecipeParser();
+ parser.setReplaceReplacementVariables(true);
+ RecipeContext context = new RecipeContext(getRecipe());
+ context.addReplacementVariableValue("opt.dir", "/foo/bar");
+ parser.parseRecipe(context);
+ Map<String, String> files = context.getDeployFiles();
+ assert files.containsKey("jboss.tar") : files;
+ assert files.get("jboss.tar").equals("/foo/bar/jboss") : files;
+ assert files.containsKey("jboss2.tar") : files;
+ assert files.get("jboss2.tar").equals("<%unknown%>/jboss") : files;
+ assert files.containsKey("jboss3.tar") : files;
+ assert files.get("jboss3.tar").equals(SystemInfoFactory.createSystemInfo().getHostname() + "/jboss") : files;
+ }
+
public void testSimpleRecipe() throws Exception {
addRecipeCommand("deploy -f jboss.tar -d /opt/jboss");
addRecipeCommand("deploy -f tomcat.tar -d /opt/tomcat");
RecipeParser parser = new RecipeParser();
- RecipeContext context = parser.parseRecipe(getRecipe());
+ RecipeContext context = new RecipeContext(getRecipe());
+ parser.parseRecipe(context);
Map<String, String> files = context.getDeployFiles();
assert files.containsKey("jboss.tar") : files;
assert files.get("jboss.tar").equals("/opt/jboss") : files;
@@ -72,7 +94,8 @@ public class RecipeParserTest {
addRecipeCommand("deploy -f jboss.tar --directory='/opt/jboss'");
addRecipeCommand("deploy -f tomcat.tar \"--directory=/opt/tomcat\"");
RecipeParser parser = new RecipeParser();
- RecipeContext context = parser.parseRecipe(getRecipe());
+ RecipeContext context = new RecipeContext(getRecipe());
+ parser.parseRecipe(context);
Map<String, String> files = context.getDeployFiles();
assert files.containsKey("jboss1.zip") : files;
assert files.get("jboss1.zip").equals("/opt/jboss1") : files;
@@ -87,7 +110,8 @@ public class RecipeParserTest {
RecipeParser parser = new RecipeParser();
try {
- parser.parseRecipe(getRecipe());
+ RecipeContext context = new RecipeContext(getRecipe());
+ parser.parseRecipe(context);
assert false : "This should have failed - need to provide a -d to the deploy command";
} catch (Exception ok) {
// to be expected
@@ -97,7 +121,8 @@ public class RecipeParserTest {
addRecipeCommand("deploy -d /opt/jboss");
try {
- parser.parseRecipe(getRecipe());
+ RecipeContext context = new RecipeContext(getRecipe());
+ parser.parseRecipe(context);
assert false : "This should have failed - need to provide a -f to the deploy command";
} catch (Exception ok) {
// to be expected
@@ -118,7 +143,8 @@ public class RecipeParserTest {
addRecipeCommand("### comment here");
addRecipeCommand("");
RecipeParser parser = new RecipeParser();
- RecipeContext context = parser.parseRecipe(getRecipe());
+ RecipeContext context = new RecipeContext(getRecipe());
+ parser.parseRecipe(context);
Map<String, String> files = context.getDeployFiles();
assert files.containsKey("jboss.tar") : files;
assert files.get("jboss.tar").equals("/opt/jboss") : files;
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 147f2a5..34902c0 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
@@ -70,16 +70,17 @@ public class BundleServerPluginComponent implements ServerPluginComponent, Bundl
public RecipeParseResults parseRecipe(String recipe) throws Exception {
RecipeParser parser = new RecipeParser();
- RecipeContext parserContext = parser.parseRecipe(recipe);
+ RecipeContext recipeContext = new RecipeContext(recipe);
+ parser.parseRecipe(recipeContext);
Set<String> bundleFileNames = new HashSet<String>();
- Map<String, String> deployFiles = deployFiles = parserContext.getDeployFiles();
+ Map<String, String> deployFiles = recipeContext.getDeployFiles();
bundleFileNames.addAll(deployFiles.keySet());
ConfigurationDefinition configDef = null;
- if (parserContext.getReplacementVariables() != null) {
+ if (recipeContext.getReplacementVariables() != null) {
configDef = new ConfigurationDefinition("replacementVariables", null);
- for (String replacementVar : parserContext.getReplacementVariables()) {
+ for (String replacementVar : recipeContext.getReplacementVariables()) {
PropertyDefinitionSimple prop = new PropertyDefinitionSimple(replacementVar, null, false,
PropertySimpleType.STRING);
configDef.put(prop);
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
index a1320ad..3fe2852 100644
--- a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
@@ -21,11 +21,14 @@ package org.rhq.plugins.filetemplate;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.rhq.bundle.filetemplate.recipe.RecipeParser;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.content.PackageVersion;
@@ -66,6 +69,7 @@ public class FileTemplateBundlePluginServerComponent implements ResourceComponen
BundleVersion bundleVersion = bundleDeployDef.getBundleVersion();
// download all the bundle files to our tmp directory
+ Map<PackageVersion, File> packageVersionFiles = new HashMap<PackageVersion, File>();
File tmpDir = new File(this.resourceContext.getTemporaryDirectory(), "" + bundleVersion.getId());
BundleManagerProvider bundleManager = request.getBundleManagerProvider();
List<PackageVersion> packageVersions = bundleManager.getAllBundleVersionPackageVersions(bundleVersion);
@@ -110,7 +114,13 @@ public class FileTemplateBundlePluginServerComponent implements ResourceComponen
}
}
- // TODO all bundle files are downloaded - now process the bundle
+ // process the recipe
+ String recipe = bundleVersion.getRecipe();
+ RecipeParser parser = new RecipeParser();
+ ProcessingRecipeContext recipeContext = new ProcessingRecipeContext(recipe);
+ recipeContext.setReplacementVariableValues(bundleDeployDef.getConfiguration());
+ parser.setReplaceReplacementVariables(true);
+ parser.parseRecipe(recipeContext);
} catch (Throwable t) {
log.error("Failed to deploy bundle [" + request + "]", t);
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
new file mode 100644
index 0000000..1dbad78
--- /dev/null
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/ProcessingRecipeContext.java
@@ -0,0 +1,133 @@
+/*
+ * 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.plugins.filetemplate;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.rhq.bundle.filetemplate.recipe.RecipeContext;
+import org.rhq.core.domain.content.PackageVersion;
+import org.rhq.core.system.ProcessExecution;
+import org.rhq.core.system.ProcessExecutionResults;
+import org.rhq.core.system.SystemInfo;
+
+/**
+ * A recipe context that processes the recipe as it adds stuff to the context
+ *
+ * @author John Mazzitelli
+ */
+public class ProcessingRecipeContext extends RecipeContext {
+
+ private final Map<PackageVersion, File> packageVersionFiles;
+ private final SystemInfo systemInfo;
+ private String baseWorkingDirectory;
+
+ public ProcessingRecipeContext(String recipe, Map<PackageVersion, File> packageVersionFiles, SystemInfo systemInfo,
+ String baseWorkingDirectory) {
+
+ super(recipe);
+ this.packageVersionFiles = packageVersionFiles;
+ this.systemInfo = systemInfo;
+ this.baseWorkingDirectory = baseWorkingDirectory; // the directory that existing bundle filenames will be relative to
+ }
+
+ @Override
+ public void addDeployFile(String filename, String directory) {
+ super.addDeployFile(filename, directory);
+
+ File existingFile = new File(this.baseWorkingDirectory, filename);
+
+ ProcessExecution pe = getUnzipExecution(filename, directory);
+ if (pe != null) {
+ ProcessExecutionResults results = this.systemInfo.executeProcess(pe);
+ if (results.getError() != null) {
+ throw new RuntimeException("Could not unbundle file [" + pe + "]: " + results, results.getError());
+ } else if (results.getExitCode() == null || results.getExitCode().intValue() > 0) {
+ throw new RuntimeException("Failed to unbundle file [" + pe + "]: " + results);
+ }
+ existingFile.delete();
+ } else {
+ // not a zipped format - just move the file to the directory as-is
+ File newFile = new File(directory, filename);
+ if (!existingFile.renameTo(newFile)) {
+ throw new RuntimeException("Failed to move [" + existingFile + "] to [" + newFile + "]");
+ }
+ }
+ }
+
+ @Override
+ public void addReplacementVariables(Set<String> replacementVariables) {
+ super.addReplacementVariables(replacementVariables);
+ }
+
+ private ProcessExecution getUnzipExecution(String filename, String directory) {
+ String exe;
+ List<String> args = null;
+
+ if (filename.endsWith(".tar")) {
+ exe = "tar";
+ args = new ArrayList<String>();
+ args.add("xf");
+ args.add(filename);
+ args.add("-C");
+ args.add(directory);
+ } else if (filename.endsWith(".tar.bz2") || filename.endsWith(".tbz2") || filename.endsWith(".tbz")) {
+ exe = "tar";
+ args = new ArrayList<String>();
+ args.add("xfj");
+ args.add(filename);
+ args.add("-C");
+ args.add(directory);
+ } else if (filename.endsWith(".tar.gz") || filename.endsWith(".tgz")) {
+ exe = "tar";
+ args = new ArrayList<String>();
+ args.add("xfz");
+ args.add(filename);
+ args.add("-C");
+ args.add(directory);
+ } else if (filename.endsWith(".zip")) {
+ exe = "unzip";
+ args = new ArrayList<String>();
+ args.add(filename);
+ args.add("-d");
+ args.add(directory);
+ } else if (filename.endsWith(".rpm")) {
+ exe = "rpm";
+ args = new ArrayList<String>();
+ args.add("-i");
+ args.add(filename);
+ if (directory != null && directory.length() > 0) {
+ args.add("--prefix");
+ args.add(directory);
+ }
+ } else {
+ return null; // isn't a unzippable package, we'll just copy it as is
+ }
+
+ ProcessExecution pe = new ProcessExecution(exe);
+ pe.setArguments(args);
+ pe.setWaitForCompletion(30 * 60 * 1000L);
+ pe.setWorkingDirectory(this.baseWorkingDirectory);
+ return pe;
+ }
+}
commit 85ce0d5d01e8b74849346640590edcff1afe8b6f
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Tue Mar 2 15:10:22 2010 -0500
SLSB work for Bundles
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 6d67e56..29b25cf 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
@@ -18,6 +18,8 @@
*/
package org.rhq.enterprise.server.bundle;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
import java.util.List;
import java.util.Random;
import java.util.UUID;
@@ -32,11 +34,17 @@ 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.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleDeployment;
+import org.rhq.core.domain.bundle.BundleFile;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.content.Architecture;
+import org.rhq.core.domain.content.Package;
+import org.rhq.core.domain.content.PackageType;
+import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.content.Repo;
import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleDeployDefinitionCriteria;
@@ -48,6 +56,9 @@ import org.rhq.core.domain.util.PersistenceUtility;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.authz.AuthorizationManagerLocal;
import org.rhq.enterprise.server.authz.PermissionException;
+import org.rhq.enterprise.server.authz.RequiredPermission;
+import org.rhq.enterprise.server.content.ContentManagerLocal;
+import org.rhq.enterprise.server.content.RepoManagerLocal;
import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginFacet;
import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal;
import org.rhq.enterprise.server.util.CriteriaQueryGenerator;
@@ -70,49 +81,208 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
private AuthorizationManagerLocal authorizationManager;
@EJB
+ private ContentManagerLocal contentManager;
+
+ @EJB
+ private RepoManagerLocal repoManager;
+
+ @EJB
private ResourceTypeManagerLocal resourceTypeManager;
- public Bundle createBundle(Subject subject, Bundle bundle) {
- if (null == bundle || null == bundle.getName())
- throw new IllegalArgumentException("Missing one or more of: bundle, name");
+ @RequiredPermission(Permission.MANAGE_INVENTORY)
+ public Bundle createBundle(Subject subject, String name, int bundleTypeId) {
+ if (null == name || "".equals(name.trim())) {
+ throw new IllegalArgumentException("Invalid bundleName: " + name);
+ }
- // add the implicit bundle repo, if necessary
- if (null == bundle.getRepo()) {
- Repo repo = new Repo(bundle.getName());
- repo.setCandidate(false);
- repo.setSyncSchedule(null);
- bundle.setRepo(repo);
+ BundleType bundleType = entityManager.find(BundleType.class, bundleTypeId);
+ if (null == bundleType) {
+ throw new IllegalArgumentException("Invalid bundleTypeId: " + bundleTypeId);
}
- log.info("Creating bundle: " + bundle);
+ Bundle bundle = new Bundle(name, bundleType);
+
+ // add the implicit bundle repo
+ Repo repo = new Repo(name);
+ repo.setCandidate(false);
+ repo.setSyncSchedule(null);
+ bundle.setRepo(repo);
+ log.info("Creating bundle: " + bundle);
entityManager.persist(bundle);
+
return bundle;
}
- public BundleType createBundleType(Subject subject, BundleType bundleType) throws Exception {
- if (null == bundleType || null == bundleType.getName())
- throw new IllegalArgumentException("Missing one or more of: bundleType, name");
+ @RequiredPermission(Permission.MANAGE_INVENTORY)
+ public BundleType createBundleType(Subject subject, String name, int resourceTypeId) throws Exception {
+ if (null == name || "".equals(name.trim())) {
+ throw new IllegalArgumentException("Invalid bundleTypeName: " + name);
+ }
+ ResourceType resourceType = entityManager.find(ResourceType.class, resourceTypeId);
+ if (null == resourceType) {
+ throw new IllegalArgumentException("Invalid resourceeTypeId: " + resourceTypeId);
+ }
+
+ BundleType bundleType = new BundleType(name, resourceType);
entityManager.persist(bundleType);
return bundleType;
}
- public BundleVersion createBundleVersion(Subject subject, int bundleId, BundleVersion bundleVersion)
+ @RequiredPermission(Permission.MANAGE_INVENTORY)
+ public BundleVersion createBundleVersion(Subject subject, int bundleId, String name, String version, String recipe)
throws Exception {
+ if (null == name || "".equals(name.trim())) {
+ throw new IllegalArgumentException("Invalid bundleVersionName: " + name);
+ }
+
Bundle bundle = entityManager.find(Bundle.class, bundleId);
+ if (null == bundle) {
+ throw new IllegalArgumentException("Invalid bundleId: " + bundleId);
+ }
+
+ // parse the recipe (validation occurs here) and get the config def and list of files
+ BundleType bundleType = bundle.getBundleType();
+ BundleServerPluginFacet bp = BundleManagerHelper.getPluginContainer().getBundleServerPluginManager()
+ .getBundleServerPluginFacet(bundleType.getName());
+ RecipeParseResults results = bp.parseRecipe(recipe);
- if (null == bundleVersion || null == bundle || null == bundleVersion.getRecipe())
- throw new IllegalArgumentException("Missing one or more of: bundle, bundleVersion, recipe");
+ // ensure we have a version
+ version = getVersion(version, bundle);
- // parse the recipe and get the config def and list of files
- BundleServerPluginFacet bp;
- // bp.parseRecipe;
+ BundleVersion bundleVersion = new BundleVersion(name, version, bundle, recipe);
+ bundleVersion.setConfigurationDefinition(results.getConfigDef());
entityManager.persist(bundleVersion);
return bundleVersion;
}
+ private String getVersion(String version, Bundle bundle) {
+ if (!(null == version || "".equals(version.trim()))) {
+ return version;
+ }
+
+ BundleVersion currentBundleVersion = null;
+ for (BundleVersion bundleVersion : bundle.getBundleVersions()) {
+ if ((null == currentBundleVersion) || (bundleVersion.getId() > currentBundleVersion.getId())) {
+ currentBundleVersion = bundleVersion;
+ }
+ }
+
+ // note - this is the same algo used by ResourceClientProxy in updatebackingContent (for a resource)
+ String oldVersion = (null == currentBundleVersion) ? null : currentBundleVersion.getVersion();
+ String newVersion = "1.0";
+ if (oldVersion != null && oldVersion.length() != 0) {
+ String[] parts = oldVersion.split("[^a-zA-Z0-9]");
+ String lastPart = parts[parts.length - 1];
+ try {
+ int lastNumber = Integer.parseInt(lastPart);
+ newVersion = oldVersion.substring(0, oldVersion.length() - lastPart.length()) + (lastNumber + 1);
+ } catch (NumberFormatException nfe) {
+ newVersion = oldVersion + ".1";
+ }
+ }
+
+ return newVersion;
+ }
+
+ @RequiredPermission(Permission.MANAGE_INVENTORY)
+ public BundleFile addBundleFile(Subject subject, int bundleVersionId, String name, String version,
+ Architecture architecture, InputStream fileStream, boolean pinToPackage) throws Exception {
+
+ if (null == name || "".equals(name.trim())) {
+ throw new IllegalArgumentException("Invalid bundleFileName: " + name);
+ }
+ if (null == version || "".equals(version.trim())) {
+ throw new IllegalArgumentException("Invalid bundleFileVersion: " + version);
+ }
+ if (null == fileStream) {
+ throw new IllegalArgumentException("Invalid fileStream: " + null);
+ }
+ BundleVersion bundleVersion = entityManager.find(BundleVersion.class, bundleVersionId);
+ if (null == bundleVersion) {
+ throw new IllegalArgumentException("Invalid bundleVersionId: " + bundleVersionId);
+ }
+
+ // Create the PackageVersion the BundleFile is tied to. This implicitly creates the
+ // Package for the PackageVersion.
+ Bundle bundle = bundleVersion.getBundle();
+ PackageType packageType = getBundleTypePackageType(bundle.getBundleType());
+ architecture = (null == architecture) ? contentManager.getNoArchitecture() : architecture;
+ PackageVersion packageVersion = contentManager.createPackageVersion(name, packageType.getId(), version,
+ architecture.getId(), fileStream);
+
+ // Create the mapping between the Bundle's Repo and the BundleFile's PackageVersion
+ Repo repo = bundle.getRepo();
+ repoManager.addPackageVersionsToRepo(subject, repo.getId(), new int[] { packageVersion.getId() });
+
+ // Classify the Package with the Bundle name in order to distinguish it from the same package name for
+ // a different bundle.
+ Package generalPackage = packageVersion.getGeneralPackage();
+ generalPackage.setClassification(bundle.getName());
+
+ // With all the plumbing in place, create and persist the BundleFile. Tie it to the Package if the caller
+ // wants this BundleFile pinned to themost recent version.
+ BundleFile bundleFile = new BundleFile();
+ bundleFile.setBundleVersion(bundleVersion);
+ bundleFile.setPackageVersion(packageVersion);
+ if (pinToPackage) {
+ bundleFile.setPackage(generalPackage);
+ }
+
+ entityManager.persist(bundleFile);
+
+ return bundleFile;
+ }
+
+ @RequiredPermission(Permission.MANAGE_INVENTORY)
+ public BundleFile addBundleFileViaByteArray(Subject subject, int bundleVersionId, String name, String version,
+ Architecture architecture, byte[] fileBytes, boolean pinToPackage) throws Exception {
+
+ return addBundleFile(subject, bundleVersionId, name, version, architecture,
+ new ByteArrayInputStream(fileBytes), pinToPackage);
+ }
+
+ @RequiredPermission(Permission.MANAGE_INVENTORY)
+ public BundleFile addBundleFileViaPackageVersion(Subject subject, int bundleVersionId, String name,
+ int packageVersionId, boolean pinToPackage) throws Exception {
+
+ if (null == name || "".equals(name.trim())) {
+ throw new IllegalArgumentException("Invalid bundleFileName: " + name);
+ }
+ BundleVersion bundleVersion = entityManager.find(BundleVersion.class, bundleVersionId);
+ if (null == bundleVersion) {
+ throw new IllegalArgumentException("Invalid bundleVersionId: " + bundleVersionId);
+ }
+ PackageVersion packageVersion = entityManager.find(PackageVersion.class, packageVersionId);
+ if (null == packageVersion) {
+ throw new IllegalArgumentException("Invalid packageVersionId: " + packageVersionId);
+ }
+
+ // With all the plumbing in place, create and persist the BundleFile. Tie it to the Package if the caller
+ // wants this BundleFile pinned to themost recent version.
+ BundleFile bundleFile = new BundleFile();
+ bundleFile.setBundleVersion(bundleVersion);
+ bundleFile.setPackageVersion(packageVersion);
+ if (pinToPackage) {
+ bundleFile.setPackage(packageVersion.getGeneralPackage());
+ }
+
+ entityManager.persist(bundleFile);
+
+ return bundleFile;
+ }
+
+ private PackageType getBundleTypePackageType(BundleType bundleType) {
+
+ Query packageTypeQuery = entityManager.createNamedQuery(PackageType.QUERY_FIND_BY_RESOURCE_TYPE_ID_AND_NAME);
+ packageTypeQuery.setParameter("typeId", bundleType.getResourceType().getId());
+ packageTypeQuery.setParameter("name", bundleType.getName());
+
+ return (PackageType) packageTypeQuery.getSingleResult();
+ }
+
@SuppressWarnings("unchecked")
public List<BundleType> getAllBundleTypes(Subject subject) {
// the list of types will be small, no need to support paging
@@ -198,8 +368,7 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
try {
ResourceType linuxPlatformResourceType = this.resourceTypeManager.getResourceTypeByNameAndPlugin("Linux",
"Platforms");
- BundleType bundleType = new BundleType(UUID.randomUUID().toString(), linuxPlatformResourceType);
- return createBundleType(subject, bundleType);
+ return createBundleType(subject, UUID.randomUUID().toString(), linuxPlatformResourceType.getId());
} catch (Exception e) {
e.printStackTrace();
return null;
@@ -215,9 +384,8 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
int randomIndex = random.nextInt(bundleTypes.size());
bundleType = bundleTypes.get(randomIndex);
}
- Bundle bundle = new Bundle(UUID.randomUUID().toString(), bundleType);
- bundle = createBundle(subject, bundle);
+ Bundle bundle = createBundle(subject, UUID.randomUUID().toString(), bundleType.getId());
// Add 1 to 5 bundle versions.
int bundleVersionCount = random.nextInt(5) + 1;
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerHelper.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerHelper.java
new file mode 100644
index 0000000..7ba49db
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerHelper.java
@@ -0,0 +1,34 @@
+package org.rhq.enterprise.server.bundle;
+
+import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.ServerPluginServiceManagement;
+import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginContainer;
+import org.rhq.enterprise.server.util.LookupUtil;
+
+public class BundleManagerHelper {
+
+ public static BundleServerPluginContainer getPluginContainer() {
+ BundleServerPluginContainer pc;
+
+ try {
+ ServerPluginServiceManagement mbean = LookupUtil.getServerPluginService();
+ if (!mbean.isMasterPluginContainerStarted()) {
+ throw new IllegalStateException("The master plugin container is not started!");
+ }
+
+ MasterServerPluginContainer master = mbean.getMasterPluginContainer();
+ pc = master.getPluginContainerByClass(BundleServerPluginContainer.class);
+ } catch (IllegalStateException ise) {
+ throw ise;
+ } catch (Exception e) {
+ throw new IllegalStateException("Cannot obtain the Bundle plugin container!", e);
+ }
+
+ if (pc == null) {
+ throw new IllegalStateException("Bundle plugin container is null!");
+ }
+
+ return pc;
+ }
+
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
index 42f573d..ec3b73b 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
@@ -18,6 +18,7 @@
*/
package org.rhq.enterprise.server.bundle;
+import java.io.InputStream;
import java.util.List;
import javax.ejb.Local;
@@ -26,8 +27,10 @@ import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleDeployment;
+import org.rhq.core.domain.bundle.BundleFile;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.content.Architecture;
import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleDeployDefinitionCriteria;
import org.rhq.core.domain.criteria.BundleDeploymentCriteria;
@@ -43,26 +46,73 @@ import org.rhq.core.domain.util.PageList;
public interface BundleManagerLocal {
/**
+ * 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 bundle required fields: name
+ * @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
+ * @param architecture architecture appropriate for the backing package. Defaults to noarch (i.e. any architecture).
+ * @param fileStream the file bits
+ * @param pinToPackage if true a new version of the backing package can trigger automatic creation of a new
+ * BundleVersion. if false new versions of the backing package have no effect on the BundleFile or its BundleVersion.
+ * @return the new BundleFile
+ * @throws Exception
+ */
+ BundleFile addBundleFile(Subject subject, int bundleVersionId, String bundleFileName, String version,
+ Architecture architecture, InputStream fileStream, boolean pinToPackage) throws Exception;
+
+ /**
+ * A convenience method taking a byte array as opposed to a stream for the file bits.
+ *
+ * @see {@link addBundleFile(Subject, int, String, String, Architecture, InputStream, boolean)}
+ */
+ BundleFile addBundleFileViaByteArray(Subject subject, int bundleVersionId, String name, String version,
+ Architecture architecture, byte[] fileBytes, boolean pinToPackage) throws Exception;
+
+ /**
+ * @param subject must be InventoryManager
+ * @param bundleVersionId id of the BundleVersion incorporating this BundleFile
+ * @param name name of the BundleFile (and the resulting Package)
+ * @param packageVersionId id of the PackageVersion this BundleFile is tied to for this BundleVersion. It is assumed
+ * the PackageVersion is already associated with the Bundle's Repo and the package is classified for the
+ * Bundle.
+ * @param pinToPackage if true a new version of the backing package can trigger automatic creation of a new
+ * BundleVersion. if false new versions of the backing package have no effect on the BundleFile or its BundleVersion.
+ * @return the new BundleFile
+ * @throws Exception
+ */
+ BundleFile addBundleFileViaPackageVersion(Subject subject, int bundleVersionId, String name, int packageVersionId,
+ boolean pinToPackage) throws Exception;
+
+ /**
+ * @param subject must be InventoryManager
+ * @param name not null or empty
+ * @param bundleTypeId valid bundleType
* @return the persisted Bundle (id is assigned)
*/
- Bundle createBundle(Subject subject, Bundle bundle) throws Exception;
+ Bundle createBundle(Subject subject, String name, int bundleTypeId) throws Exception;
/**
+ * Not generally called. For use by Server Side Plugins when registering a Bundle Plugin.
+ *
* @param subject must be InventoryManager
- * @param bundleType required fields: name
+ * @param name not null or empty
+ * @param resourceTypeId id of the ResourceType that handles this BundleType
* @return the persisted BundleType (id is assigned)
*/
- BundleType createBundleType(Subject subject, BundleType bundleType) throws Exception;
+ BundleType createBundleType(Subject subject, String name, int resourceTypeId) throws Exception;
/**
* @param subject must be InventoryManager
- * @param int bundleId the bundle for which this will be the next version
- * @param bundleVersion required fields: recipe (the full recipe as a String)
+ * @param bundleId the bundle for which this will be the next version
+ * @param name not null or empty
+ * @param bundleVersion optional. If not supplied set to 1.0 for first version, or incremented (as best as possible) for subsequent version
* @return the persisted BundleVersion (id is assigned)
*/
- BundleVersion createBundleVersion(Subject subject, int bundleId, BundleVersion bundleVersion) throws Exception;
+ BundleVersion createBundleVersion(Subject subject, int bundleId, String name, String bundleVersion, String recipe)
+ throws Exception;
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
index e381dd4..e8ac546 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
@@ -41,6 +41,7 @@ import org.rhq.core.domain.criteria.BundleVersionCriteria;
import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.util.PageList;
+import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainer;
import org.rhq.enterprise.server.test.AbstractEJB3Test;
import org.rhq.enterprise.server.util.LookupUtil;
@@ -57,8 +58,20 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
private BundleManagerLocal bundleManagerBean;
+ private TestBundleServerPluginService ps;
+ private MasterServerPluginContainer pc;
+
@BeforeMethod
public void beforeMethod() {
+ super.startTest();
+
+ if (null == ps) {
+ ps = new TestBundleServerPluginService();
+ pc = ps.createMasterPluginContainer();
+ } else {
+ pc.initialize(ps.masterConfig);
+ }
+
bundleManagerBean = LookupUtil.getBundleManager();
}
@@ -119,6 +132,12 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
em.close();
}
}
+
+ if (null != pc) {
+ pc.shutdown();
+ }
+
+ super.endTest();
}
@Test(enabled = ENABLED)
@@ -232,8 +251,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
private BundleType createBundleType(String name) throws Exception {
final String fullName = TEST_PREFIX + "-type-" + name;
- BundleType bt = new BundleType(fullName, createResourceType(name));
- bt = bundleManagerBean.createBundleType(getOverlord(), bt);
+ BundleType bt = bundleManagerBean.createBundleType(getOverlord(), fullName, createResourceType(name).getId());
assert bt.getId() > 0;
assert bt.getName().endsWith(fullName);
@@ -247,8 +265,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
private Bundle createBundle(String name, BundleType bt) throws Exception {
final String fullName = TEST_PREFIX + "-bundle-" + name;
- Bundle b = new Bundle(fullName, bt);
- b = bundleManagerBean.createBundle(getOverlord(), b);
+ Bundle b = bundleManagerBean.createBundle(getOverlord(), fullName, bt.getId());
assert b.getId() > 0;
assert b.getName().endsWith(fullName);
@@ -257,9 +274,9 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
private BundleVersion createBundleVersion(String name, String version, Bundle bundle) throws Exception {
final String fullName = TEST_PREFIX + "-version-" + version + "-" + name;
- final String recipe = TEST_PREFIX + "-recipe-" + name;
- BundleVersion bv = new BundleVersion(fullName, version, bundle, recipe);
- bv = bundleManagerBean.createBundleVersion(getOverlord(), bv);
+ final String recipe = "deploy -f " + TEST_PREFIX + ".zip -d <% test.path %>";
+ BundleVersion bv = bundleManagerBean.createBundleVersion(getOverlord(), bundle.getId(), fullName, version,
+ recipe);
assert bv.getId() > 0;
assert bv.getName().endsWith(fullName);
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
new file mode 100644
index 0000000..dcbc951
--- /dev/null
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/TestBundleServerPluginService.java
@@ -0,0 +1,218 @@
+/*
+ * 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.bundle;
+
+import java.io.File;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
+import org.rhq.core.domain.plugin.PluginKey;
+import org.rhq.core.domain.plugin.PluginStatusType;
+import org.rhq.core.domain.plugin.ServerPlugin;
+import org.rhq.core.util.MessageDigestGenerator;
+import org.rhq.enterprise.server.plugin.pc.AbstractTypeServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.MasterServerPluginContainerConfiguration;
+import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
+import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment;
+import org.rhq.enterprise.server.plugin.pc.ServerPluginManager;
+import org.rhq.enterprise.server.plugin.pc.ServerPluginService;
+import org.rhq.enterprise.server.plugin.pc.ServerPluginType;
+import org.rhq.enterprise.server.plugin.pc.generic.GenericServerPluginContainer;
+import org.rhq.enterprise.server.plugin.pc.generic.TestGenericServerPluginServiceMBean;
+import org.rhq.enterprise.server.xmlschema.ServerPluginDescriptorMetadataParser;
+import org.rhq.enterprise.server.xmlschema.generated.serverplugin.ServerPluginDescriptorType;
+
+/**
+ * Used as a mock service for the generic server plugin container.
+ */
+public class TestBundleServerPluginService extends ServerPluginService implements TestGenericServerPluginServiceMBean {
+ public enum State {
+ INITIALIZED, STARTED, STOPPED, UNINITIALIZED
+ }
+
+ // public so tests can directly set these
+ public TestMasterServerPluginContainer master;
+ public TestBundleServerPluginContainer bundlePC;
+ public MasterServerPluginContainerConfiguration masterConfig;
+
+ public TestBundleServerPluginService() {
+ // build the config at constructor time so tests have it even before the PC is initialized
+ File dir = new File(System.getProperty("java.io.tmpdir"), "test-server-plugins");
+ this.masterConfig = new MasterServerPluginContainerConfiguration(dir, dir, dir, null);
+ }
+
+ @Override
+ public MasterServerPluginContainer createMasterPluginContainer() {
+ this.master = new TestMasterServerPluginContainer();
+ this.master.initialize(this.masterConfig);
+ return this.master;
+ }
+
+ /**
+ * The test master PC
+ */
+ class TestMasterServerPluginContainer extends MasterServerPluginContainer {
+ @Override
+ protected List<AbstractTypeServerPluginContainer> createPluginContainers() {
+ ArrayList<AbstractTypeServerPluginContainer> pcs = new ArrayList<AbstractTypeServerPluginContainer>(1);
+ bundlePC = new TestBundleServerPluginContainer(this);
+ pcs.add(bundlePC);
+ return pcs;
+ }
+
+ @Override
+ protected ClassLoader createRootServerPluginClassLoader() {
+ return this.getClass().getClassLoader();
+ }
+
+ @Override
+ protected Map<URL, ? extends ServerPluginDescriptorType> preloadAllPlugins() throws Exception {
+ // if our test never setup any plugins, ignore it and just return an empty map
+ File pluginDir = getConfiguration().getPluginDirectory();
+ if (pluginDir == null || pluginDir.listFiles() == null || pluginDir.listFiles().length == 0) {
+ return new HashMap<URL, ServerPluginDescriptorType>();
+ } else {
+ return super.preloadAllPlugins();
+ }
+ }
+
+ @Override
+ protected List<PluginKey> getDisabledPluginKeys() {
+ // in the real world, the db is checked for enable flag, here we say all plugins are enabled
+ return new ArrayList<PluginKey>();
+ }
+ }
+
+ public class TestBundleServerPluginContainer extends GenericServerPluginContainer {
+ public State state = State.UNINITIALIZED;
+
+ public TestBundleServerPluginContainer(MasterServerPluginContainer master) {
+ super(master);
+ }
+
+ @Override
+ protected ServerPluginManager createPluginManager() {
+ TestBundlePluginManager pm = new TestBundlePluginManager(this);
+ return pm;
+ }
+
+ @Override
+ public synchronized void initialize() throws Exception {
+ if (state == State.UNINITIALIZED) {
+ state = State.INITIALIZED;
+ } else {
+ System.out.println("!!! PC LIFECYCLE WAS BAD - THIS IS A BUG !!!");
+ throw new IllegalStateException("not uninitialized: " + state);
+ }
+ super.initialize();
+ }
+
+ @Override
+ public synchronized void start() {
+ if (state == State.INITIALIZED) {
+ state = State.STARTED;
+ } else {
+ System.out.println("!!! PC LIFECYCLE WAS BAD - THIS IS A BUG !!!");
+ throw new IllegalStateException("not initialized: " + state);
+ }
+ super.start();
+ }
+
+ @Override
+ public synchronized void stop() {
+ if (state == State.STARTED) {
+ state = State.STOPPED;
+ } else {
+ System.out.println("!!! PC LIFECYCLE WAS BAD - THIS IS A BUG !!!");
+ throw new IllegalStateException("not started: " + state);
+ }
+ super.stop();
+ }
+
+ @Override
+ public synchronized void shutdown() {
+ if (state == State.STOPPED) {
+ state = State.UNINITIALIZED;
+ } else {
+ System.out.println("!!! PC LIFECYCLE WAS BAD - THIS IS A BUG !!!");
+ throw new IllegalStateException("not stopped: " + state);
+ }
+ super.shutdown();
+ }
+ }
+
+ /**
+ * The test plugin manager.
+ */
+ class TestBundlePluginManager extends ServerPluginManager {
+ public final Map<String, ServerPluginComponent> components;
+
+ public TestBundlePluginManager(TestBundleServerPluginContainer pc) {
+ super(pc);
+ components = new HashMap<String, ServerPluginComponent>();
+ }
+
+ @Override
+ protected ServerPlugin getPlugin(ServerPluginEnvironment env) {
+
+ try {
+ Configuration pluginConfig = null;
+ Configuration scheduledJobsConfig = null;
+ ConfigurationDefinition configDef;
+
+ ServerPluginDescriptorType pluginDescriptor = env.getPluginDescriptor();
+
+ configDef = ServerPluginDescriptorMetadataParser.getPluginConfigurationDefinition(pluginDescriptor);
+ if (configDef != null) {
+ pluginConfig = configDef.getDefaultTemplate().createConfiguration();
+ }
+
+ configDef = ServerPluginDescriptorMetadataParser.getScheduledJobsDefinition(pluginDescriptor);
+ if (configDef != null) {
+ scheduledJobsConfig = configDef.getDefaultTemplate().createConfiguration();
+ }
+
+ File pluginFile = new File(env.getPluginUrl().toURI());
+ ServerPlugin plugin = new ServerPlugin(0, env.getPluginKey().getPluginName(), pluginFile.getName(),
+ pluginDescriptor.getDisplayName(), true, PluginStatusType.INSTALLED, pluginDescriptor
+ .getDescription(), "", MessageDigestGenerator.getDigestString(pluginFile), pluginDescriptor
+ .getVersion(), pluginDescriptor.getVersion(), pluginConfig, scheduledJobsConfig,
+ new ServerPluginType(pluginDescriptor).stringify(), System.currentTimeMillis(), System
+ .currentTimeMillis());
+ return plugin;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ protected ServerPluginComponent createServerPluginComponent(ServerPluginEnvironment environment)
+ throws Exception {
+ ServerPluginComponent component = super.createServerPluginComponent(environment);
+ components.put(environment.getPluginKey().getPluginName(), component);
+ return component;
+ }
+ }
+}
\ No newline at end of file
commit bf127b50c0157b289c78b9073002931bb131ea00
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Mar 2 13:52:43 2010 -0500
be defensive when building the template engine replacement variables - get as many variables as we can, ignoring native errors if we hit them
diff --git a/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java b/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java
index 27a1375..573e9c0 100644
--- a/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java
+++ b/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java
@@ -26,10 +26,11 @@ import java.io.File;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
+import java.net.InetAddress;
import java.net.URL;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
-import java.util.TreeMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -43,7 +44,11 @@ import org.rhq.core.util.exception.ThrowableUtil;
* @author John Mazzitelli
*/
public class SystemInfoFactory {
- private static final String TOKEN_PREFIX = "rhq.system.";
+ /**
+ * All template engine replacement variables that this factory's template engine will know about
+ * will be prefixed with this string.
+ */
+ public static final String TOKEN_PREFIX = "rhq.system.";
private static final Log LOG = LogFactory.getLog(SystemInfoFactory.class);
@@ -343,35 +348,60 @@ public class SystemInfoFactory {
public static TemplateEngine fetchTemplateEngine() {
- try{
- SystemInfo systemInfo = createSystemInfo();
-
- Map<String, String> tokens = new HashMap<String, String>();
- tokens.put(TOKEN_PREFIX+"hostname", systemInfo.getHostname());
-
- tokens.put(TOKEN_PREFIX+"os.name", systemInfo.getOperatingSystemName());
- tokens.put(TOKEN_PREFIX+"os.version", systemInfo.getOperatingSystemVersion());
- tokens.put(TOKEN_PREFIX+"os.type", systemInfo.getOperatingSystemType().toString());
- tokens.put(TOKEN_PREFIX+"cpu.count", Integer.toString(systemInfo.getNumberOfCpus()));
- tokens.put(TOKEN_PREFIX+"architecture", systemInfo.getSystemArchitecture());
-
- for (NetworkAdapterInfo networkAdapter : systemInfo.getAllNetworkAdapters()) {
- String key = TOKEN_PREFIX+"interfaces." + networkAdapter.getName();
- tokens.put(key + ".mac", networkAdapter.getMacAddressString());
- tokens.put(key + ".type", networkAdapter.getType());
- tokens.put(key + ".flags", networkAdapter.getAllFlags());
-
- if (!networkAdapter.getUnicastAddresses().isEmpty()) {
- tokens.put(key + ".address", networkAdapter.getUnicastAddresses().get(0).getHostAddress());
+ try {
+ SystemInfo systemInfo = createSystemInfo();
+
+ Map<String, String> tokens = new HashMap<String, String>();
+ tokens.put(TOKEN_PREFIX + "hostname", systemInfo.getHostname());
+
+ tokens.put(TOKEN_PREFIX + "os.name", systemInfo.getOperatingSystemName());
+ tokens.put(TOKEN_PREFIX + "os.version", systemInfo.getOperatingSystemVersion());
+ tokens.put(TOKEN_PREFIX + "os.type", systemInfo.getOperatingSystemType().toString());
+ tokens.put(TOKEN_PREFIX + "architecture", systemInfo.getSystemArchitecture());
+ try {
+ tokens.put(TOKEN_PREFIX + "cpu.count", Integer.toString(systemInfo.getNumberOfCpus()));
+ } catch (Exception e) {
+ tokens.put(TOKEN_PREFIX + "cpu.count", "?");
}
- if (!networkAdapter.getMulticastAddresses().isEmpty()) {
- tokens.put(key + ".multicast.address", networkAdapter.getMulticastAddresses().get(0).getHostAddress());
+
+ List<NetworkAdapterInfo> allNetworkAdapters = null;
+ try {
+ allNetworkAdapters = systemInfo.getAllNetworkAdapters();
+ } catch (Exception e) {
}
- }
- TemplateEngine templateEngine = new TemplateEngine(tokens);
- return templateEngine;
- }catch(Exception e){
- return new TemplateEngine(new HashMap());
+ if (allNetworkAdapters != null) {
+ for (NetworkAdapterInfo networkAdapter : allNetworkAdapters) {
+ String key = TOKEN_PREFIX + "interfaces." + networkAdapter.getName();
+ tokens.put(key + ".mac", networkAdapter.getMacAddressString());
+ tokens.put(key + ".type", networkAdapter.getType());
+ tokens.put(key + ".flags", networkAdapter.getAllFlags());
+
+ if (!networkAdapter.getUnicastAddresses().isEmpty()) {
+ tokens.put(key + ".address", networkAdapter.getUnicastAddresses().get(0).getHostAddress());
+ }
+ if (!networkAdapter.getMulticastAddresses().isEmpty()) {
+ tokens.put(key + ".multicast.address", networkAdapter.getMulticastAddresses().get(0)
+ .getHostAddress());
+ }
+ }
+ }
+
+ // create a base IP address - this one is known to java and should always exist no matter what platform we are on
+ try {
+ try {
+ tokens.put(TOKEN_PREFIX + "interfaces.java.address", InetAddress
+ .getByName(systemInfo.getHostname()).getHostAddress());
+ } catch (Exception e) {
+ tokens.put(TOKEN_PREFIX + "interfaces.java.address", InetAddress.getLocalHost().getHostAddress());
+ }
+ } catch (Exception e2) {
+ }
+
+ TemplateEngine templateEngine = new TemplateEngine(tokens);
+ return templateEngine;
+ } catch (Exception e) {
+ // some rare exception occurred that we didn't expect, rather than blow up entirely, just don't provide any values
+ return new TemplateEngine(new HashMap<String, String>());
}
}
}
\ No newline at end of file
commit 1ad822fe979dbc3e7e05b525ad49022a73b57fd3
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Mar 2 13:04:35 2010 -0500
cherry picking two commits b10d6026bba36c90530077dec3f22475c34ac69c and
3b7d6dc377c6c5e211ce8b868ccd0801f0b57a7a to pick up fixes to the template engine
Catch and exception and return an empty template enginer if SystemInfoFactory throws and exception. Reorder operations in ConfigurationManager to not swallow a null exception.
Conflicts:
modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java
diff --git a/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java b/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java
index 2558b44..27a1375 100644
--- a/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java
+++ b/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java
@@ -343,10 +343,12 @@ public class SystemInfoFactory {
public static TemplateEngine fetchTemplateEngine() {
+ try{
SystemInfo systemInfo = createSystemInfo();
Map<String, String> tokens = new HashMap<String, String>();
tokens.put(TOKEN_PREFIX+"hostname", systemInfo.getHostname());
+
tokens.put(TOKEN_PREFIX+"os.name", systemInfo.getOperatingSystemName());
tokens.put(TOKEN_PREFIX+"os.version", systemInfo.getOperatingSystemVersion());
tokens.put(TOKEN_PREFIX+"os.type", systemInfo.getOperatingSystemType().toString());
@@ -366,7 +368,10 @@ public class SystemInfoFactory {
tokens.put(key + ".multicast.address", networkAdapter.getMulticastAddresses().get(0).getHostAddress());
}
}
- TemplateEngine templateEngine = new TemplateEngine(tokens);
+ TemplateEngine templateEngine = new TemplateEngine(tokens);
return templateEngine;
+ }catch(Exception e){
+ return new TemplateEngine(new HashMap());
+ }
}
}
\ No newline at end of file
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java
index 580da62..8c3d50c 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java
@@ -22,8 +22,18 @@
*/
package org.rhq.core.pc.configuration;
+import java.util.LinkedList;
+import java.util.Queue;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.agent.configuration.ConfigurationAgentService;
import org.rhq.core.clientapi.agent.configuration.ConfigurationUpdateRequest;
@@ -46,15 +56,6 @@ import org.rhq.core.pluginapi.configuration.ResourceConfigurationFacet;
import org.rhq.core.system.SystemInfoFactory;
import org.rhq.core.template.TemplateEngine;
-import java.util.LinkedList;
-import java.util.Queue;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
/**
* Manages configuration of all resources across all plugins.
*
@@ -185,21 +186,20 @@ public class ConfigurationManager extends AgentService implements ContainerServi
Configuration structuredConfig = facet.loadStructuredConfiguration();
TemplateEngine templateEngine = SystemInfoFactory.fetchTemplateEngine();
-
+
if (structuredConfig != null) {
prepareConfigForMergeIntoStructured(configuration, structuredConfig);
for (RawConfiguration rawConfig : configuration.getRawConfigurations()) {
String contents = templateEngine.replaceTokens(new String(rawConfig.getContents()));
rawConfig.setContents(contents);
-
+
structuredConfig.addRawConfiguration(rawConfig);
facet.mergeStructuredConfiguration(rawConfig, configuration);
}
}
}
-
private void prepareConfigForMergeIntoStructured(Configuration config, Configuration latestStructured) {
config.getAllProperties().clear();
for (Property property : latestStructured.getProperties()) {
@@ -217,12 +217,14 @@ public class ConfigurationManager extends AgentService implements ContainerServi
prepareConfigForMergeIntoRaws(configuration, rawConfigs);
Queue<RawConfiguration> queue = new LinkedList<RawConfiguration>(rawConfigs);
+ TemplateEngine templateEngine = SystemInfoFactory.fetchTemplateEngine();
while (!queue.isEmpty()) {
RawConfiguration originalRaw = queue.poll();
RawConfiguration mergedRaw = facet.mergeRawConfiguration(configuration, originalRaw);
-
if (mergedRaw != null) {
+ //TODO bypass validation of structured config for template values
+ mergedRaw.setContents(templateEngine.replaceTokens(mergedRaw.getContents()));
updateRawConfig(configuration, originalRaw, mergedRaw);
}
}
@@ -364,7 +366,7 @@ public class ConfigurationManager extends AgentService implements ContainerServi
}
public void validate(Configuration configuration, int resourceId, boolean isStructured)
- throws PluginContainerException {
+ throws PluginContainerException {
boolean daemonOnly = true;
boolean onlyIfStarted = true;
ResourceConfigurationFacet facet = componentService.getComponent(resourceId, ResourceConfigurationFacet.class,
@@ -372,26 +374,27 @@ public class ConfigurationManager extends AgentService implements ContainerServi
if (isStructured) {
return;
} else {
- StringBuilder errorMessage = null;
+ StringBuilder errorMessage = null;
- try{
+ try {
for (RawConfiguration rawConfiguration : configuration.getRawConfigurations()) {
try {
facet.validateRawConfiguration(rawConfiguration);
} catch (IllegalArgumentException e) {
- if (null == errorMessage){
+ if (null == errorMessage) {
errorMessage = new StringBuilder();
}
- errorMessage.append("file " + rawConfiguration.getPath() +" failed validation with " + e.getMessage()+"." );
+ errorMessage.append("file " + rawConfiguration.getPath() + " failed validation with "
+ + e.getMessage() + ".");
}
}
- }catch(Throwable t){
+ } catch (Throwable t) {
errorMessage = new StringBuilder();
- errorMessage.append("configuation validation failed with" + t.getMessage()+".");
- }
- if (null != errorMessage){
- throw new PluginContainerException(errorMessage.toString());
- }
- }
+ errorMessage.append("configuation validation failed with" + t.getMessage() + ".");
+ }
+ if (null != errorMessage) {
+ throw new PluginContainerException(errorMessage.toString());
+ }
+ }
}
}
commit 93681f0a83acd915eec2aad84b17304f9545a04b
Author: Adam Young <ayoung(a)redhat.com>
Date: Wed Jan 27 21:16:56 2010 -0500
Modified the key for template replacement.
diff --git a/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java b/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java
index 3a29fff..2558b44 100644
--- a/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java
+++ b/modules/core/native-system/src/main/java/org/rhq/core/system/SystemInfoFactory.java
@@ -43,6 +43,8 @@ import org.rhq.core.util.exception.ThrowableUtil;
* @author John Mazzitelli
*/
public class SystemInfoFactory {
+ private static final String TOKEN_PREFIX = "rhq.system.";
+
private static final Log LOG = LogFactory.getLog(SystemInfoFactory.class);
private static final String NATIVE_LIBRARY_CLASS_NAME = "org.hyperic.sigar.Sigar";
@@ -344,15 +346,15 @@ public class SystemInfoFactory {
SystemInfo systemInfo = createSystemInfo();
Map<String, String> tokens = new HashMap<String, String>();
- tokens.put("rhq.hostname", systemInfo.getHostname());
- tokens.put("rhq.os.name", systemInfo.getOperatingSystemName());
- tokens.put("rhq.os.version", systemInfo.getOperatingSystemVersion());
- tokens.put("rhq.os.type", systemInfo.getOperatingSystemType().toString());
- tokens.put("rhq.cpu.count", Integer.toString(systemInfo.getNumberOfCpus()));
- tokens.put("rhq.architecture", systemInfo.getSystemArchitecture());
+ tokens.put(TOKEN_PREFIX+"hostname", systemInfo.getHostname());
+ tokens.put(TOKEN_PREFIX+"os.name", systemInfo.getOperatingSystemName());
+ tokens.put(TOKEN_PREFIX+"os.version", systemInfo.getOperatingSystemVersion());
+ tokens.put(TOKEN_PREFIX+"os.type", systemInfo.getOperatingSystemType().toString());
+ tokens.put(TOKEN_PREFIX+"cpu.count", Integer.toString(systemInfo.getNumberOfCpus()));
+ tokens.put(TOKEN_PREFIX+"architecture", systemInfo.getSystemArchitecture());
for (NetworkAdapterInfo networkAdapter : systemInfo.getAllNetworkAdapters()) {
- String key = "rhq.interfaces." + networkAdapter.getName();
+ String key = TOKEN_PREFIX+"interfaces." + networkAdapter.getName();
tokens.put(key + ".mac", networkAdapter.getMacAddressString());
tokens.put(key + ".type", networkAdapter.getType());
tokens.put(key + ".flags", networkAdapter.getAllFlags());
commit dd4632701533ece8302da44595ef1dc6c2a1fdd4
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Mon Mar 1 17:12:54 2010 -0500
start parsing replacement variables
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java
index 029222b..26d1b82 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java
@@ -26,6 +26,10 @@ package org.rhq.bundle.filetemplate.recipe;
import gnu.getopt.Getopt;
import gnu.getopt.LongOpt;
+/**
+ * @deprecated I think this command will not be used - probably should delete it
+ * @author mazz
+ */
public class ConfigdefRecipeCommand implements RecipeCommand {
public String getName() {
@@ -67,7 +71,8 @@ public class ConfigdefRecipeCommand implements RecipeCommand {
throw new IllegalArgumentException("Missing the -f argument to indicate what the config def filename is");
}
- context.setConfigurationDefinitionFilename(filename);
+ // TODO: what to do? can I delete this command entirely?
+
return;
}
}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
index 92c204e..c895107 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
@@ -24,7 +24,9 @@
package org.rhq.bundle.filetemplate.recipe;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
/**
* Contains information that is gleened from a recipe after it is parsed.
@@ -34,13 +36,13 @@ import java.util.Map;
public class RecipeContext {
private final String recipe;
- private String configurationDefinitionFilename;
- private Map<String, String> deployFiles;
+ private final Map<String, String> deployFiles;
+ private final Set<String> replacementVariables;
public RecipeContext(String recipe) {
this.recipe = recipe;
- this.configurationDefinitionFilename = null;
this.deployFiles = new HashMap<String, String>();
+ this.replacementVariables = new HashSet<String>();
}
/**
@@ -49,21 +51,7 @@ public class RecipeContext {
* @return the actual recipe text
*/
public String getRecipe() {
- return recipe;
- }
-
- /**
- * A recipe can have an optional configuration definition file associated with it.
- * If this returns non-<code>null</code>, it refers to this configuration definition file.
- *
- * @return config def filename
- */
- public String getConfigurationDefinitionFilename() {
- return configurationDefinitionFilename;
- }
-
- public void setConfigurationDefinitionFilename(String filename) {
- this.configurationDefinitionFilename = filename;
+ return this.recipe;
}
/**
@@ -79,4 +67,18 @@ public class RecipeContext {
public void addDeployFile(String filename, String directory) {
this.deployFiles.put(filename, directory);
}
+
+ /**
+ * The names of all replacement variables that are found in the recipe.
+ *
+ * @return the replacement variables
+ */
+ public Set<String> getReplacementVariables() {
+ return this.replacementVariables;
+ }
+
+ public void addReplacementVariables(Set<String> replacementVariables) {
+ this.replacementVariables.addAll(replacementVariables);
+ }
+
}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
index b52e807..df797f4 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
@@ -30,8 +30,12 @@ import java.io.StreamTokenizer;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* Parses the file template recipe.
@@ -42,6 +46,12 @@ import java.util.Map;
public class RecipeParser {
private Map<String, RecipeCommand> recipeCommands;
+ // note that we use the same as the core util's template engine
+ // the native system replacement variable prefix is used by the agent-side fact variable names
+ private final Pattern replacementVariableDeclarationPattern = Pattern.compile("<%\\s*(\\w+\\.?)+\\s*%>");
+ private final Pattern replacementVariableNamePattern = Pattern.compile("(\\w+\\.?)+");
+ private final String systemReplacementVariablePrefix = "rhq.system.";
+
public RecipeParser() {
setupRecipeCommands();
}
@@ -74,7 +84,13 @@ public class RecipeParser {
throw new Exception("Unknown command in recipe: " + commandName);
}
+ Set<String> replacementVars = getReplacementVariables(line);
+ if (replacementVars != null) {
+ context.addReplacementVariables(replacementVars);
+ }
+
recipeCommand.parse(context, arguments);
+
return;
}
@@ -90,6 +106,27 @@ public class RecipeParser {
}
}
+ private Set<String> getReplacementVariables(String cmdLine) {
+ Set<String> replacementVariables = null;
+ Matcher matcher = this.replacementVariableDeclarationPattern.matcher(cmdLine);
+ while (matcher.find()) {
+ String replacementDeclaration = matcher.group();
+ Matcher matcherInner = this.replacementVariableNamePattern.matcher(replacementDeclaration);
+ if (!matcherInner.find()) {
+ throw new IllegalArgumentException("Bad replacement declaration [" + replacementDeclaration + "]");
+ }
+ String replacementVariable = matcherInner.group();
+ if (!replacementVariable.startsWith(this.systemReplacementVariablePrefix)) {
+ if (replacementVariables == null) {
+ replacementVariables = new HashSet<String>(1);
+ }
+ replacementVariables.add(replacementVariable);
+ }
+ }
+
+ return replacementVariables;
+ }
+
private String[] splitCommandLine(String cmdLine) {
ByteArrayInputStream in = new ByteArrayInputStream(cmdLine.getBytes());
StreamTokenizer strtok = new StreamTokenizer(new InputStreamReader(in));
diff --git a/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
index d573072..7d58b88 100644
--- a/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
+++ b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
@@ -23,6 +23,8 @@
package org.rhq.bundle.filetemplate.recipe;
+import java.util.Map;
+
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@@ -35,14 +37,49 @@ public class RecipeParserTest {
cleanRecipe();
}
+ public void testSimpleRecipeReplacementVariables() throws Exception {
+ addRecipeCommand("# <% ignored.inside.comment %>");
+ addRecipeCommand("deploy -f jboss.tar -d \"<% opt.dir %>/jboss\"");
+ addRecipeCommand("deploy -f tomcat.tar -d <%opt.dir%>/tomcat");
+ addRecipeCommand("deploy -f jboss.zip -d <%rhq.system.hostname%>/opt/tomcat"); // this is ignored, its an agent fact variable
+ RecipeParser parser = new RecipeParser();
+ RecipeContext context = parser.parseRecipe(getRecipe());
+ Map<String, String> files = context.getDeployFiles();
+ assert files.containsKey("jboss.tar") : files;
+ assert files.get("jboss.tar").equals("<% opt.dir %>/jboss") : files;
+ assert files.containsKey("tomcat.tar") : files;
+ assert files.get("tomcat.tar").equals("<%opt.dir%>/tomcat") : files;
+ assert files.containsKey("jboss.zip") : files;
+ assert files.get("jboss.zip").equals("<%rhq.system.hostname%>/opt/tomcat") : files;
+ assert context.getReplacementVariables().contains("opt.dir") : context.getReplacementVariables();
+ assert context.getReplacementVariables().size() == 1 : context.getReplacementVariables();
+ }
+
public void testSimpleRecipe() throws Exception {
addRecipeCommand("deploy -f jboss.tar -d /opt/jboss");
- addRecipeCommand("configdef -f config.xml");
+ addRecipeCommand("deploy -f tomcat.tar -d /opt/tomcat");
+ RecipeParser parser = new RecipeParser();
+ RecipeContext context = parser.parseRecipe(getRecipe());
+ Map<String, String> files = context.getDeployFiles();
+ assert files.containsKey("jboss.tar") : files;
+ assert files.get("jboss.tar").equals("/opt/jboss") : files;
+ assert files.containsKey("tomcat.tar") : files;
+ assert files.get("tomcat.tar").equals("/opt/tomcat") : files;
+ }
+
+ public void testSimpleRecipeWithQuotes() throws Exception {
+ addRecipeCommand("deploy -f jboss1.zip -d \"/opt/jboss1\"");
+ addRecipeCommand("deploy -f jboss.tar --directory='/opt/jboss'");
+ addRecipeCommand("deploy -f tomcat.tar \"--directory=/opt/tomcat\"");
RecipeParser parser = new RecipeParser();
RecipeContext context = parser.parseRecipe(getRecipe());
- assert context.getConfigurationDefinitionFilename().equals("config.xml");
- assert context.getDeployFiles().containsKey("jboss.tar");
- assert context.getDeployFiles().get("jboss.tar").equals("/opt/jboss");
+ Map<String, String> files = context.getDeployFiles();
+ assert files.containsKey("jboss1.zip") : files;
+ assert files.get("jboss1.zip").equals("/opt/jboss1") : files;
+ assert files.containsKey("jboss.tar") : files;
+ assert files.get("jboss.tar").equals("'/opt/jboss'") : files;
+ assert files.containsKey("tomcat.tar") : files;
+ assert files.get("tomcat.tar").equals("/opt/tomcat") : files;
}
public void testSimpleRecipeError() throws Exception {
@@ -57,11 +94,11 @@ public class RecipeParserTest {
}
cleanRecipe();
- addRecipeCommand("configdef");
+ addRecipeCommand("deploy -d /opt/jboss");
try {
parser.parseRecipe(getRecipe());
- assert false : "This should have failed - need to provide a -f to the configdef command";
+ assert false : "This should have failed - need to provide a -f to the deploy command";
} catch (Exception ok) {
// to be expected
}
@@ -75,16 +112,18 @@ public class RecipeParserTest {
addRecipeCommand("");
addRecipeCommand("#");
addRecipeCommand("### comment here");
- addRecipeCommand("configdef -f config.xml");
+ addRecipeCommand("deploy -f tomcat.tar -d /opt/tomcat");
addRecipeCommand("");
addRecipeCommand("#");
addRecipeCommand("### comment here");
addRecipeCommand("");
RecipeParser parser = new RecipeParser();
RecipeContext context = parser.parseRecipe(getRecipe());
- assert context.getConfigurationDefinitionFilename().equals("config.xml");
- assert context.getDeployFiles().containsKey("jboss.tar");
- assert context.getDeployFiles().get("jboss.tar").equals("/opt/jboss");
+ Map<String, String> files = context.getDeployFiles();
+ assert files.containsKey("jboss.tar") : files;
+ assert files.get("jboss.tar").equals("/opt/jboss") : files;
+ assert files.containsKey("tomcat.tar") : files;
+ assert files.get("tomcat.tar").equals("/opt/tomcat") : files;
}
private void cleanRecipe() {
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 a67fc1a..147f2a5 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,8 @@
package org.rhq.enterprise.server.plugins.filetemplate;
+import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
@@ -29,6 +31,8 @@ import org.rhq.bundle.filetemplate.recipe.RecipeParser;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
+import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
+import org.rhq.core.domain.configuration.definition.PropertySimpleType;
import org.rhq.enterprise.server.bundle.RecipeParseResults;
import org.rhq.enterprise.server.plugin.pc.ControlFacet;
import org.rhq.enterprise.server.plugin.pc.ControlResults;
@@ -68,9 +72,19 @@ public class BundleServerPluginComponent implements ServerPluginComponent, Bundl
RecipeParser parser = new RecipeParser();
RecipeContext parserContext = parser.parseRecipe(recipe);
- // TODO convert the context into the proper data that the parse results wants
+ Set<String> bundleFileNames = new HashSet<String>();
+ Map<String, String> deployFiles = deployFiles = parserContext.getDeployFiles();
+ bundleFileNames.addAll(deployFiles.keySet());
+
ConfigurationDefinition configDef = null;
- Set<String> bundleFileNames = null;
+ if (parserContext.getReplacementVariables() != null) {
+ configDef = new ConfigurationDefinition("replacementVariables", null);
+ for (String replacementVar : parserContext.getReplacementVariables()) {
+ PropertyDefinitionSimple prop = new PropertyDefinitionSimple(replacementVar, null, false,
+ PropertySimpleType.STRING);
+ configDef.put(prop);
+ }
+ }
RecipeParseResults results = new RecipeParseResults(configDef, bundleFileNames);
return results;
commit c0c6ae1ec0cfe537d9980b9015b5b757de7ac4d6
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Mon Mar 1 15:10:29 2010 -0500
get configdef and deploy to parse - create unit test - support blank/comment lines
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java
index 057d474..029222b 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java
@@ -45,11 +45,11 @@ public class ConfigdefRecipeCommand implements RecipeCommand {
switch (code) {
case ':':
case '?': {
- throw new IllegalArgumentException("Bad recipe command [" + getName() + "]: " + args);
+ throw new IllegalArgumentException("Bad recipe argument.");
}
case 1: {
- throw new IllegalArgumentException("Bad recipe command [" + getName() + "]: " + args);
+ throw new IllegalArgumentException("Bad recipe argument!");
}
case 'f': {
@@ -58,12 +58,16 @@ public class ConfigdefRecipeCommand implements RecipeCommand {
}
default: {
- throw new IllegalArgumentException("Unexpected error in recipe command [" + getName() + "]: " + args);
+ throw new IllegalArgumentException("Unexpected error in recipe command");
}
-
}
}
- // TODO : do something with filename
+ if (filename == null) {
+ throw new IllegalArgumentException("Missing the -f argument to indicate what the config def filename is");
+ }
+
+ context.setConfigurationDefinitionFilename(filename);
+ return;
}
}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java
index 145398c..5f14f2f 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java
@@ -47,11 +47,11 @@ public class DeployRecipeCommand implements RecipeCommand {
switch (code) {
case ':':
case '?': {
- throw new IllegalArgumentException("Bad recipe command [" + getName() + "]: " + args);
+ throw new IllegalArgumentException("Bad recipe command.");
}
case 1: {
- throw new IllegalArgumentException("Bad recipe command [" + getName() + "]: " + args);
+ throw new IllegalArgumentException("Bad recipe command!");
}
case 'f': {
@@ -65,12 +65,21 @@ public class DeployRecipeCommand implements RecipeCommand {
}
default: {
- throw new IllegalArgumentException("Unexpected error in recipe command [" + getName() + "]: " + args);
+ throw new IllegalArgumentException("Unexpected error in recipe command");
}
}
}
- // TODO : do something with filename and directory
+ if (filename == null) {
+ throw new IllegalArgumentException("Did not specify the name of the file to deploy");
+ }
+
+ if (directory == null) {
+ throw new IllegalArgumentException("Did not specify the directory where the file should be deployed");
+ }
+
+ context.addDeployFile(filename, directory);
+ return;
}
}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
index da96ceb..92c204e 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
@@ -23,15 +23,24 @@
package org.rhq.bundle.filetemplate.recipe;
+import java.util.HashMap;
+import java.util.Map;
+
/**
+ * Contains information that is gleened from a recipe after it is parsed.
+ *
* @author John Mazzitelli
*/
public class RecipeContext {
private final String recipe;
+ private String configurationDefinitionFilename;
+ private Map<String, String> deployFiles;
public RecipeContext(String recipe) {
this.recipe = recipe;
+ this.configurationDefinitionFilename = null;
+ this.deployFiles = new HashMap<String, String>();
}
/**
@@ -42,4 +51,32 @@ public class RecipeContext {
public String getRecipe() {
return recipe;
}
+
+ /**
+ * A recipe can have an optional configuration definition file associated with it.
+ * If this returns non-<code>null</code>, it refers to this configuration definition file.
+ *
+ * @return config def filename
+ */
+ public String getConfigurationDefinitionFilename() {
+ return configurationDefinitionFilename;
+ }
+
+ public void setConfigurationDefinitionFilename(String filename) {
+ this.configurationDefinitionFilename = filename;
+ }
+
+ /**
+ * Returns all the files that are to be deployed. The key is the bundle file's name, the
+ * value is the directory where the bundle is to be deployed to.
+ *
+ * @return map of all files to be deployed and the location where they are to be deployed
+ */
+ public Map<String, String> getDeployFiles() {
+ return this.deployFiles;
+ }
+
+ public void addDeployFile(String filename, String directory) {
+ this.deployFiles.put(filename, directory);
+ }
}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
index ff9b91f..b52e807 100644
--- a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
@@ -52,21 +52,30 @@ public class RecipeParser {
BufferedReader recipeReader = new BufferedReader(new StringReader(recipe));
String line = recipeReader.readLine();
while (line != null) {
- String[] commandLineArray = splitCommandLine(line);
- String commandName = commandLineArray[0];
- String[] arguments = extractArguments(commandLineArray);
+ parseRecipeCommandLine(context, line);
+ line = recipeReader.readLine();
+ }
- RecipeCommand recipeCommand = recipeCommands.get(commandName);
- if (recipeCommand == null) {
- throw new Exception("Unknown command in recipe: " + commandName);
- }
+ return context;
+ }
- recipeCommand.parse(context, arguments);
+ public void parseRecipeCommandLine(RecipeContext context, String line) throws Exception {
+ // ignore blank lines or comment lines that start with #
+ if (line == null || line.trim().length() == 0 || line.startsWith("#")) {
+ return;
+ }
- line = recipeReader.readLine();
+ String[] commandLineArray = splitCommandLine(line);
+ String commandName = commandLineArray[0];
+ String[] arguments = extractArguments(commandLineArray);
+
+ RecipeCommand recipeCommand = recipeCommands.get(commandName);
+ if (recipeCommand == null) {
+ throw new Exception("Unknown command in recipe: " + commandName);
}
- return context;
+ recipeCommand.parse(context, arguments);
+ return;
}
private void setupRecipeCommands() {
diff --git a/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
new file mode 100644
index 0000000..d573072
--- /dev/null
+++ b/modules/common/filetemplate-bundle/src/test/java/org/rhq/bundle/filetemplate/recipe/RecipeParserTest.java
@@ -0,0 +1,101 @@
+/*
+ * 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, 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.bundle.filetemplate.recipe;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+@Test
+public class RecipeParserTest {
+ private StringBuilder recipe;
+
+ @BeforeMethod
+ public void cleanRecipeBeforeMethod() {
+ cleanRecipe();
+ }
+
+ public void testSimpleRecipe() throws Exception {
+ addRecipeCommand("deploy -f jboss.tar -d /opt/jboss");
+ addRecipeCommand("configdef -f config.xml");
+ RecipeParser parser = new RecipeParser();
+ RecipeContext context = parser.parseRecipe(getRecipe());
+ assert context.getConfigurationDefinitionFilename().equals("config.xml");
+ assert context.getDeployFiles().containsKey("jboss.tar");
+ assert context.getDeployFiles().get("jboss.tar").equals("/opt/jboss");
+ }
+
+ public void testSimpleRecipeError() throws Exception {
+ addRecipeCommand("deploy -f jboss.tar");
+ RecipeParser parser = new RecipeParser();
+
+ try {
+ parser.parseRecipe(getRecipe());
+ assert false : "This should have failed - need to provide a -d to the deploy command";
+ } catch (Exception ok) {
+ // to be expected
+ }
+
+ cleanRecipe();
+ addRecipeCommand("configdef");
+
+ try {
+ parser.parseRecipe(getRecipe());
+ assert false : "This should have failed - need to provide a -f to the configdef command";
+ } catch (Exception ok) {
+ // to be expected
+ }
+ }
+
+ public void testSimpleRecipeComments() throws Exception {
+ addRecipeCommand("");
+ addRecipeCommand("#");
+ addRecipeCommand("### comment here");
+ addRecipeCommand("deploy -f jboss.tar -d /opt/jboss");
+ addRecipeCommand("");
+ addRecipeCommand("#");
+ addRecipeCommand("### comment here");
+ addRecipeCommand("configdef -f config.xml");
+ addRecipeCommand("");
+ addRecipeCommand("#");
+ addRecipeCommand("### comment here");
+ addRecipeCommand("");
+ RecipeParser parser = new RecipeParser();
+ RecipeContext context = parser.parseRecipe(getRecipe());
+ assert context.getConfigurationDefinitionFilename().equals("config.xml");
+ assert context.getDeployFiles().containsKey("jboss.tar");
+ assert context.getDeployFiles().get("jboss.tar").equals("/opt/jboss");
+ }
+
+ private void cleanRecipe() {
+ this.recipe = new StringBuilder();
+ }
+
+ private void addRecipeCommand(String commandLine) {
+ this.recipe.append(commandLine).append("\n");
+ }
+
+ private String getRecipe() {
+ return this.recipe.toString();
+ }
+}
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 96f7070..a67fc1a 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
@@ -68,7 +68,7 @@ public class BundleServerPluginComponent implements ServerPluginComponent, Bundl
RecipeParser parser = new RecipeParser();
RecipeContext parserContext = parser.parseRecipe(recipe);
- // TODO convert the context to the results object
+ // TODO convert the context into the proper data that the parse results wants
ConfigurationDefinition configDef = null;
Set<String> bundleFileNames = null;
commit f2f559b7cdb5055bf572804b82db5f1322913582
Merge: 84ebcfc... 7f70926...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Mar 1 14:50:20 2010 -0500
Merge branch 'bundle' into bundle-jay
commit 84ebcfc94992d0d7f0d6cb1a0a441ece7131d69e
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Mar 1 14:50:13 2010 -0500
local intermittent check-in for merge purposes
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 ce559bf..6d67e56 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
@@ -35,7 +35,6 @@ import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleDeployment;
-import org.rhq.core.domain.bundle.BundleFile;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.content.Repo;
@@ -49,6 +48,7 @@ import org.rhq.core.domain.util.PersistenceUtility;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.authz.AuthorizationManagerLocal;
import org.rhq.enterprise.server.authz.PermissionException;
+import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginFacet;
import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal;
import org.rhq.enterprise.server.util.CriteriaQueryGenerator;
import org.rhq.enterprise.server.util.CriteriaQueryRunner;
@@ -72,15 +72,10 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
@EJB
private ResourceTypeManagerLocal resourceTypeManager;
- @SuppressWarnings("unchecked")
- public List<BundleFile> findBundleFilesForBundleVersion(int bundleVersionId) throws Exception {
- Query q = entityManager.createNamedQuery(BundleFile.QUERY_FIND_BY_BUNDLE_VERSION_ID);
- q.setParameter("id", bundleVersionId);
- List<BundleFile> bundleFiles = (List<BundleFile>) q.getResultList();
- return bundleFiles;
- }
-
public Bundle createBundle(Subject subject, Bundle bundle) {
+ if (null == bundle || null == bundle.getName())
+ throw new IllegalArgumentException("Missing one or more of: bundle, name");
+
// add the implicit bundle repo, if necessary
if (null == bundle.getRepo()) {
Repo repo = new Repo(bundle.getName());
@@ -95,12 +90,25 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
return bundle;
}
- public BundleType createBundleType(Subject subject, BundleType bundleType) {
+ public BundleType createBundleType(Subject subject, BundleType bundleType) throws Exception {
+ if (null == bundleType || null == bundleType.getName())
+ throw new IllegalArgumentException("Missing one or more of: bundleType, name");
+
entityManager.persist(bundleType);
return bundleType;
}
- public BundleVersion createBundleVersion(Subject subject, BundleVersion bundleVersion) {
+ public BundleVersion createBundleVersion(Subject subject, int bundleId, BundleVersion bundleVersion)
+ throws Exception {
+ Bundle bundle = entityManager.find(Bundle.class, bundleId);
+
+ if (null == bundleVersion || null == bundle || null == bundleVersion.getRecipe())
+ throw new IllegalArgumentException("Missing one or more of: bundle, bundleVersion, recipe");
+
+ // parse the recipe and get the config def and list of files
+ BundleServerPluginFacet bp;
+ // bp.parseRecipe;
+
entityManager.persist(bundleVersion);
return bundleVersion;
}
@@ -186,10 +194,16 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
public BundleType createMockBundleType(Subject subject) {
- ResourceType linuxPlatformResourceType = this.resourceTypeManager.getResourceTypeByNameAndPlugin("Linux",
- "Platforms");
- BundleType bundleType = new BundleType(UUID.randomUUID().toString(), linuxPlatformResourceType);
- return createBundleType(subject, bundleType);
+
+ try {
+ ResourceType linuxPlatformResourceType = this.resourceTypeManager.getResourceTypeByNameAndPlugin("Linux",
+ "Platforms");
+ BundleType bundleType = new BundleType(UUID.randomUUID().toString(), linuxPlatformResourceType);
+ return createBundleType(subject, bundleType);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
}
public Bundle createMockBundle(Subject subject, List<BundleType> bundleTypes) {
commit 74b491f9cc626a1fa2f603fb0a0dbb22343b0605
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Mar 1 14:42:07 2010 -0500
Add bundleFiles field to BundleVersion and update the criteria object.
Eliminate the getBundleFilesForBundleVersion convenience routine in favor
of a standard criteria fetch.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java
index 125baa7..b70c53d 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java
@@ -94,6 +94,9 @@ public class BundleVersion implements Serializable {
@OneToMany(mappedBy = "bundleVersion", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<BundleDeployDefinition> bundleDeployDefinitions = new ArrayList<BundleDeployDefinition>();
+ @OneToMany(mappedBy = "bundleVersion", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
+ private List<BundleFile> bundleFiles = new ArrayList<BundleFile>();
+
public BundleVersion() {
// for JPA use
}
@@ -182,6 +185,19 @@ public class BundleVersion implements Serializable {
this.bundleDeployDefinitions = bundleDeployDefinitions;
}
+ public List<BundleFile> getBundleFiles() {
+ return bundleFiles;
+ }
+
+ public void addBundleFile(BundleFile bundleFile) {
+ this.bundleFiles.add(bundleFile);
+ bundleFile.setBundleVersion(this);
+ }
+
+ public void setBundleFiles(List<BundleFile> bundleFiles) {
+ this.bundleFiles = bundleFiles;
+ }
+
@Override
public String toString() {
return "BundleVersion[id=" + id + ",name=" + name + ",version=" + version + ",bundle=" + bundle + "]";
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleVersionCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleVersionCriteria.java
index 72c07ed..5264a76 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleVersionCriteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleVersionCriteria.java
@@ -41,6 +41,7 @@ public class BundleVersionCriteria extends Criteria {
private boolean fetchBundle;
private boolean fetchBundleDeployDefinitions;
+ private boolean fetchBundleFiles;
private boolean fetchDistribution;
private boolean fetchConfigurationDefinition;
@@ -70,12 +71,16 @@ public class BundleVersionCriteria extends Criteria {
this.fetchBundle = fetchBundle;
}
- public void fetchDistribution(boolean fetchDistribution) {
- this.fetchDistribution = fetchDistribution;
- }
-
public void fetchBundleDeployDefinitions(boolean fetchBundleDeployDefinitions) {
this.fetchBundleDeployDefinitions = fetchBundleDeployDefinitions;
}
+ public void fetchBundleFiles(boolean fetchBundleFiles) {
+ this.fetchBundleFiles = fetchBundleFiles;
+ }
+
+ public void fetchDistribution(boolean fetchDistribution) {
+ this.fetchDistribution = fetchDistribution;
+ }
+
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
index 9266530..42f573d 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
@@ -26,7 +26,6 @@ import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleDeployment;
-import org.rhq.core.domain.bundle.BundleFile;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.criteria.BundleCriteria;
@@ -42,13 +41,28 @@ import org.rhq.core.domain.util.PageList;
*/
@Local
public interface BundleManagerLocal {
- Bundle createBundle(Subject subject, Bundle b);
- BundleType createBundleType(Subject subject, BundleType bundleType);
+ /**
+ * @param subject must be InventoryManager
+ * @param bundle required fields: name
+ * @return the persisted Bundle (id is assigned)
+ */
+ Bundle createBundle(Subject subject, Bundle bundle) throws Exception;
- BundleVersion createBundleVersion(Subject subject, BundleVersion bundleVersion);
+ /**
+ * @param subject must be InventoryManager
+ * @param bundleType required fields: name
+ * @return the persisted BundleType (id is assigned)
+ */
+ BundleType createBundleType(Subject subject, BundleType bundleType) throws Exception;
- List<BundleFile> findBundleFilesForBundleVersion(int bundleVersionId) throws Exception;
+ /**
+ * @param subject must be InventoryManager
+ * @param int bundleId the bundle for which this will be the next version
+ * @param bundleVersion required fields: recipe (the full recipe as a String)
+ * @return the persisted BundleVersion (id is assigned)
+ */
+ BundleVersion createBundleVersion(Subject subject, int bundleId, BundleVersion bundleVersion) throws Exception;
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java
index 09f4669..71d038c 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java
@@ -27,8 +27,11 @@ import org.apache.commons.logging.LogFactory;
import org.rhq.core.clientapi.server.bundle.BundleServerService;
import org.rhq.core.clientapi.server.bundle.BundleStatusUpdate;
+import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.BundleFile;
+import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.content.PackageVersion;
+import org.rhq.core.domain.criteria.BundleVersionCriteria;
import org.rhq.core.util.exception.WrappedRemotingException;
import org.rhq.enterprise.server.content.ContentSourceManagerLocal;
import org.rhq.enterprise.server.util.LookupUtil;
@@ -49,7 +52,12 @@ public class BundleServerServiceImpl implements BundleServerService {
public List<PackageVersion> getAllBundleVersionPackageVersions(int bundleVersionId) {
try {
BundleManagerLocal bm = LookupUtil.getBundleManager();
- List<BundleFile> bundleFiles = bm.findBundleFilesForBundleVersion(bundleVersionId);
+ BundleVersionCriteria c = new BundleVersionCriteria();
+ Subject subject = LookupUtil.getSubjectManager().getOverlord();
+ c.addFilterId(bundleVersionId);
+ c.fetchBundleFiles(true);
+ List<BundleVersion> bundleVersions = bm.findBundleVersionsByCriteria(subject, c);
+ List<BundleFile> bundleFiles = bundleVersions.get(0).getBundleFiles();
List<PackageVersion> packageVersions = new ArrayList<PackageVersion>(bundleFiles.size());
for (BundleFile bundleFile : bundleFiles) {
packageVersions.add(bundleFile.getPackageVersion());
commit 7f70926f340987e7808652cce688769dca1eac0e
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Mon Mar 1 14:27:00 2010 -0500
stub the useage of parse results
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java
index c810a97..ba53759 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java
@@ -40,13 +40,15 @@ public class RecipeParseResults {
/** The set of bundle files that make up the bundle (version) as specified in the recipe commands */
private Set<String> bundleFileNames;
- private RecipeParseResults(ConfigurationDefinition configDef, Set<String> bundleFileNames) {
+ public RecipeParseResults(ConfigurationDefinition configDef, Set<String> bundleFileNames) {
this.configDef = configDef;
this.bundleFileNames = bundleFileNames;
}
public ConfigurationDefinition getConfigDef() {
+
// stub out a test ConfigDef here until we actual parse the recipe
+ System.out.println("!!!!!! REMOVE THIS TEST CODE !!!!!!!!");
configDef = new ConfigurationDefinition("SampleBundle", "Stubbed ConfigDef for Sample Bundle");
configDef.put(new PropertyDefinitionSimple("sample.bundle.deploy.directory",
"Stubbed Property for deploy directory (must already exist on target platform)", true,
@@ -62,6 +64,7 @@ public class RecipeParseResults {
public Set<String> getBundleFileNames() {
// stub out a test set of BundleFiles here until we actual parse the recipe. For now lets just deploy
// a war file into an existing app server dir.
+ System.out.println("!!!!!! REMOVE THIS TEST CODE !!!!!!!!");
bundleFileNames = new HashSet<String>();
bundleFileNames.add("sample-bundle.war");
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 2bf4719..a2d6b96 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,12 +19,13 @@
package org.rhq.enterprise.server.plugin.pc.bundle;
+import org.rhq.enterprise.server.bundle.RecipeParseResults;
+
/**
* All bundle server plugins must implement this facet.
*
* @author John Mazzitelli
*/
public interface BundleServerPluginFacet {
- // TODO return something the server/jar SLSB likes
- void parseRecipe(String recipe) throws Exception;
+ RecipeParseResults parseRecipe(String recipe) throws Exception;
}
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 a1f770e..96f7070 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,9 +19,17 @@
package org.rhq.enterprise.server.plugins.filetemplate;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.bundle.filetemplate.recipe.RecipeContext;
import org.rhq.bundle.filetemplate.recipe.RecipeParser;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
+import org.rhq.enterprise.server.bundle.RecipeParseResults;
import org.rhq.enterprise.server.plugin.pc.ControlFacet;
import org.rhq.enterprise.server.plugin.pc.ControlResults;
import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
@@ -35,28 +43,38 @@ import org.rhq.enterprise.server.plugin.pc.bundle.BundleServerPluginFacet;
*/
public class BundleServerPluginComponent implements ServerPluginComponent, BundleServerPluginFacet, ControlFacet {
+ private final Log log = LogFactory.getLog(BundleServerPluginComponent.class);
+
private ServerPluginContext context;
public void initialize(ServerPluginContext context) throws Exception {
this.context = context;
- System.out.println("The filetemplate bundle plugin has been initialized!!! : " + this);
+ log.debug("The filetemplate bundle plugin has been initialized!!! : " + this);
}
public void start() {
- System.out.println("The filetemplate bundle plugin has started!!! : " + this);
+ log.debug("The filetemplate bundle plugin has started!!! : " + this);
}
public void stop() {
- System.out.println("The filetemplate bundle plugin has stopped!!! : " + this);
+ log.debug("The filetemplate bundle plugin has stopped!!! : " + this);
}
public void shutdown() {
- System.out.println("The filetemplate bundle plugin has been shut down!!! : " + this);
+ log.debug("The filetemplate bundle plugin has been shut down!!! : " + this);
}
- public void parseRecipe(String recipe) throws Exception {
+ public RecipeParseResults parseRecipe(String recipe) throws Exception {
RecipeParser parser = new RecipeParser();
- parser.parseRecipe(recipe);
+ RecipeContext parserContext = parser.parseRecipe(recipe);
+
+ // TODO convert the context to the results object
+ ConfigurationDefinition configDef = null;
+ Set<String> bundleFileNames = null;
+
+ RecipeParseResults results = new RecipeParseResults(configDef, bundleFileNames);
+ return results;
+
}
public ControlResults invoke(String name, Configuration parameters) {
commit 7210b1f604f74ac9e384715a84f7ef0fc785fcfa
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Mon Mar 1 13:57:49 2010 -0500
first stubbed version of the commons filetemplate bundle commons lib
diff --git a/.classpath b/.classpath
index bb17f97..c6a1ed2 100644
--- a/.classpath
+++ b/.classpath
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="modules/common/jboss-as/src/main/java"/>
+ <classpathentry kind="src" path="modules/common/filetemplate-bundle/src/main/java"/>
+ <classpathentry kind="src" path="modules/common/filetemplate-bundle/src/test/java"/>
<classpathentry kind="src" path="modules/enterprise/gui/base-perspective-jar/src/main/java"/>
<classpathentry kind="src" path="modules/enterprise/server/plugins/jboss-software/src/test/java"/>
<classpathentry kind="src" path="modules/enterprise/server/plugins/jboss-software/src/main/java"/>
diff --git a/etc/eclipse-tools/maven/RHQ Maven Build and Test - Plugin Common Libraries.launch b/etc/eclipse-tools/maven/RHQ Maven Build and Test - Plugin Common Libraries.launch
new file mode 100644
index 0000000..34c8c3d
--- /dev/null
+++ b/etc/eclipse-tools/maven/RHQ Maven Build and Test - Plugin Common Libraries.launch
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.ui.externaltools.ProgramLaunchConfigurationType">
+<stringAttribute key="bad_container_name" value="\rhq\etc\eclipse-tools\maven"/>
+<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
+<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
+<listEntry value="org.eclipse.ui.externaltools.launchGroup"/>
+</listAttribute>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${env_var:M2_HOME}/bin/${MAVEN_EXE}"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="-o -Dmaven.test.skip=false install"/>
+<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/rhq/modules/common}"/>
+</launchConfiguration>
diff --git a/modules/common/filetemplate-bundle/pom.xml b/modules/common/filetemplate-bundle/pom.xml
new file mode 100644
index 0000000..e6a3107
--- /dev/null
+++ b/modules/common/filetemplate-bundle/pom.xml
@@ -0,0 +1,37 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-common-parent</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-filetemplate-bundle-common</artifactId>
+ <packaging>jar</packaging>
+
+ <name>RHQ File Template Bundle Plugins Common Library</name>
+ <description>A library with the code common to the agent and server plugins for File Template Bundles</description>
+
+ <scm>
+ <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/common/filetemplat...</connection>
+ <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/common/filetemplat...</developerConnection>
+ </scm>
+
+ <properties>
+ <scm.module.path>modules/common/filetemplate-bundle/</scm.module.path>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>gnu-getopt</groupId>
+ <artifactId>getopt</artifactId>
+ <!-- NOTE: The version is defined in the root POM's dependencyManagement section. -->
+ </dependency>
+
+ </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java
new file mode 100644
index 0000000..057d474
--- /dev/null
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/ConfigdefRecipeCommand.java
@@ -0,0 +1,69 @@
+/*
+ * 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, 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.bundle.filetemplate.recipe;
+
+import gnu.getopt.Getopt;
+import gnu.getopt.LongOpt;
+
+public class ConfigdefRecipeCommand implements RecipeCommand {
+
+ public String getName() {
+ return "configdef";
+ }
+
+ public void parse(RecipeContext context, String[] args) {
+ String sopts = ":f:";
+ LongOpt[] lopts = { new LongOpt("file", LongOpt.REQUIRED_ARGUMENT, null, 'f') };
+
+ String filename = null;
+
+ Getopt getopt = new Getopt(context.toString(), args, sopts, lopts);
+ int code;
+
+ while ((code = getopt.getopt()) != -1) {
+ switch (code) {
+ case ':':
+ case '?': {
+ throw new IllegalArgumentException("Bad recipe command [" + getName() + "]: " + args);
+ }
+
+ case 1: {
+ throw new IllegalArgumentException("Bad recipe command [" + getName() + "]: " + args);
+ }
+
+ case 'f': {
+ filename = getopt.getOptarg();
+ break;
+ }
+
+ default: {
+ throw new IllegalArgumentException("Unexpected error in recipe command [" + getName() + "]: " + args);
+ }
+
+ }
+ }
+
+ // TODO : do something with filename
+ }
+}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java
new file mode 100644
index 0000000..145398c
--- /dev/null
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/DeployRecipeCommand.java
@@ -0,0 +1,76 @@
+/*
+ * 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, 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.bundle.filetemplate.recipe;
+
+import gnu.getopt.Getopt;
+import gnu.getopt.LongOpt;
+
+public class DeployRecipeCommand implements RecipeCommand {
+
+ public String getName() {
+ return "deploy";
+ }
+
+ public void parse(RecipeContext context, String[] args) {
+ String sopts = ":f:d:";
+ LongOpt[] lopts = { new LongOpt("file", LongOpt.REQUIRED_ARGUMENT, null, 'f'),
+ new LongOpt("directory", LongOpt.REQUIRED_ARGUMENT, null, 'd') };
+
+ String filename = null;
+ String directory = null;
+
+ Getopt getopt = new Getopt(context.toString(), args, sopts, lopts);
+ int code;
+
+ while ((code = getopt.getopt()) != -1) {
+ switch (code) {
+ case ':':
+ case '?': {
+ throw new IllegalArgumentException("Bad recipe command [" + getName() + "]: " + args);
+ }
+
+ case 1: {
+ throw new IllegalArgumentException("Bad recipe command [" + getName() + "]: " + args);
+ }
+
+ case 'f': {
+ filename = getopt.getOptarg();
+ break;
+ }
+
+ case 'd': {
+ directory = getopt.getOptarg();
+ break;
+ }
+
+ default: {
+ throw new IllegalArgumentException("Unexpected error in recipe command [" + getName() + "]: " + args);
+ }
+
+ }
+ }
+
+ // TODO : do something with filename and directory
+ }
+}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeCommand.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeCommand.java
new file mode 100644
index 0000000..7cfa964
--- /dev/null
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeCommand.java
@@ -0,0 +1,42 @@
+/*
+ * 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, 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.bundle.filetemplate.recipe;
+
+public interface RecipeCommand {
+
+ /**
+ * The name of the recipe command. This must be the first word in the recipe line in order for this command to be triggered.
+ *
+ * @return name of the recipe command
+ */
+ String getName();
+
+ /**
+ * Parses this recipe command and optionally puts information in the context.
+ *
+ * @param context information where the parser can store information regarding the command that was processed
+ * @param args arguments passed to the command.
+ */
+ void parse(RecipeContext context, String[] args);
+}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
new file mode 100644
index 0000000..da96ceb
--- /dev/null
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeContext.java
@@ -0,0 +1,45 @@
+/*
+ * 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, 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.bundle.filetemplate.recipe;
+
+/**
+ * @author John Mazzitelli
+ */
+public class RecipeContext {
+
+ private final String recipe;
+
+ public RecipeContext(String recipe) {
+ this.recipe = recipe;
+ }
+
+ /**
+ * The full recipe that this context represents.
+ *
+ * @return the actual recipe text
+ */
+ public String getRecipe() {
+ return recipe;
+ }
+}
diff --git a/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
new file mode 100644
index 0000000..ff9b91f
--- /dev/null
+++ b/modules/common/filetemplate-bundle/src/main/java/org/rhq/bundle/filetemplate/recipe/RecipeParser.java
@@ -0,0 +1,127 @@
+/*
+ * 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, 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.bundle.filetemplate.recipe;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.StreamTokenizer;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Parses the file template recipe.
+ *
+ * @author John Mazzitelli
+ *
+ */
+public class RecipeParser {
+ private Map<String, RecipeCommand> recipeCommands;
+
+ public RecipeParser() {
+ setupRecipeCommands();
+ }
+
+ public RecipeContext parseRecipe(String recipe) throws Exception {
+ RecipeContext context = new RecipeContext(recipe);
+
+ BufferedReader recipeReader = new BufferedReader(new StringReader(recipe));
+ String line = recipeReader.readLine();
+ while (line != null) {
+ String[] commandLineArray = splitCommandLine(line);
+ String commandName = commandLineArray[0];
+ String[] arguments = extractArguments(commandLineArray);
+
+ RecipeCommand recipeCommand = recipeCommands.get(commandName);
+ if (recipeCommand == null) {
+ throw new Exception("Unknown command in recipe: " + commandName);
+ }
+
+ recipeCommand.parse(context, arguments);
+
+ line = recipeReader.readLine();
+ }
+
+ return context;
+ }
+
+ private void setupRecipeCommands() {
+ recipeCommands = new HashMap<String, RecipeCommand>();
+
+ RecipeCommand[] knownCommands = new RecipeCommand[] { new ConfigdefRecipeCommand(), //
+ new DeployRecipeCommand() //
+ };
+
+ for (RecipeCommand recipeCommand : knownCommands) {
+ recipeCommands.put(recipeCommand.getName(), recipeCommand);
+ }
+ }
+
+ private String[] splitCommandLine(String cmdLine) {
+ ByteArrayInputStream in = new ByteArrayInputStream(cmdLine.getBytes());
+ StreamTokenizer strtok = new StreamTokenizer(new InputStreamReader(in));
+ List<String> args = new ArrayList<String>();
+ boolean keep_going = true;
+
+ // we don't want to parse numbers and we want ' to be a normal word character
+ strtok.ordinaryChars('0', '9');
+ strtok.ordinaryChar('.');
+ strtok.ordinaryChar('-');
+ strtok.ordinaryChar('\'');
+ strtok.wordChars(33, 127);
+ strtok.quoteChar('\"');
+
+ // parse the command line
+ while (keep_going) {
+ int nextToken;
+
+ try {
+ nextToken = strtok.nextToken();
+ } catch (IOException e) {
+ nextToken = StreamTokenizer.TT_EOF;
+ }
+
+ if (nextToken == java.io.StreamTokenizer.TT_WORD) {
+ args.add(strtok.sval);
+ } else if (nextToken == '\"') {
+ args.add(strtok.sval);
+ } else if ((nextToken == java.io.StreamTokenizer.TT_EOF) || (nextToken == java.io.StreamTokenizer.TT_EOL)) {
+ keep_going = false;
+ }
+ }
+
+ return args.toArray(new String[args.size()]);
+ }
+
+ private String[] extractArguments(String[] commandLine) {
+ // strip the first element (the command name) from the array, leaving only the arguments
+ int newLength = commandLine.length - 1;
+ String[] argsOnly = new String[newLength];
+ System.arraycopy(commandLine, 1, argsOnly, 0, newLength);
+ return argsOnly;
+ }
+}
diff --git a/modules/common/pom.xml b/modules/common/pom.xml
index e9f0385..8abfe11 100644
--- a/modules/common/pom.xml
+++ b/modules/common/pom.xml
@@ -66,5 +66,6 @@
<modules>
<module>jboss-as</module>
+ <module>filetemplate-bundle</module>
</modules>
</project>
\ No newline at end of file
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 0585a4b..2bf4719 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
@@ -25,5 +25,6 @@ package org.rhq.enterprise.server.plugin.pc.bundle;
* @author John Mazzitelli
*/
public interface BundleServerPluginFacet {
-
+ // TODO return something the server/jar SLSB likes
+ void parseRecipe(String recipe) throws Exception;
}
diff --git a/modules/enterprise/server/plugins/filetemplate-bundle/pom.xml b/modules/enterprise/server/plugins/filetemplate-bundle/pom.xml
index 7a19819..4a3536e 100644
--- a/modules/enterprise/server/plugins/filetemplate-bundle/pom.xml
+++ b/modules/enterprise/server/plugins/filetemplate-bundle/pom.xml
@@ -42,6 +42,12 @@
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-filetemplate-bundle-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
<!-- 3rd Party Deps -->
<!-- TODO: This is a fix for the Javac bug requiring annotations to be
@@ -71,11 +77,37 @@
<configuration>
<excludedGroups>${rhq.testng.excludedGroups}</excludedGroups>
<!--
- <argLine>-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y</argLine>
+ <argLine>-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y</argLine>
-->
</configuration>
</plugin>
+ <plugin>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.0</version>
+ <executions>
+ <execution>
+ <id>copy-rhq-plugins</id>
+ <phase>process-resources</phase>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-filetemplate-bundle-common</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ </artifactItems>
+ <outputDirectory>${project.build.outputDirectory}/lib</outputDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
</plugins>
</build>
@@ -141,7 +173,8 @@
<include name="META-INF/**" />
</patternset>
</unjar>
- <jar destfile="${deployment.file}" manifest="${project.build.outputDirectory}/META-INF/MANIFEST.MF" update="true">
+ <jar destfile="${deployment.file}" manifest="${project.build.outputDirectory}/META-INF/MANIFEST.MF"
+ update="true">
</jar>
</tasks>
</configuration>
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 58dd5b1..a1f770e 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 org.rhq.bundle.filetemplate.recipe.RecipeParser;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.enterprise.server.plugin.pc.ControlFacet;
@@ -53,6 +54,11 @@ public class BundleServerPluginComponent implements ServerPluginComponent, Bundl
System.out.println("The filetemplate bundle plugin has been shut down!!! : " + this);
}
+ public void parseRecipe(String recipe) throws Exception {
+ RecipeParser parser = new RecipeParser();
+ parser.parseRecipe(recipe);
+ }
+
public ControlResults invoke(String name, Configuration parameters) {
ControlResults controlResults = new ControlResults();
if (name.equals("testControl")) {
diff --git a/modules/plugins/filetemplate-bundle/pom.xml b/modules/plugins/filetemplate-bundle/pom.xml
index b1f18b5..93f1c4c 100644
--- a/modules/plugins/filetemplate-bundle/pom.xml
+++ b/modules/plugins/filetemplate-bundle/pom.xml
@@ -26,13 +26,17 @@
<dependencies>
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-filetemplate-bundle-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
</dependencies>
<build>
<plugins>
- <!--
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.0</version>
@@ -47,9 +51,9 @@
<artifactItems>
<artifactItem>
- <groupId>org.jboss</groupId>
- <artifactId>byteman</artifactId>
- <version>1.2.0</version>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-filetemplate-bundle-common</artifactId>
+ <version>${project.version}</version>
</artifactItem>
</artifactItems>
@@ -58,7 +62,6 @@
</execution>
</executions>
</plugin>
- -->
</plugins>
</build>
commit 47723277426d7e582828b2bc45316edbdd005195
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Mar 1 13:55:48 2010 -0500
initial version with some stubbed return values for testing
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java
new file mode 100644
index 0000000..c810a97
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/RecipeParseResults.java
@@ -0,0 +1,75 @@
+/*
+ * 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.util.HashSet;
+import java.util.Set;
+
+import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
+import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
+import org.rhq.core.domain.configuration.definition.PropertySimpleType;
+
+/**
+ * This class is general to all Bundle handling server side plugins. It is returned by the SSP when parsing
+ * a bundle's recipe and contains all of the information neded to create a bundle version.
+ *
+ * @author jay shaughnessy
+ */
+public class RecipeParseResults {
+
+ /** The configuration definition parsed out of, or expcitly provided by, the recipe */
+ private ConfigurationDefinition configDef;
+
+ /** The set of bundle files that make up the bundle (version) as specified in the recipe commands */
+ private Set<String> bundleFileNames;
+
+ private RecipeParseResults(ConfigurationDefinition configDef, Set<String> bundleFileNames) {
+ this.configDef = configDef;
+ this.bundleFileNames = bundleFileNames;
+ }
+
+ public ConfigurationDefinition getConfigDef() {
+ // stub out a test ConfigDef here until we actual parse the recipe
+ configDef = new ConfigurationDefinition("SampleBundle", "Stubbed ConfigDef for Sample Bundle");
+ configDef.put(new PropertyDefinitionSimple("sample.bundle.deploy.directory",
+ "Stubbed Property for deploy directory (must already exist on target platform)", true,
+ PropertySimpleType.STRING));
+
+ return configDef;
+ }
+
+ public void setConfigDef(ConfigurationDefinition configDef) {
+ this.configDef = configDef;
+ }
+
+ public Set<String> getBundleFileNames() {
+ // stub out a test set of BundleFiles here until we actual parse the recipe. For now lets just deploy
+ // a war file into an existing app server dir.
+ bundleFileNames = new HashSet<String>();
+ bundleFileNames.add("sample-bundle.war");
+
+ return bundleFileNames;
+ }
+
+ public void setBundleFiles(Set<String> bundleFileNames) {
+ this.bundleFileNames = bundleFileNames;
+ }
+
+}
commit 007fe3b4708ebeb2953b0dd8482b02d1f558993a
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Mon Mar 1 10:12:52 2010 -0500
remove circular dep - plugin api should never dep on pc module
introduct new bundle manager provider interface that plugins will use to callback into the PC bundle manager
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployRequest.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployRequest.java
index 40e663b..2dd6e6d 100644
--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployRequest.java
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployRequest.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2009 Red Hat, Inc.
+ * Copyright (C) 2005-2010 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -22,7 +22,6 @@ package org.rhq.core.pluginapi.bundle;
import java.io.Serializable;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
-import org.rhq.core.pc.bundle.BundleManager;
/**
* A request to deploy a bundle.
@@ -33,7 +32,7 @@ public class BundleDeployRequest implements Serializable {
private static final long serialVersionUID = 1L;
private BundleDeployDefinition bundleDeployDefinition;
- private BundleManager bundleManager;
+ private BundleManagerProvider bundleManager;
public BundleDeployDefinition getBundleDeployDefinition() {
return bundleDeployDefinition;
@@ -43,12 +42,12 @@ public class BundleDeployRequest implements Serializable {
this.bundleDeployDefinition = bundleDeployDefinition;
}
- public BundleManager getBundleManager() {
+ public BundleManagerProvider getBundleManagerProvider() {
return bundleManager;
}
- public void setBundleManager(BundleManager bundleManager) {
- this.bundleManager = bundleManager;
+ public void setBundleManagerProvider(BundleManagerProvider provider) {
+ this.bundleManager = provider;
}
}
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
new file mode 100644
index 0000000..d06561f
--- /dev/null
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleManagerProvider.java
@@ -0,0 +1,52 @@
+/*
+ * 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.core.pluginapi.bundle;
+
+import java.io.OutputStream;
+import java.util.List;
+
+import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.content.PackageVersion;
+
+/**
+ * Provides bundle functionality that plugin components will need in order to process bundles.
+ *
+ * @author John Mazzitelli
+ */
+public interface BundleManagerProvider {
+ /**
+ * Bndle plugins call back into this manager to obtain the bundle files that belong to a given bundle version.
+ *
+ * @param bundleVersion
+ * @return the bundle files that are associated with the given bundle
+ * @throws Exception
+ */
+ List<PackageVersion> getAllBundleVersionPackageVersions(BundleVersion bundleVersion) throws Exception;
+
+ /**
+ * Bundle plugins call back into this manager to obtain the bundle file content for the given package.
+ *
+ * @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
+ */
+ 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 6f6eed5..5db906f 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
@@ -50,6 +50,7 @@ import org.rhq.core.pc.util.FacetLockType;
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;
/**
* Manages the bundle subsystem, which allows bundles of content to be installed.
@@ -58,7 +59,7 @@ import org.rhq.core.pluginapi.bundle.BundleFacet;
*
* @author John Mazzitelli
*/
-public class BundleManager extends AgentService implements BundleAgentService, ContainerService {
+public class BundleManager extends AgentService implements BundleAgentService, BundleManagerProvider, ContainerService {
private final Log log = LogFactory.getLog(BundleManager.class);
private PluginContainerConfiguration configuration;
@@ -99,7 +100,7 @@ public class BundleManager extends AgentService implements BundleAgentService, C
// deploy the bundle utilizing the bundle facet object
BundleDeployRequest deployRequest = new BundleDeployRequest();
- deployRequest.setBundleManager(this);
+ deployRequest.setBundleManagerProvider(this);
deployRequest.setBundleDeployDefinition(request.getBundleDeployDefinition());
BundleDeployResult result = bundlePluginComponent.deployBundle(deployRequest);
if (!result.isSuccess()) {
@@ -113,29 +114,12 @@ public class BundleManager extends AgentService implements BundleAgentService, C
return response;
}
- /**
- * This is used by bundle plugins - bundle plugins call back into this manager to obtain the
- * bundle files that belong to a given bundle version.
- *
- * @param bundleVersion
- * @return the bundle files that are associated with the given bundle
- * @throws Exception
- */
public List<PackageVersion> getAllBundleVersionPackageVersions(BundleVersion bundleVersion) throws Exception {
int bvId = bundleVersion.getId();
List<PackageVersion> pvs = getBundleServerService().getAllBundleVersionPackageVersions(bvId);
return pvs;
}
- /**
- * This is used by bundle plugins - bundle plugins call back into this manager to obtain the
- * bundle file content for the given package.
- *
- * @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
- */
public long getFileContent(PackageVersion packageVersion, OutputStream outputStream) throws Exception {
long size = getBundleServerService().downloadPackageBits(packageVersion, outputStream);
return size;
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
index d8ac092..a1320ad 100644
--- a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
@@ -30,10 +30,10 @@ import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.measurement.AvailabilityType;
-import org.rhq.core.pc.bundle.BundleManager;
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.util.MessageDigestGenerator;
@@ -59,7 +59,6 @@ public class FileTemplateBundlePluginServerComponent implements ResourceComponen
return AvailabilityType.UP;
}
- @Override
public BundleDeployResult deployBundle(BundleDeployRequest request) {
BundleDeployResult result = new BundleDeployResult();
try {
@@ -68,7 +67,7 @@ public class FileTemplateBundlePluginServerComponent implements ResourceComponen
// download all the bundle files to our tmp directory
File tmpDir = new File(this.resourceContext.getTemporaryDirectory(), "" + bundleVersion.getId());
- BundleManager bundleManager = request.getBundleManager();
+ BundleManagerProvider bundleManager = request.getBundleManagerProvider();
List<PackageVersion> packageVersions = bundleManager.getAllBundleVersionPackageVersions(bundleVersion);
for (PackageVersion packageVersion : packageVersions) {
File packageFile = new File(tmpDir, packageVersion.getFileName());
commit fc813fe40f25db9ce1924d259923df095f51ff18
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 26 14:27:11 2010 -0500
file template bundle can download bundle files and verify them
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
index a7100ec..d8ac092 100644
--- a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
@@ -18,15 +18,25 @@
*/
package org.rhq.plugins.filetemplate;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.util.List;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.rhq.core.domain.bundle.BundleDeployDefinition;
+import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.pc.bundle.BundleManager;
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.inventory.ResourceComponent;
import org.rhq.core.pluginapi.inventory.ResourceContext;
+import org.rhq.core.util.MessageDigestGenerator;
/**
* @author John Mazzitelli
@@ -51,8 +61,62 @@ public class FileTemplateBundlePluginServerComponent implements ResourceComponen
@Override
public BundleDeployResult deployBundle(BundleDeployRequest request) {
- // TODO
BundleDeployResult result = new BundleDeployResult();
+ try {
+ BundleDeployDefinition bundleDeployDef = request.getBundleDeployDefinition();
+ BundleVersion bundleVersion = bundleDeployDef.getBundleVersion();
+
+ // download all the bundle files to our tmp directory
+ File tmpDir = new File(this.resourceContext.getTemporaryDirectory(), "" + bundleVersion.getId());
+ BundleManager bundleManager = request.getBundleManager();
+ List<PackageVersion> packageVersions = bundleManager.getAllBundleVersionPackageVersions(bundleVersion);
+ for (PackageVersion packageVersion : packageVersions) {
+ File packageFile = new File(tmpDir, packageVersion.getFileName());
+ packageFile.getParentFile().mkdirs();
+ FileOutputStream fos = new FileOutputStream(packageFile);
+ try {
+ long size = bundleManager.getFileContent(packageVersion, fos);
+ if (packageVersion.getFileSize() != null && size != packageVersion.getFileSize().longValue()) {
+ log.warn("Downloaded bundle file [" + packageVersion + "] but its size was [" + size
+ + "] when it was expected to be [" + packageVersion.getFileSize() + "].");
+ }
+ } finally {
+ fos.close();
+ }
+
+ // verify the content
+ if (packageVersion.getMD5() != null) {
+ String realMD5 = MessageDigestGenerator.getDigestString(packageFile);
+ if (!packageVersion.getMD5().equals(realMD5)) {
+ throw new Exception("Package version [" + packageVersion + "] failed MD5 check. expected=["
+ + packageVersion.getMD5() + "], actual=[" + realMD5 + "]");
+ }
+ } else if (packageVersion.getSHA256() != null) {
+ FileInputStream is = new FileInputStream(packageFile);
+ try {
+ MessageDigestGenerator gen = new MessageDigestGenerator("SHA256");
+ gen.add(is);
+ String realSHA256 = gen.getDigestString();
+ if (!packageVersion.getSHA256().equals(realSHA256)) {
+ throw new Exception("Package version [" + packageVersion
+ + "] failed SHA256 check. expected=[" + packageVersion.getSHA256() + "], actual=["
+ + realSHA256 + "]");
+ }
+ } finally {
+ is.close();
+ }
+
+ } else {
+ log.debug("Package version [" + packageVersion + "] has no MD5/SHA256 hash - not verifying it");
+ }
+ }
+
+ // TODO all bundle files are downloaded - now process the bundle
+
+ } catch (Throwable t) {
+ log.error("Failed to deploy bundle [" + request + "]", t);
+ result.setErrorMessage(t);
+ }
return result;
}
}
commit 0870cc72f3e8321e5e633fdb6221bad4cf92d2dd
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 26 12:50:20 2010 -0500
opps.. typo
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 abbef53..6f6eed5 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
@@ -137,7 +137,7 @@ public class BundleManager extends AgentService implements BundleAgentService, C
* @throws Exception
*/
public long getFileContent(PackageVersion packageVersion, OutputStream outputStream) throws Exception {
- long size = getBundleServerService().downloadPackageBitsGivenResource(packageVersion, outputStream);
+ long size = getBundleServerService().downloadPackageBits(packageVersion, outputStream);
return size;
}
commit 632be079062b309fe0f9e02b9553c6eb5a91304b
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 26 12:28:52 2010 -0500
API for agent plugin to ask for bundle file content
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleServerService.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleServerService.java
index eb09a4e..dbc0555 100644
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleServerService.java
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleServerService.java
@@ -22,10 +22,14 @@
*/
package org.rhq.core.clientapi.server.bundle;
+import java.io.OutputStream;
import java.util.List;
+import org.rhq.core.clientapi.server.content.ContentServerService;
import org.rhq.core.communications.command.annotation.Asynchronous;
-import org.rhq.core.domain.bundle.BundleFile;
+import org.rhq.core.communications.command.annotation.LimitedConcurrency;
+import org.rhq.core.communications.command.annotation.Timeout;
+import org.rhq.core.domain.content.PackageVersion;
/**
* Interface for agents to use when needing to inform the server about bundle tasks. Implementations of this interface, once registered with the
@@ -38,5 +42,21 @@ public interface BundleServerService {
@Asynchronous(guaranteedDelivery = true)
void updateStatus(BundleStatusUpdate update);
- List<BundleFile> getAllBundleFiles(int bundleVersionId);
+ List<PackageVersion> getAllBundleVersionPackageVersions(int bundleVersionId);
+
+ /**
+ * Requests that the server download and stream the bits for the specified package version.
+ * If the package cannot be found, an exception will be thrown.
+ *
+ * @param packageVersion identifies the package to download
+ * @param outputStream an output stream where the server should write the package contents. It is up to the
+ * caller to prepare this output stream in order to write the package content to an
+ * appropriate location.
+ *
+ * @return the number of bytes written to the output stream - this is the size of the package version that was
+ * downloaded
+ */
+ @Timeout(45 * 60 * 1000L)
+ @LimitedConcurrency(ContentServerService.CONCURRENCY_LIMIT_CONTENT_DOWNLOAD)
+ long downloadPackageBits(PackageVersion packageVersion, OutputStream outputStream);
}
\ No newline at end of file
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 4ab1c03..abbef53 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
@@ -22,6 +22,7 @@
*/
package org.rhq.core.pc.bundle;
+import java.io.OutputStream;
import java.util.List;
import java.util.Set;
@@ -34,9 +35,9 @@ import org.rhq.core.clientapi.agent.bundle.BundleScheduleRequest;
import org.rhq.core.clientapi.agent.bundle.BundleScheduleResponse;
import org.rhq.core.clientapi.server.bundle.BundleServerService;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
-import org.rhq.core.domain.bundle.BundleFile;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.pc.ContainerService;
@@ -120,9 +121,24 @@ public class BundleManager extends AgentService implements BundleAgentService, C
* @return the bundle files that are associated with the given bundle
* @throws Exception
*/
- public List<BundleFile> getAllBundleFiles(BundleVersion bundleVersion) throws Exception {
- List<BundleFile> bundleFiles = getBundleServerService().getAllBundleFiles(bundleVersion.getId());
- return bundleFiles;
+ public List<PackageVersion> getAllBundleVersionPackageVersions(BundleVersion bundleVersion) throws Exception {
+ int bvId = bundleVersion.getId();
+ List<PackageVersion> pvs = getBundleServerService().getAllBundleVersionPackageVersions(bvId);
+ return pvs;
+ }
+
+ /**
+ * This is used by bundle plugins - bundle plugins call back into this manager to obtain the
+ * bundle file content for the given package.
+ *
+ * @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
+ */
+ public long getFileContent(PackageVersion packageVersion, OutputStream outputStream) throws Exception {
+ long size = getBundleServerService().downloadPackageBitsGivenResource(packageVersion, outputStream);
+ return size;
}
/**
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 747b980..ce559bf 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
@@ -35,6 +35,7 @@ import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleDeployment;
+import org.rhq.core.domain.bundle.BundleFile;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.content.Repo;
@@ -71,6 +72,14 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
@EJB
private ResourceTypeManagerLocal resourceTypeManager;
+ @SuppressWarnings("unchecked")
+ public List<BundleFile> findBundleFilesForBundleVersion(int bundleVersionId) throws Exception {
+ Query q = entityManager.createNamedQuery(BundleFile.QUERY_FIND_BY_BUNDLE_VERSION_ID);
+ q.setParameter("id", bundleVersionId);
+ List<BundleFile> bundleFiles = (List<BundleFile>) q.getResultList();
+ return bundleFiles;
+ }
+
public Bundle createBundle(Subject subject, Bundle bundle) {
// add the implicit bundle repo, if necessary
if (null == bundle.getRepo()) {
@@ -80,6 +89,8 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
bundle.setRepo(repo);
}
+ log.info("Creating bundle: " + bundle);
+
entityManager.persist(bundle);
return bundle;
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
index 9cfc099..9266530 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
@@ -26,6 +26,7 @@ import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleDeployment;
+import org.rhq.core.domain.bundle.BundleFile;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.criteria.BundleCriteria;
@@ -47,6 +48,8 @@ public interface BundleManagerLocal {
BundleVersion createBundleVersion(Subject subject, BundleVersion bundleVersion);
+ List<BundleFile> findBundleFilesForBundleVersion(int bundleVersionId) throws Exception;
+
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
// The remaining methods are shared with the Remote Interface.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java
index fa84821..09f4669 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java
@@ -18,6 +18,8 @@
*/
package org.rhq.enterprise.server.bundle;
+import java.io.OutputStream;
+import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
@@ -26,6 +28,10 @@ import org.apache.commons.logging.LogFactory;
import org.rhq.core.clientapi.server.bundle.BundleServerService;
import org.rhq.core.clientapi.server.bundle.BundleStatusUpdate;
import org.rhq.core.domain.bundle.BundleFile;
+import org.rhq.core.domain.content.PackageVersion;
+import org.rhq.core.util.exception.WrappedRemotingException;
+import org.rhq.enterprise.server.content.ContentSourceManagerLocal;
+import org.rhq.enterprise.server.util.LookupUtil;
/**
* Server-side implementation of the <code>BundleServerService</code>. This implmentation simply forwards
@@ -40,7 +46,29 @@ public class BundleServerServiceImpl implements BundleServerService {
// TODO Auto-generated method stub
}
- public List<BundleFile> getAllBundleFiles(int bundleVersionId) {
- return null;
+ public List<PackageVersion> getAllBundleVersionPackageVersions(int bundleVersionId) {
+ try {
+ BundleManagerLocal bm = LookupUtil.getBundleManager();
+ List<BundleFile> bundleFiles = bm.findBundleFilesForBundleVersion(bundleVersionId);
+ List<PackageVersion> packageVersions = new ArrayList<PackageVersion>(bundleFiles.size());
+ for (BundleFile bundleFile : bundleFiles) {
+ packageVersions.add(bundleFile.getPackageVersion());
+ }
+ return packageVersions;
+ } catch (Exception e) {
+ log.error("Failed to obtain bundle files for bundle version id: " + bundleVersionId, e);
+ throw new WrappedRemotingException(e);
+ }
+ }
+
+ public long downloadPackageBits(PackageVersion packageVersion, OutputStream outputStream) {
+ try {
+ ContentSourceManagerLocal csm = LookupUtil.getContentSourceManager();
+ long size = csm.outputPackageVersionBits(packageVersion, outputStream);
+ return size;
+ } catch (Exception e) {
+ log.error("Failed to obtain package version bits for package version: " + packageVersion, e);
+ throw new WrappedRemotingException(e);
+ }
}
}
\ No newline at end of file
commit f96e2404b6596f030fdc1d4d54a6a4d0a6c8e36e
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 26 10:20:49 2010 -0500
starting agent side bundle deployment stuff - not even close to useful yet
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleAgentService.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleAgentService.java
index 2e0f2f2..345567f 100644
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleAgentService.java
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleAgentService.java
@@ -30,5 +30,10 @@ package org.rhq.core.clientapi.agent.bundle;
* @author John Mazzitelli
*/
public interface BundleAgentService {
- BundleUpdateResponse update(BundleUpdateRequest request);
+ /**
+ * Schedules the deployment of a bundle to occur immediately.
+ * @param request
+ * @return the results of the immediate scheduling
+ */
+ BundleScheduleResponse schedule(BundleScheduleRequest request);
}
\ No newline at end of file
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleScheduleRequest.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleScheduleRequest.java
new file mode 100644
index 0000000..0b49cd7
--- /dev/null
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleScheduleRequest.java
@@ -0,0 +1,56 @@
+/*
+ * 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, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.rhq.core.clientapi.agent.bundle;
+
+import java.io.Serializable;
+
+import org.rhq.core.domain.bundle.BundleDeployDefinition;
+
+/**
+ * @author John Mazzitelli
+ */
+public class BundleScheduleRequest implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private BundleDeployDefinition bundleDeployDefinition;
+
+ public BundleScheduleRequest(BundleDeployDefinition bundleDef) {
+ this.bundleDeployDefinition = bundleDef;
+ }
+
+ public BundleDeployDefinition getBundleDeployDefinition() {
+ return bundleDeployDefinition;
+ }
+
+ public void setBundleDeployDefinition(BundleDeployDefinition bundleDeployDefinition) {
+ this.bundleDeployDefinition = bundleDeployDefinition;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder str = new StringBuilder(this.getClass() + ": ");
+ str.append(bundleDeployDefinition.toString());
+ return str.toString();
+ }
+}
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleScheduleResponse.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleScheduleResponse.java
new file mode 100644
index 0000000..a82e866
--- /dev/null
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleScheduleResponse.java
@@ -0,0 +1,66 @@
+/*
+ * 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, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.rhq.core.clientapi.agent.bundle;
+
+import java.io.Serializable;
+
+import org.rhq.core.util.exception.ThrowableUtil;
+
+/**
+ * @author John Mazzitelli
+ */
+public class BundleScheduleResponse implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private String errorMessage;
+
+ public BundleScheduleResponse() {
+ }
+
+ public boolean isSuccess() {
+ return this.errorMessage == null;
+ }
+
+ public String getErrorMessage() {
+ return this.errorMessage;
+ }
+
+ public void setErrorMessage(String errorMessage) {
+ this.errorMessage = errorMessage;
+ }
+
+ public void setErrorMessage(Throwable t) {
+ this.errorMessage = ThrowableUtil.getAllMessages(t);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder str = new StringBuilder(this.getClass().getSimpleName());
+ if (getErrorMessage() != null) {
+ str.append(" error=[").append(getErrorMessage()).append("];");
+ }
+ str.append(" success=[").append(isSuccess()).append("]");
+ return str.toString();
+ }
+}
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleUpdateRequest.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleUpdateRequest.java
deleted file mode 100644
index ba0f7b1..0000000
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleUpdateRequest.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 Red Hat, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation, and/or the GNU Lesser
- * General Public License, version 2.1, also as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License and the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * and the GNU Lesser General Public License along with this program;
- * if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-package org.rhq.core.clientapi.agent.bundle;
-
-/**
- * @author John Mazzitelli
- */
-public class BundleUpdateRequest {
-
-}
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleUpdateResponse.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleUpdateResponse.java
deleted file mode 100644
index 9482fb5..0000000
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/bundle/BundleUpdateResponse.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 Red Hat, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation, and/or the GNU Lesser
- * General Public License, version 2.1, also as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License and the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * and the GNU Lesser General Public License along with this program;
- * if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-package org.rhq.core.clientapi.agent.bundle;
-
-/**
- * @author John Mazzitelli
- */
-public class BundleUpdateResponse {
-
-}
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleServerService.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleServerService.java
index 2d71236..eb09a4e 100644
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleServerService.java
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleServerService.java
@@ -22,7 +22,10 @@
*/
package org.rhq.core.clientapi.server.bundle;
+import java.util.List;
+
import org.rhq.core.communications.command.annotation.Asynchronous;
+import org.rhq.core.domain.bundle.BundleFile;
/**
* Interface for agents to use when needing to inform the server about bundle tasks. Implementations of this interface, once registered with the
@@ -33,5 +36,7 @@ import org.rhq.core.communications.command.annotation.Asynchronous;
public interface BundleServerService {
@Asynchronous(guaranteedDelivery = true)
- void updateComplete(BundleUpdateComplete buc);
+ void updateStatus(BundleStatusUpdate update);
+
+ List<BundleFile> getAllBundleFiles(int bundleVersionId);
}
\ No newline at end of file
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleStatusUpdate.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleStatusUpdate.java
new file mode 100644
index 0000000..99bdda8
--- /dev/null
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleStatusUpdate.java
@@ -0,0 +1,33 @@
+/*
+ * 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, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.rhq.core.clientapi.server.bundle;
+
+/**
+ * Object that informs the server that a bundle deployment has a new status.
+ * This will be the way the bundle deployment process is tracked.
+ *
+ * @author John Mazzitelli
+ */
+public class BundleStatusUpdate {
+
+}
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleUpdateComplete.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleUpdateComplete.java
deleted file mode 100644
index 0314857..0000000
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/server/bundle/BundleUpdateComplete.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2008 Red Hat, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation, and/or the GNU Lesser
- * General Public License, version 2.1, also as published by the Free
- * Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License and the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * and the GNU Lesser General Public License along with this program;
- * if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.rhq.core.clientapi.server.bundle;
-
-/**
- *
- * @author John Mazzitelli
- */
-public class BundleUpdateComplete {
-
-}
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployRequest.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployRequest.java
new file mode 100644
index 0000000..40e663b
--- /dev/null
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployRequest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.core.pluginapi.bundle;
+
+import java.io.Serializable;
+
+import org.rhq.core.domain.bundle.BundleDeployDefinition;
+import org.rhq.core.pc.bundle.BundleManager;
+
+/**
+ * A request to deploy a bundle.
+ *
+ * @author John Mazzitelli
+ */
+public class BundleDeployRequest implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private BundleDeployDefinition bundleDeployDefinition;
+ private BundleManager bundleManager;
+
+ public BundleDeployDefinition getBundleDeployDefinition() {
+ return bundleDeployDefinition;
+ }
+
+ public void setBundleDeployDefinition(BundleDeployDefinition bundleDeployDefinition) {
+ this.bundleDeployDefinition = bundleDeployDefinition;
+ }
+
+ public BundleManager getBundleManager() {
+ return bundleManager;
+ }
+
+ public void setBundleManager(BundleManager bundleManager) {
+ this.bundleManager = bundleManager;
+ }
+
+}
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployResult.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployResult.java
new file mode 100644
index 0000000..b2b3628
--- /dev/null
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleDeployResult.java
@@ -0,0 +1,64 @@
+/*
+ * 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, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.rhq.core.pluginapi.bundle;
+
+import java.io.Serializable;
+
+import org.rhq.core.util.exception.ThrowableUtil;
+
+/**
+ * The results after an attempt to deploy a bundle has been completed.
+ * @author John Mazzitelli
+ */
+public class BundleDeployResult implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private String errorMessage;
+
+ public boolean isSuccess() {
+ return this.errorMessage == null;
+ }
+
+ public String getErrorMessage() {
+ return this.errorMessage;
+ }
+
+ public void setErrorMessage(String errorMessage) {
+ this.errorMessage = errorMessage;
+ }
+
+ public void setErrorMessage(Throwable t) {
+ this.errorMessage = ThrowableUtil.getAllMessages(t);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder str = new StringBuilder(this.getClass().getSimpleName());
+ if (getErrorMessage() != null) {
+ str.append(" error=[").append(getErrorMessage()).append("];");
+ }
+ str.append(" success=[").append(isSuccess()).append("]");
+ return str.toString();
+ }
+
+}
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleFacet.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleFacet.java
index cb5ea35..2b76c0c 100644
--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleFacet.java
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/bundle/BundleFacet.java
@@ -28,4 +28,5 @@ package org.rhq.core.pluginapi.bundle;
* @author John Mazzitelli
*/
public interface BundleFacet {
+ BundleDeployResult deployBundle(BundleDeployRequest request);
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/ServerServices.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/ServerServices.java
index e109755..33951b6 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/ServerServices.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/ServerServices.java
@@ -1,35 +1,36 @@
- /*
- * 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, 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.
- */
+/*
+ * 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, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
package org.rhq.core.pc;
+import org.rhq.core.clientapi.server.bundle.BundleServerService;
import org.rhq.core.clientapi.server.configuration.ConfigurationServerService;
import org.rhq.core.clientapi.server.content.ContentServerService;
import org.rhq.core.clientapi.server.core.CoreServerService;
import org.rhq.core.clientapi.server.discovery.DiscoveryServerService;
+import org.rhq.core.clientapi.server.event.EventServerService;
import org.rhq.core.clientapi.server.inventory.ResourceFactoryServerService;
import org.rhq.core.clientapi.server.measurement.MeasurementServerService;
import org.rhq.core.clientapi.server.operation.OperationServerService;
-import org.rhq.core.clientapi.server.event.EventServerService;
/**
* Provides access to remote pojo's representing the JON Server's client interfaces. These server service interfaces are
@@ -49,6 +50,7 @@ public class ServerServices {
private ResourceFactoryServerService resourceFactoryServerService;
private ContentServerService contentServerService;
private EventServerService eventServerService;
+ private BundleServerService bundleServerService;
public CoreServerService getCoreServerService() {
return coreServerService;
@@ -113,4 +115,13 @@ public class ServerServices {
public void setEventServerService(EventServerService eventServerService) {
this.eventServerService = eventServerService;
}
+
+ public BundleServerService getBundleServerService() {
+ return bundleServerService;
+ }
+
+ public void setBundleServerService(BundleServerService bundleServerService) {
+ this.bundleServerService = bundleServerService;
+ }
+
}
\ No newline at end of file
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 ff92d8c..4ab1c03 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
@@ -22,15 +22,32 @@
*/
package org.rhq.core.pc.bundle;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
import org.rhq.core.clientapi.agent.PluginContainerException;
import org.rhq.core.clientapi.agent.bundle.BundleAgentService;
-import org.rhq.core.clientapi.agent.bundle.BundleUpdateRequest;
-import org.rhq.core.clientapi.agent.bundle.BundleUpdateResponse;
+import org.rhq.core.clientapi.agent.bundle.BundleScheduleRequest;
+import org.rhq.core.clientapi.agent.bundle.BundleScheduleResponse;
+import org.rhq.core.clientapi.server.bundle.BundleServerService;
+import org.rhq.core.domain.bundle.BundleDeployDefinition;
+import org.rhq.core.domain.bundle.BundleFile;
+import org.rhq.core.domain.bundle.BundleType;
+import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.pc.ContainerService;
+import org.rhq.core.pc.PluginContainer;
import org.rhq.core.pc.PluginContainerConfiguration;
import org.rhq.core.pc.agent.AgentService;
+import org.rhq.core.pc.inventory.InventoryManager;
import org.rhq.core.pc.util.ComponentUtil;
import org.rhq.core.pc.util.FacetLockType;
+import org.rhq.core.pluginapi.bundle.BundleDeployRequest;
+import org.rhq.core.pluginapi.bundle.BundleDeployResult;
import org.rhq.core.pluginapi.bundle.BundleFacet;
/**
@@ -41,12 +58,16 @@ import org.rhq.core.pluginapi.bundle.BundleFacet;
* @author John Mazzitelli
*/
public class BundleManager extends AgentService implements BundleAgentService, ContainerService {
+ private final Log log = LogFactory.getLog(BundleManager.class);
+
+ private PluginContainerConfiguration configuration;
public BundleManager() {
super(BundleAgentService.class);
}
public void setConfiguration(PluginContainerConfiguration configuration) {
+ this.configuration = configuration;
}
public void initialize() {
@@ -55,9 +76,66 @@ public class BundleManager extends AgentService implements BundleAgentService, C
public void shutdown() {
}
- public BundleUpdateResponse update(BundleUpdateRequest request) {
- // TODO Auto-generated method stub
- return null;
+ public BundleScheduleResponse schedule(BundleScheduleRequest request) {
+ BundleScheduleResponse response = new BundleScheduleResponse();
+
+ try {
+ BundleDeployDefinition bundleDef = request.getBundleDeployDefinition();
+
+ // find the resource that will handle the bundle processing
+ InventoryManager im = PluginContainer.getInstance().getInventoryManager();
+ BundleType bundleType = bundleDef.getBundleVersion().getBundle().getBundleType();
+ ResourceType resourceType = bundleType.getResourceType();
+ Set<Resource> resources = im.getResourcesWithType(resourceType);
+ if (resources.isEmpty()) {
+ throw new Exception("No bundle plugin supports bundle type [" + bundleType + "]");
+ }
+ int bundleHandlerResourceId = resources.iterator().next().getId();
+
+ // get the bundle facet object that will process the bundle
+ int facetMethodTimeout = 4 * 60 * 60 * 1000; // 4 hours is given to the bundle plugin to do its thing
+ BundleFacet bundlePluginComponent = getBundleFacet(bundleHandlerResourceId, facetMethodTimeout);
+
+ // deploy the bundle utilizing the bundle facet object
+ BundleDeployRequest deployRequest = new BundleDeployRequest();
+ deployRequest.setBundleManager(this);
+ deployRequest.setBundleDeployDefinition(request.getBundleDeployDefinition());
+ BundleDeployResult result = bundlePluginComponent.deployBundle(deployRequest);
+ if (!result.isSuccess()) {
+ response.setErrorMessage(result.getErrorMessage());
+ }
+ } catch (Throwable t) {
+ log.error("Failed to schedule bundle request: " + request, t);
+ response.setErrorMessage(t);
+ }
+
+ return response;
+ }
+
+ /**
+ * This is used by bundle plugins - bundle plugins call back into this manager to obtain the
+ * bundle files that belong to a given bundle version.
+ *
+ * @param bundleVersion
+ * @return the bundle files that are associated with the given bundle
+ * @throws Exception
+ */
+ public List<BundleFile> getAllBundleFiles(BundleVersion bundleVersion) throws Exception {
+ List<BundleFile> bundleFiles = getBundleServerService().getAllBundleFiles(bundleVersion.getId());
+ return bundleFiles;
+ }
+
+ /**
+ * If this manager can talk to a server-side {@link BundleServerService}, a proxy to that service is returned.
+ *
+ * @return the server-side proxy; <code>null</code> if this manager doesn't have a server to talk to
+ */
+ private BundleServerService getBundleServerService() {
+ if (configuration.getServerServices() != null) {
+ return configuration.getServerServices().getBundleServerService();
+ }
+
+ throw new IllegalStateException("There is no bundle server service available to obtain bundle files");
}
/**
@@ -66,13 +144,14 @@ public class BundleManager extends AgentService implements BundleAgentService, C
* The resource must be in the STARTED (i.e. connected) state.
*
* @param resourceId identifies the resource that is to perform the bundle activities
+ * @param timeout if any facet method invocation thread has not completed after this many milliseconds, interrupt
+ * it; value must be positive
*
* @return the resource's bundle facet interface
*
* @throws PluginContainerException on error
*/
- protected BundleFacet getBundleFacet(int resourceId, long facetMethodTimeout) throws PluginContainerException {
- return ComponentUtil.getComponent(resourceId, BundleFacet.class, FacetLockType.READ, facetMethodTimeout, false,
- true);
+ private BundleFacet getBundleFacet(int resourceId, long timeout) throws PluginContainerException {
+ return ComponentUtil.getComponent(resourceId, BundleFacet.class, FacetLockType.READ, timeout, false, true);
}
}
diff --git a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
index 94513d0..19624fa 100644
--- a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
+++ b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
@@ -68,6 +68,7 @@ import org.jboss.remoting.security.SSLSocketBuilder;
import org.jboss.remoting.transport.http.ssl.HTTPSClientInvoker;
import org.jboss.util.StringPropertyReplacer;
+import org.rhq.core.clientapi.server.bundle.BundleServerService;
import org.rhq.core.clientapi.server.configuration.ConfigurationServerService;
import org.rhq.core.clientapi.server.content.ContentServerService;
import org.rhq.core.clientapi.server.core.AgentNotSupportedException;
@@ -1648,6 +1649,7 @@ public class AgentMain {
.getRemotePojo(ResourceFactoryServerService.class);
ContentServerService contentServerService = factory.getRemotePojo(ContentServerService.class);
EventServerService eventServerService = factory.getRemotePojo(EventServerService.class);
+ BundleServerService bundleServerService = factory.getRemotePojo(BundleServerService.class);
ServerServices serverServices = new ServerServices();
serverServices.setCoreServerService(coreServerService);
@@ -1658,6 +1660,7 @@ public class AgentMain {
serverServices.setResourceFactoryServerService(resourceFactoryServerSerfice);
serverServices.setContentServerService(contentServerService);
serverServices.setEventServerService(eventServerService);
+ serverServices.setBundleServerService(bundleServerService);
pc_config.setServerServices(serverServices);
} catch (Exception e) {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java
index a676704..fa84821 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleServerServiceImpl.java
@@ -18,11 +18,14 @@
*/
package org.rhq.enterprise.server.bundle;
+import java.util.List;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rhq.core.clientapi.server.bundle.BundleServerService;
-import org.rhq.core.clientapi.server.bundle.BundleUpdateComplete;
+import org.rhq.core.clientapi.server.bundle.BundleStatusUpdate;
+import org.rhq.core.domain.bundle.BundleFile;
/**
* Server-side implementation of the <code>BundleServerService</code>. This implmentation simply forwards
@@ -33,7 +36,11 @@ import org.rhq.core.clientapi.server.bundle.BundleUpdateComplete;
public class BundleServerServiceImpl implements BundleServerService {
private final Log log = LogFactory.getLog(this.getClass());
- public void updateComplete(BundleUpdateComplete buc) {
+ public void updateStatus(BundleStatusUpdate update) {
// TODO Auto-generated method stub
}
+
+ public List<BundleFile> getAllBundleFiles(int bundleVersionId) {
+ return null;
+ }
}
\ No newline at end of file
diff --git a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
index 08eb7b4..a7100ec 100644
--- a/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
+++ b/modules/plugins/filetemplate-bundle/src/main/java/org/rhq/plugins/filetemplate/FileTemplateBundlePluginServerComponent.java
@@ -22,6 +22,8 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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.inventory.ResourceComponent;
import org.rhq.core.pluginapi.inventory.ResourceContext;
@@ -46,4 +48,11 @@ public class FileTemplateBundlePluginServerComponent implements ResourceComponen
public AvailabilityType getAvailability() {
return AvailabilityType.UP;
}
+
+ @Override
+ public BundleDeployResult deployBundle(BundleDeployRequest request) {
+ // TODO
+ BundleDeployResult result = new BundleDeployResult();
+ return result;
+ }
}
commit 04bf57471b1df335789d03a77b348728db8ab9f8
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Wed Feb 24 12:21:24 2010 -0500
don't bother looping/logging if debug not enabled.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java
index ef27906..dd943e0 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java
@@ -125,8 +125,11 @@ public abstract class Criteria implements Serializable {
results.put(getCleansedFieldName(filterField, 6), filterFieldValue);
}
}
- for (Map.Entry<String, Object> entries : results.entrySet()) {
- LOG.debug("Filter: (" + entries.getKey() + ", " + entries.getValue() + ")");
+
+ if (LOG.isDebugEnabled()) {
+ for (Map.Entry<String, Object> entries : results.entrySet()) {
+ LOG.debug("Filter: (" + entries.getKey() + ", " + entries.getValue() + ")");
+ }
}
return results;
}
@@ -160,8 +163,10 @@ public abstract class Criteria implements Serializable {
}
}
}
- for (String entry : results) {
- LOG.debug("Fetch: (" + entry + ")");
+ if (LOG.isDebugEnabled()) {
+ for (String entry : results) {
+ LOG.debug("Fetch: (" + entry + ")");
+ }
}
return results;
}
@@ -283,7 +288,9 @@ public abstract class Criteria implements Serializable {
}
}
}
- LOG.debug("Page Control: " + pc);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Page Control: " + pc);
+ }
return pc;
}
commit 27317cceaaffe3c97a9c6c22318fa36ce748b5db
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Feb 23 13:31:57 2010 -0500
given a bundle type name, you can now get a plugin component from the bundle plugin that supports that type.
BundleServerPluginFacet will be the interface of the bundle server plugin to the outside world (the SLSBs for example)
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java
index 768162f..5f75e96 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginManager.java
@@ -486,7 +486,6 @@ public class ServerPluginManager {
*
* The new object will be loaded in the plugin's specific classloader.
*
- * @param pluginName the name of the plugin whose main component is to be retrieved
* @param environment the environment in which the plugin will execute
*
* @return a new object loaded in the proper plugin classloader that can initialize/shutdown the plugin,
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/bundle/BundleServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/bundle/BundleServerPluginContainer.java
index 59eb94c..6814b2b 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/bundle/BundleServerPluginContainer.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/bundle/BundleServerPluginContainer.java
@@ -44,4 +44,9 @@ public class BundleServerPluginContainer extends AbstractTypeServerPluginContain
protected ServerPluginManager createPluginManager() {
return new BundleServerPluginManager(this);
}
+
+ public BundleServerPluginManager getBundleServerPluginManager() {
+ return (BundleServerPluginManager) getPluginManager();
+ }
+
}
\ No newline at end of file
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
new file mode 100644
index 0000000..0585a4b
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/bundle/BundleServerPluginFacet.java
@@ -0,0 +1,29 @@
+/*
+ * 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.server.plugin.pc.bundle;
+
+/**
+ * All bundle server plugins must implement this facet.
+ *
+ * @author John Mazzitelli
+ */
+public interface BundleServerPluginFacet {
+
+}
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 c1b542d..68f8a0f 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,8 +18,11 @@
*/
package org.rhq.enterprise.server.plugin.pc.bundle;
+import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment;
import org.rhq.enterprise.server.plugin.pc.ServerPluginManager;
+import org.rhq.enterprise.server.xmlschema.generated.serverplugin.bundle.BundlePluginDescriptorType;
+import org.rhq.enterprise.server.xmlschema.generated.serverplugin.bundle.BundleType;
/**
* This loads in all bundle server plugins that can be found. You can obtain a loaded plugin's
@@ -38,4 +41,55 @@ public class BundleServerPluginManager extends ServerPluginManager {
public void initialize() throws Exception {
super.initialize();
}
+
+ @Override
+ protected void loadPlugin(ServerPluginEnvironment env, boolean enabled) throws Exception {
+ if (enabled) {
+ // validate some things about this plugin that are specific for bundle functionality
+
+ BundlePluginDescriptorType descriptor = (BundlePluginDescriptorType) env.getPluginDescriptor();
+ BundleType bt = descriptor.getBundle();
+ if (bt == null || bt.getType() == null || bt.getType().length() == 0) {
+ // if the xml parser did its job, this will probably never happen, but just in case, make sure there is
+ // a non-null, valid bundle type name - we have other code that expects this to be true
+ throw new Exception("The bundle plugin [" + env.getPluginKey().getPluginName()
+ + "] did not specify a valid bundle type in its descriptor");
+ }
+
+ ServerPluginComponent component = createServerPluginComponent(env);
+ if (!(component instanceof BundleServerPluginFacet)) {
+ throw new Exception("The bundle plugin [" + env.getPluginKey().getPluginName()
+ + "] has an invalid component [" + component + "]. It does not implement ["
+ + BundleServerPluginFacet.class + "]");
+ }
+ }
+
+ super.loadPlugin(env, enabled);
+ }
+
+ /**
+ * Given the {@link BundleType#getName() name of a bundle type}, this will return the stateful plugin component
+ * that manages bundles of that type.
+ *
+ * @param bundleTypeName
+ *
+ * @return the plugin component object that will manage bundles of the named bundle type; <code>null</code> if there is no plugin
+ * that can support the given bundle type
+ */
+ public BundleServerPluginFacet getBundleServerPluginFacet(String bundleTypeName) {
+ if (bundleTypeName == null) {
+ throw new IllegalArgumentException("bundleTypeName == null");
+ }
+
+ for (ServerPluginEnvironment env : getPluginEnvironments()) {
+ BundlePluginDescriptorType descriptor = (BundlePluginDescriptorType) env.getPluginDescriptor();
+ if (bundleTypeName.equals(descriptor.getBundle().getType())) {
+ ServerPluginComponent component = getServerPluginComponent(env.getPluginKey().getPluginName());
+ // we know this cast will work because our loadPlugin ensured that this component implements this interface
+ return (BundleServerPluginFacet) component;
+ }
+ }
+
+ return null;
+ }
}
\ No newline at end of file
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 0e8659e..58dd5b1 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
@@ -25,13 +25,14 @@ import org.rhq.enterprise.server.plugin.pc.ControlFacet;
import org.rhq.enterprise.server.plugin.pc.ControlResults;
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;
/**
* A bundle server-side plugin component that the server uses to process file template bundles.
*
* @author John Mazzitelli
*/
-public class BundleServerPluginComponent implements ServerPluginComponent, ControlFacet {
+public class BundleServerPluginComponent implements ServerPluginComponent, BundleServerPluginFacet, ControlFacet {
private ServerPluginContext context;
commit 76b177feed88fd1706a93e75f7453f67bc5be890
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 22 12:14:28 2010 -0500
Add OneToOne Bundle-Repo relation to db upgrade, domain, criteria and test
code. Change to CascadeType all such that the repo is added and removed
implicitly (i.e. owned by the bundle).
diff --git a/modules/core/dbutils/pom.xml b/modules/core/dbutils/pom.xml
index 1cc3eee..ca2d943 100644
--- a/modules/core/dbutils/pom.xml
+++ b/modules/core/dbutils/pom.xml
@@ -22,7 +22,7 @@
<properties>
<scm.module.path>modules/core/dbutils/</scm.module.path>
- <db.schema.version>2.78</db.schema.version>
+ <db.schema.version>2.78.1</db.schema.version>
</properties>
<dependencies>
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
index 565b0f1..8169695 100644
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@ -3166,9 +3166,21 @@
<schema-addColumn table="RHQ_BUNDLE_DEPLOY_HIST" column="AUDIT_MESSAGE" columnType="LONGVARCHAR" />
<!-- Changes to RHQ_BUNDLE_FILE -->
- <schema-alterColumn table="RHQ_BUNDLE_FILE" column="PACKAGE_VERSION_ID" nullable="FALSE" />
-
- </schemaSpec>
+ <schema-alterColumn table="RHQ_BUNDLE_FILE" column="PACKAGE_VERSION_ID" nullable="FALSE" />
+ </schemaSpec>
+
+ <schemaSpec version="2.78.1">
+ <schema-addColumn table="RHQ_BUNDLE" column="REPO_ID" columnType="INTEGER" />
+ <schema-directSQL>
+ <statement desc="Creating RHQ_BUNDLE foreign key relation to RHQ_REPO">
+ ALTER TABLE RHQ_BUNDLE
+ ADD CONSTRAINT RHQ_REPO_ID_FK
+ FOREIGN KEY (REPO_ID)
+ REFERENCES RHQ_REPO (ID)
+ </statement>
+ </schema-directSQL>
+ </schemaSpec>
+
</dbupgrade>
</target>
</project>
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
index 8109117..02f4a5f 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
@@ -83,7 +83,7 @@ public class Bundle implements Serializable {
private BundleType bundleType;
@JoinColumn(name = "REPO_ID", referencedColumnName = "ID", nullable = false)
- @OneToOne(fetch = FetchType.LAZY, optional = false, cascade = CascadeType.PERSIST)
+ @OneToOne(fetch = FetchType.LAZY, optional = false, cascade = CascadeType.ALL)
private Repo repo;
@OneToMany(mappedBy = "bundle", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@@ -96,6 +96,11 @@ public class Bundle implements Serializable {
public Bundle(String name, BundleType type) {
setName(name);
setBundleType(type);
+ // add implicit Repo
+ Repo repo = new Repo(name);
+ repo.setCandidate(false);
+ repo.setSyncSchedule(null);
+ setRepo(repo);
}
public int getId() {
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java
index 5c40cd0..aed446a 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java
@@ -40,6 +40,7 @@ public class BundleCriteria extends Criteria {
private String filterName;
private boolean fetchBundleVersions;
+ private boolean fetchRepo;
public BundleCriteria() {
super(Bundle.class);
@@ -67,4 +68,9 @@ public class BundleCriteria extends Criteria {
public void fetchBundleVersions(boolean fetchBundleVersions) {
this.fetchBundleVersions = fetchBundleVersions;
}
+
+ public void fetchRepo(boolean fetchRepo) {
+ this.fetchRepo = fetchRepo;
+ }
+
}
diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/bundle/test/BundleTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/bundle/test/BundleTest.java
index 83b9f9f..5b95575 100644
--- a/modules/core/domain/src/test/java/org/rhq/core/domain/bundle/test/BundleTest.java
+++ b/modules/core/domain/src/test/java/org/rhq/core/domain/bundle/test/BundleTest.java
@@ -240,7 +240,9 @@ public class BundleTest extends AbstractEJB3Test {
em.persist(b);
id = b.getId();
assert id > 0;
- assert b.getBundleType().getId() != 0 : "bundleType should have been cascade persisted too";
+ assert b.getBundleType().getId() != 0 : "bundleType should have been persisted independently";
+ assert b.getRepo().getId() != 0 : "bundle's repo should have been cascade persisted with the bundle";
+ assert name.equals(b.getRepo().getName()) : "bundle's repo should have same name as bundle";
q = em.createNamedQuery(Bundle.QUERY_FIND_BY_NAME);
q.setParameter("name", name);
@@ -283,6 +285,15 @@ public class BundleTest extends AbstractEJB3Test {
em.close();
getTransactionManager().commit();
+ // make sure we did cascade delete the repo
+ getTransactionManager().begin();
+ em = getEntityManager();
+ q = em.createNamedQuery(Repo.QUERY_FIND_BY_NAME);
+ q.setParameter("name", bFind.getRepo().getName());
+ assert q.getResultList().size() == 0 : "didn't clean up test repo";
+ em.close();
+ getTransactionManager().commit();
+
done = true;
} catch (Throwable t) {
t.printStackTrace();
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 2d9fd9d..747b980 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
@@ -72,11 +72,13 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
private ResourceTypeManagerLocal resourceTypeManager;
public Bundle createBundle(Subject subject, Bundle bundle) {
- // add the implicit bundle repo
- Repo repo = new Repo(bundle.getName());
- repo.setCandidate(false);
- repo.setSyncSchedule(null);
- bundle.setRepo(repo);
+ // add the implicit bundle repo, if necessary
+ if (null == bundle.getRepo()) {
+ Repo repo = new Repo(bundle.getName());
+ repo.setCandidate(false);
+ repo.setSyncSchedule(null);
+ bundle.setRepo(repo);
+ }
entityManager.persist(bundle);
return bundle;
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
index 4003c40..e381dd4 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
@@ -35,6 +35,7 @@ import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.content.Repo;
import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleVersionCriteria;
import org.rhq.core.domain.resource.ResourceCategory;
@@ -86,6 +87,12 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
em.remove(em.getReference(Bundle.class, ((Bundle) removeMe).getId()));
}
+ q = em.createQuery("SELECT r FROM Repo r WHERE r.name LIKE '" + TEST_PREFIX + "%'");
+ doomed = q.getResultList();
+ for (Object removeMe : doomed) {
+ em.remove(em.getReference(Repo.class, ((Repo) removeMe).getId()));
+ }
+
q = em.createQuery("SELECT bt FROM BundleType bt WHERE bt.name LIKE '" + TEST_PREFIX + "%'");
doomed = q.getResultList();
for (Object removeMe : doomed) {
@@ -170,6 +177,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
c.addFilterName(b.getName());
c.addFilterBundleTypeName(b.getName());
c.fetchBundleVersions(true);
+ c.fetchRepo(true);
bundles = bundleManagerBean.findBundlesByCriteria(getOverlord(), c);
assertNotNull(bundles);
assertEquals(1, bundles.size());
@@ -181,6 +189,9 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
BundleVersion bv = b.getBundleVersions().get(0);
assertEquals(bv2, bv);
assertEquals(b, bv.getBundle());
+ Repo r = b.getRepo();
+ assertNotNull(r);
+ assertEquals(b.getName(), r.getName());
}
@Test(enabled = ENABLED)
commit 9bf4056f5e52ed6d28b6e1b376413ade0645d37e
Merge: ebdfffd... 828a173...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 22 10:50:23 2010 -0500
Merge branch 'bundle' into bundle-jay
Conflicts:
.classpath
diff --cc modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
index 1882586,1882586..0817125
--- a/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
@@@ -499,6 -499,6 +499,7 @@@
<column name="ID" default="sequence-only" initial="10001" primarykey="true" required="true" type="INTEGER"/>
<column name="NAME" size="200" type="VARCHAR2" required="true"/>
<column name="BUNDLE_TYPE_ID" type="INTEGER" required="true" references="RHQ_BUNDLE_TYPE"/>
++ <column name="REPO_ID" type="INTEGER" required="true" references="RHQ_REPO"/>
</table>
<!-- BUNDLE_VERSION represents an actual piece of content that needs to be installed somewhere -->
commit ebdfffdb1241ec829af2c3bb7b47ee9cb12e0240
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 22 10:44:50 2010 -0500
update .classpath to reflect the latest change in base perspective war (not
bundle related)
diff --git a/.classpath b/.classpath
index e9a098f..bb17f97 100644
--- a/.classpath
+++ b/.classpath
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="modules/common/jboss-as/src/main/java"/>
- <classpathentry kind="src" path="etc/modules/base-perspective-war/src/main/java"/>
+ <classpathentry kind="src" path="modules/enterprise/gui/base-perspective-jar/src/main/java"/>
<classpathentry kind="src" path="modules/enterprise/server/plugins/jboss-software/src/test/java"/>
<classpathentry kind="src" path="modules/enterprise/server/plugins/jboss-software/src/main/java"/>
<classpathentry kind="src" path="modules/enterprise/remoting/client-api/src/main/java"/>
commit 2f2a2721301232f9d06c52a6a022ab45397f9c4b
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 22 10:44:15 2010 -0500
- Add 1 to 1 relation between Bundle and its implicit Repo.
- Remove bundleType from the natural key of a Bundle. The NK
is now just the bundle name, which is then used as the name of the
implicit Repo.
- SLSB createBundle() now creates the bundle's implicit repo under the
covers. The repo is named after the bundle, has no sync sched and is
isCandidate is set to false.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
index 783b707..8109117 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
@@ -38,11 +38,14 @@ import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
+import org.rhq.core.domain.content.Repo;
+
/**
* Defines a bundle of content that can be versioned.
*
@@ -79,6 +82,10 @@ public class Bundle implements Serializable {
@ManyToOne(fetch = FetchType.EAGER)
private BundleType bundleType;
+ @JoinColumn(name = "REPO_ID", referencedColumnName = "ID", nullable = false)
+ @OneToOne(fetch = FetchType.LAZY, optional = false, cascade = CascadeType.PERSIST)
+ private Repo repo;
+
@OneToMany(mappedBy = "bundle", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<BundleVersion> bundleVersions = new ArrayList<BundleVersion>();
@@ -115,6 +122,14 @@ public class Bundle implements Serializable {
this.bundleType = bundleType;
}
+ public Repo getRepo() {
+ return repo;
+ }
+
+ public void setRepo(Repo repo) {
+ this.repo = repo;
+ }
+
public List<BundleVersion> getBundleVersions() {
return bundleVersions;
}
@@ -138,7 +153,6 @@ public class Bundle implements Serializable {
final int prime = 31;
int result = 1;
result = (prime * result) + ((name == null) ? 0 : name.hashCode());
- result = (prime * result) + ((bundleType == null) ? 0 : bundleType.hashCode());
return result;
}
@@ -162,14 +176,6 @@ public class Bundle implements Serializable {
return false;
}
- if (bundleType == null) {
- if (other.bundleType != null) {
- return false;
- }
- } else if (!bundleType.equals(other.bundleType)) {
- return false;
- }
-
return true;
}
}
\ No newline at end of file
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 3045872..2d9fd9d 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
@@ -37,6 +37,7 @@ import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleDeployment;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.content.Repo;
import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleDeployDefinitionCriteria;
import org.rhq.core.domain.criteria.BundleDeploymentCriteria;
@@ -71,6 +72,12 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
private ResourceTypeManagerLocal resourceTypeManager;
public Bundle createBundle(Subject subject, Bundle bundle) {
+ // add the implicit bundle repo
+ Repo repo = new Repo(bundle.getName());
+ repo.setCandidate(false);
+ repo.setSyncSchedule(null);
+ bundle.setRepo(repo);
+
entityManager.persist(bundle);
return bundle;
}
@@ -189,14 +196,13 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
int bundleVersionCount = random.nextInt(5) + 1;
for (int i = 0; i < bundleVersionCount; i++) {
String bundleVersionName = UUID.randomUUID().toString();
- final String RECIPE = "repo rhel-x86_64-5\n" +
- "package foo-1.25.rpm\n" +
- "package bar-1.25.rpm\n" +
- "script foo.bash -c some parameter\n" +
- "deploy jboss.tar %{jboss.home.directory}\n" +
- "realize %{jboss.home.directory}/server/default/setting.xml\n" +
- "file example.setting /etc/some/setting.ini\n" +
- "service example restart\n";
+ final String RECIPE = "repo rhel-x86_64-5\n" //
+ + "package foo-1.25.rpm\n" //
+ + "package bar-1.25.rpm\n" //
+ + "script foo.bash -c some parameter\n" //
+ + "deploy jboss.tar %{jboss.home.directory}\n" //
+ + "realize %{jboss.home.directory}/server/default/setting.xml\n" //
+ + "file example.setting /etc/some/setting.ini\n" + "service example restart\n";
BundleVersion bundleVersion = new BundleVersion(bundleVersionName, String.valueOf(i + 1), null, RECIPE);
bundle.addBundleVersion(bundleVersion);
}
commit b6e1eba41e09a48e21eef602f7b281a48d03db74
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 22 10:35:54 2010 -0500
tweak to improve debug logging in rt log handling. (not bundle related)
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/util/ResponseTimeLogParser.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/util/ResponseTimeLogParser.java
index 6f825b2..a3efb74 100644
--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/util/ResponseTimeLogParser.java
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/util/ResponseTimeLogParser.java
@@ -218,12 +218,13 @@ public class ResponseTimeLogParser {
}
private void truncateLog(File logFile) throws IOException {
- log.debug("Truncating response-time log file '" + logFile + "'...");
+ log.debug("Truncating response-time log file: '" + logFile + "'...");
RandomAccessFile randomAccessFile = null;
try {
String mode = "rws";
randomAccessFile = new RandomAccessFile(logFile, mode);
+ log.debug("Truncating response-time log file: setting length to 0.");
randomAccessFile.setLength(0);
} catch (SecurityException e) {
/* User doesn't have permission to change the length, so
@@ -238,6 +239,7 @@ public class ResponseTimeLogParser {
} finally {
if (null != randomAccessFile) {
try {
+ log.debug("Truncating response-time log file: closing file.");
randomAccessFile.close();
} catch (Exception e) {
log.error("Unable to close response-time log file.", e);
commit 828a1738713978ea9ec163cc3852aad3db17efab
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 19 17:51:53 2010 -0500
i think this should report an error always on lock acq failure. we'll leave the flag alone - don't set it to true - let the next call take care of whether or not the init callback should be invoked or not
diff --git a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
index 8c37b50..cd3b479 100644
--- a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
+++ b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
@@ -588,11 +588,9 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
writeLock.unlock();
}
} else {
- if (m_needToCallInitializeCallback) {
- Throwable t = new Throwable("Initialize callback lock could not be acquired");
- LOG.error(CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, t.getMessage());
- return new GenericCommandResponse(command, false, null, t);
- }
+ Throwable t = new Throwable("Initialize callback lock could not be acquired");
+ LOG.error(CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, t.getMessage());
+ return new GenericCommandResponse(command, false, null, t);
}
}
return null;
commit aa5d97b46edc37ebd619f4ee4ef0a28486ad4c8e
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 19 17:44:11 2010 -0500
should not worry about the lock failure if the init callback doesn't need to be invoked anyway
diff --git a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
index 762b9b4..8c37b50 100644
--- a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
+++ b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
@@ -588,10 +588,11 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
writeLock.unlock();
}
} else {
- m_needToCallInitializeCallback = true; // can't invoke callback, we'll want to still call it later
- Throwable t = new Throwable("Initialize callback lock could not be acquired");
- LOG.error(CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, t.getMessage());
- return new GenericCommandResponse(command, false, null, t);
+ if (m_needToCallInitializeCallback) {
+ Throwable t = new Throwable("Initialize callback lock could not be acquired");
+ LOG.error(CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, t.getMessage());
+ return new GenericCommandResponse(command, false, null, t);
+ }
}
}
return null;
commit 9b464808786abd46f1197ebe2a790e52ac312025
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 19 17:38:16 2010 -0500
BZ 537396 - to not block indefinitely if a lock cannot be acquired before attempting to invoke the initialize callback
diff --git a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
index 3775212..762b9b4 100644
--- a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
+++ b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
@@ -21,6 +21,9 @@ package org.rhq.enterprise.communications.command.client;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
import mazz.i18n.Logger;
@@ -95,10 +98,22 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
private InitializeCallback m_initializeCallback;
/**
- * When the first element is <code>true</code>, the initialize callback will need to be called prior
- * to sending any commands. This is an array because the array itself is used for its lock.
+ * When <code>true</code>, the initialize callback will need to be called prior
+ * to sending any commands. Used in conjunection with its associated RW lock.
*/
- private final boolean[] m_needToCallInitializeCallback;
+ private boolean m_needToCallInitializeCallback;
+
+ /**
+ * RW lock when needing to access its associated atomic boolean flag.
+ */
+ private final ReentrantReadWriteLock m_needToCallInitializeCallbackLock;
+
+ /**
+ * Number of minutes to wait while attempting to aquire a lock before attempting
+ * to invoke the initialize callback. If this amount of minutes expires before the lock
+ * is acquired, an error will occur and the initialize callback will have to be attempted later.
+ */
+ private final long m_initializeCallbackLockAcquisitionTimeoutMins;
/**
* Constructor for {@link JBossRemotingRemoteCommunicator} that initializes the client with no invoker locator
@@ -200,7 +215,17 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
m_clientConfiguration.putAll(client_config);
}
- m_needToCallInitializeCallback = new boolean[] { false };
+ m_needToCallInitializeCallback = false;
+ m_needToCallInitializeCallbackLock = new ReentrantReadWriteLock();
+
+ long mins;
+ try {
+ String minsStr = System.getProperty("rhq.communications.initial-callback-lock-wait-mins", "60");
+ mins = Long.parseLong(minsStr);
+ } catch (Throwable t) {
+ mins = 60L;
+ }
+ m_initializeCallbackLockAcquisitionTimeoutMins = mins;
return;
}
@@ -319,7 +344,7 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
if (m_remotingClient != null) {
m_remotingClient.disconnect();
m_remotingClient = null;
- m_needToCallInitializeCallback[0] = (getInitializeCallback() != null); // specifically do not synchronize, just set it
+ m_needToCallInitializeCallback = (getInitializeCallback() != null); // specifically do not synchrononize by using lock, just set it
}
LOG.info(CommI18NResourceKeys.COMMUNICATOR_CHANGING_ENDPOINT, m_invokerLocator, locator);
@@ -377,7 +402,7 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
public void setInitializeCallback(InitializeCallback callback) {
m_initializeCallback = callback;
- m_needToCallInitializeCallback[0] = (callback != null); // specifically do not synchronize, just set it
+ m_needToCallInitializeCallback = (callback != null); // specifically do not synchrononize by using lock, just set it
}
public String getRemoteEndpoint() {
@@ -403,7 +428,7 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
public void connect() throws Exception {
if ((m_remotingClient != null) && !m_remotingClient.isConnected()) {
m_remotingClient.connect();
- m_needToCallInitializeCallback[0] = (getInitializeCallback() != null); // specifically do not synchronize, just set it
+ m_needToCallInitializeCallback = (getInitializeCallback() != null); // specifically do not synchrononize by using lock, just set it
}
return;
@@ -412,7 +437,7 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
public void disconnect() {
if (m_remotingClient != null) {
m_remotingClient.disconnect();
- m_needToCallInitializeCallback[0] = (getInitializeCallback() != null); // specifically do not synchronize, just set it
+ m_needToCallInitializeCallback = (getInitializeCallback() != null); // specifically do not synchrononize by using lock, just set it
}
return;
@@ -535,18 +560,38 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
private CommandResponse invokeInitializeCallbackIfNeeded(Command command) {
InitializeCallback callback = getInitializeCallback();
if (callback != null) {
- // block here - in effect, this will stop all commands from going out until the callback is done
- synchronized (m_needToCallInitializeCallback) {
- if (m_needToCallInitializeCallback[0]) {
- try {
- m_needToCallInitializeCallback[0] = !callback.sendingInitialCommand(this, command);
- LOG.debug(CommI18NResourceKeys.INITIALIZE_CALLBACK_DONE, m_needToCallInitializeCallback[0]);
- } catch (Throwable t) {
- m_needToCallInitializeCallback[0] = true; // callback failed, we'll want to call it again
- LOG.error(t, CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, ThrowableUtil.getAllMessages(t));
- return new GenericCommandResponse(command, false, null, t);
+ // block here - in effect, this will stop all commands from going out until the callback is done
+ // to avoid infinite blocking, we'll only wait for a set time (though long).
+
+ WriteLock writeLock = m_needToCallInitializeCallbackLock.writeLock();
+ boolean locked;
+ try {
+ locked = writeLock.tryLock(m_initializeCallbackLockAcquisitionTimeoutMins, TimeUnit.MINUTES);
+ } catch (InterruptedException ie) {
+ locked = false;
+ }
+
+ if (locked) {
+ try {
+ if (m_needToCallInitializeCallback) {
+ try {
+ m_needToCallInitializeCallback = (!callback.sendingInitialCommand(this, command));
+ LOG.debug(CommI18NResourceKeys.INITIALIZE_CALLBACK_DONE, m_needToCallInitializeCallback);
+ } catch (Throwable t) {
+ m_needToCallInitializeCallback = true; // callback failed, we'll want to call it again
+ LOG.error(t, CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, ThrowableUtil
+ .getAllMessages(t));
+ return new GenericCommandResponse(command, false, null, t);
+ }
}
+ } finally {
+ writeLock.unlock();
}
+ } else {
+ m_needToCallInitializeCallback = true; // can't invoke callback, we'll want to still call it later
+ Throwable t = new Throwable("Initialize callback lock could not be acquired");
+ LOG.error(CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, t.getMessage());
+ return new GenericCommandResponse(command, false, null, t);
}
}
return null;
commit a8f8356472ef662fdef16ca6b8db2d1c2b64469e
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 19 02:53:49 2010 -0500
create a peer package type for all bundle types during metadata updates
fix the plugin validator - it wasn't flagging failures when it should have been
fix the virt plugin due to the plugin validation failure that was now correctly detected
diff --git a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/PluginMetadataParser.java b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/PluginMetadataParser.java
index 5d38963..26bf354 100644
--- a/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/PluginMetadataParser.java
+++ b/modules/core/client-api/src/main/java/org/rhq/core/clientapi/agent/metadata/PluginMetadataParser.java
@@ -50,6 +50,7 @@ import org.rhq.core.clientapi.descriptor.plugin.ServerDescriptor;
import org.rhq.core.clientapi.descriptor.plugin.ServiceDescriptor;
import org.rhq.core.clientapi.descriptor.plugin.SubCategoryDescriptor;
import org.rhq.core.domain.bundle.BundleType;
+import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.event.EventDefinition;
import org.rhq.core.domain.measurement.MeasurementDefinition;
import org.rhq.core.domain.resource.ClassLoaderType;
@@ -59,6 +60,7 @@ import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceCreationDataType;
import org.rhq.core.domain.resource.ResourceSubCategory;
import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.util.StringUtils;
/**
* This is a stateful class intended to hold the related metadata for a single plugin descriptor. It is designed to be
@@ -165,6 +167,8 @@ public class PluginMetadataParser {
+ "The <runs-inside> information will be ignored in resource type: " + platformResourceType);
}
+ platformResourceType.setCreateDeletePolicy(CreateDeletePolicy.NEITHER);
+
return platformResourceType;
}
@@ -523,6 +527,18 @@ public class PluginMetadataParser {
if (bundle != null) {
String typeName = bundle.getType();
resourceType.setBundleType(new BundleType(typeName, resourceType));
+
+ // create the peer package type for the bundle type
+ PackageType bundlePackageType = new PackageType();
+ bundlePackageType.setName(typeName);
+ bundlePackageType.setDescription("Package type for content of bundles of type " + typeName);
+ bundlePackageType.setCategory(null);
+ bundlePackageType.setSupportsArchitecture(false);
+ bundlePackageType.setDisplayName(StringUtils.deCamelCase(typeName));
+ bundlePackageType.setDiscoveryInterval(-1L);
+ bundlePackageType.setCreationData(false);
+ bundlePackageType.setDeploymentConfigurationDefinition(null);
+ resourceType.addPackageType(bundlePackageType);
}
} catch (InvalidPluginDescriptorException e) {
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/content/ContentManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/content/ContentManager.java
index 90f0cd6..673ba1a 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/content/ContentManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/content/ContentManager.java
@@ -354,10 +354,22 @@ public class ContentManager extends AgentService implements ContainerService, Co
discoveryInfo.getResourceId());
if (resourceContainer != null) {
- log.debug("Rescheduling [" + discoveryInfo + "]...");
- discoveryInfo.setNextDiscovery(System.currentTimeMillis() + discoveryInfo.getInterval());
- addToQueue(discoveryInfo);
- log.debug("Finished rescheduling: " + discoveryInfo);
+ boolean debugEnabled = log.isDebugEnabled();
+
+ if (discoveryInfo.getInterval() > 0) {
+ if (debugEnabled) {
+ log.debug("Rescheduling [" + discoveryInfo + "]...");
+ }
+ discoveryInfo.setNextDiscovery(System.currentTimeMillis() + discoveryInfo.getInterval());
+ addToQueue(discoveryInfo);
+ if (debugEnabled) {
+ log.debug("Finished rescheduling: " + discoveryInfo);
+ }
+ } else {
+ if (debugEnabled) {
+ log.debug("Will not reschedule content discovery: " + discoveryInfo);
+ }
+ }
}
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginValidator.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginValidator.java
index deb6341..a38fb51 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginValidator.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/plugin/PluginValidator.java
@@ -34,6 +34,7 @@ import org.apache.commons.logging.LogFactory;
import org.rhq.core.clientapi.agent.metadata.PluginMetadataManager;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.pc.PluginContainerConfiguration;
+import org.rhq.core.pluginapi.bundle.BundleFacet;
import org.rhq.core.pluginapi.configuration.ConfigurationFacet;
import org.rhq.core.pluginapi.content.ContentFacet;
import org.rhq.core.pluginapi.inventory.CreateChildResourceFacet;
@@ -126,9 +127,11 @@ public class PluginValidator {
success = success && validateResourceComponentClass(metadataManager, resourceType, pluginEnvironment);
// if the optional discovery class was specified, make sure it can be loaded by the plugin classloader
- success = success && validateResourceDiscoveryComponentClass(metadataManager, resourceType, pluginEnvironment);
+ success = success
+ && validateResourceDiscoveryComponentClass(metadataManager, resourceType, pluginEnvironment);
- success = success && validatePluginLifecycleListenerClass(metadataManager, resourceType, pluginEnvironment);
+ success = success
+ && validatePluginLifecycleListenerClass(metadataManager, resourceType, pluginEnvironment);
}
} finally {
manager.shutdown();
@@ -138,8 +141,7 @@ public class PluginValidator {
}
private static boolean validateResourceComponentClass(PluginMetadataManager metadataManager,
- ResourceType resourceType,
- PluginEnvironment pluginEnvironment) {
+ ResourceType resourceType, PluginEnvironment pluginEnvironment) {
boolean success = true;
String componentClass = metadataManager.getComponentClass(resourceType);
if (componentClass == null) {
@@ -148,41 +150,50 @@ public class PluginValidator {
+ resourceType.getPlugin() + "]");
} else {
try {
- Class componentClazz = Class.forName(componentClass, false, pluginEnvironment
- .getPluginClassLoader());
+ Class componentClazz = Class.forName(componentClass, false, pluginEnvironment.getPluginClassLoader());
if (!ResourceComponent.class.isAssignableFrom(componentClazz)) {
success = false;
- LOG.error("Component class [" + componentClass + "] for resource type ["
- + resourceType.getName() + "] from plugin [" + resourceType.getPlugin()
- + "] does not implement " + ResourceComponent.class);
+ LOG.error("Component class [" + componentClass + "] for resource type [" + resourceType.getName()
+ + "] from plugin [" + resourceType.getPlugin() + "] does not implement "
+ + ResourceComponent.class);
}
if (!resourceType.getMetricDefinitions().isEmpty()
&& !MeasurementFacet.class.isAssignableFrom(componentClazz)) {
success = false;
- LOG.error("Component class [" + componentClass + "] for resource type ["
- + resourceType.getName() + "] from plugin [" + resourceType.getPlugin()
- + "] does not support measurement collection.");
+ LOG.error("Component class [" + componentClass + "] for resource type [" + resourceType.getName()
+ + "] from plugin [" + resourceType.getPlugin()
+ + "] does not support the measurement collection facet but defines metrics.");
}
if (!resourceType.getOperationDefinitions().isEmpty()
&& !OperationFacet.class.isAssignableFrom(componentClazz)) {
success = false;
- LOG.error("Component class [" + componentClass + "] for resource type ["
- + resourceType.getName() + "] from plugin [" + resourceType.getPlugin()
- + "] does not support operations.");
+ LOG.error("Component class [" + componentClass + "] for resource type [" + resourceType.getName()
+ + "] from plugin [" + resourceType.getPlugin()
+ + "] does not support the operations facet but defines operations.");
}
- if (!resourceType.getPackageTypes().isEmpty()
- && !ContentFacet.class.isAssignableFrom(componentClazz)) {
+ if (resourceType.getBundleType() != null && !BundleFacet.class.isAssignableFrom(componentClazz)) {
success = false;
- LOG.error("Component class [" + componentClass + "] for resource type ["
- + resourceType.getName() + "] from plugin [" + resourceType.getPlugin()
- + "] does not support content management.");
+ LOG.error("Component class [" + componentClass + "] for resource type [" + resourceType.getName()
+ + "] from plugin [" + resourceType.getPlugin()
+ + "] does not support the bundle facet but defines a bundle type.");
+ }
+ if (!resourceType.getPackageTypes().isEmpty() && !ContentFacet.class.isAssignableFrom(componentClazz)) {
+ // this might be OK - there is a package type implicit if a bundle type is also defined
+ // if there is one package type, and there is a bundle type, they should have the same name
+ if (!(resourceType.getBundleType() != null && resourceType.getPackageTypes().size() == 1 && resourceType
+ .getBundleType().getName().equals(resourceType.getPackageTypes().iterator().next().getName()))) {
+ success = false;
+ LOG.error("Component class [" + componentClass + "] for resource type ["
+ + resourceType.getName() + "] from plugin [" + resourceType.getPlugin()
+ + "] does not support the content management facet but defines package types.");
+ }
}
if (resourceType.getResourceConfigurationDefinition() != null
&& !ConfigurationFacet.class.isAssignableFrom(componentClazz)) {
success = false;
- LOG.error("Component class [" + componentClass + "] for resource type ["
- + resourceType.getName() + "] from plugin [" + resourceType.getPlugin()
- + "] does not support configuration.");
+ LOG.error("Component class [" + componentClass + "] for resource type [" + resourceType.getName()
+ + "] from plugin [" + resourceType.getPlugin()
+ + "] does not support the configuration facet but defines resource configuration.");
}
boolean hasCreatableChild = false;
for (ResourceType childResourceType : resourceType.getChildResourceTypes()) {
@@ -192,14 +203,16 @@ public class PluginValidator {
}
}
if (hasCreatableChild && !CreateChildResourceFacet.class.isAssignableFrom(componentClazz)) {
- LOG.error("Component class [" + componentClass + "] for resource type ["
- + resourceType.getName() + "] from plugin [" + resourceType.getPlugin()
- + "] does not support creation of child resources.");
+ success = false;
+ LOG.error("Component class [" + componentClass + "] for resource type [" + resourceType.getName()
+ + "] from plugin [" + resourceType.getPlugin()
+ + "] does not support the child creation facet but has metadata saying it can.");
}
if (resourceType.isDeletable() && !DeleteResourceFacet.class.isAssignableFrom(componentClazz)) {
- LOG.error("Component class [" + componentClass + "] for resource type ["
- + resourceType.getName() + "] from plugin [" + resourceType.getPlugin()
- + "] does not support deletion.");
+ success = false;
+ LOG.error("Component class [" + componentClass + "] for resource type [" + resourceType.getName()
+ + "] from plugin [" + resourceType.getPlugin()
+ + "] does not support delete resource facet but has metadata saying it can delete children.");
}
} catch (Exception e) {
success = false;
@@ -211,24 +224,21 @@ public class PluginValidator {
}
private static boolean validateResourceDiscoveryComponentClass(PluginMetadataManager metadataManager,
- ResourceType resourceType,
- PluginEnvironment pluginEnvironment) {
+ ResourceType resourceType, PluginEnvironment pluginEnvironment) {
boolean success = true;
String discoveryClass = metadataManager.getDiscoveryClass(resourceType);
if (discoveryClass != null) {
try {
- Class discoveryClazz = Class.forName(discoveryClass, false, pluginEnvironment
- .getPluginClassLoader());
+ Class discoveryClazz = Class.forName(discoveryClass, false, pluginEnvironment.getPluginClassLoader());
if (!ResourceDiscoveryComponent.class.isAssignableFrom(discoveryClazz)) {
success = false;
- LOG.error("Discovery class [" + discoveryClass + "] for resource type ["
- + resourceType.getName() + "] from plugin [" + resourceType.getPlugin()
- + "] does not implement " + ResourceDiscoveryComponent.class);
+ LOG.error("Discovery class [" + discoveryClass + "] for resource type [" + resourceType.getName()
+ + "] from plugin [" + resourceType.getPlugin() + "] does not implement "
+ + ResourceDiscoveryComponent.class);
}
if (resourceType.isSupportsManualAdd() && !ManualAddFacet.class.isAssignableFrom(discoveryClazz)) {
- LOG.warn("Discovery class [" + discoveryClass + "] for resource type ["
- + resourceType.getName() + "] from plugin [" + resourceType.getPlugin()
- + "] does not implement " + ManualAddFacet.class
+ LOG.warn("Discovery class [" + discoveryClass + "] for resource type [" + resourceType.getName()
+ + "] from plugin [" + resourceType.getPlugin() + "] does not implement " + ManualAddFacet.class
+ " - implementing manual-add in discoverResources() is deprecated.");
}
} catch (Exception e) {
@@ -241,8 +251,7 @@ public class PluginValidator {
}
private static boolean validatePluginLifecycleListenerClass(PluginMetadataManager metadataManager,
- ResourceType resourceType,
- PluginEnvironment pluginEnvironment) {
+ ResourceType resourceType, PluginEnvironment pluginEnvironment) {
boolean success = true;
String overseerClass = metadataManager.getPluginLifecycleListenerClass(resourceType.getPlugin());
if (overseerClass != null) {
@@ -251,8 +260,7 @@ public class PluginValidator {
if (!PluginLifecycleListener.class.isAssignableFrom(overseerClazz)) {
success = false;
LOG.error("Plugin Lifecycle Listener class [" + overseerClass + "] for plugin ["
- + resourceType.getPlugin() + "] does not implement "
- + PluginLifecycleListener.class);
+ + resourceType.getPlugin() + "] does not implement " + PluginLifecycleListener.class);
}
} catch (Exception e) {
success = false;
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java
index c1f46fc..9e69de6 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java
@@ -54,6 +54,7 @@ import org.rhq.core.clientapi.descriptor.AgentPluginDescriptorUtil;
import org.rhq.core.clientapi.descriptor.plugin.PluginDescriptor;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.authz.Permission;
+import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.event.EventDefinition;
@@ -587,8 +588,6 @@ public class ResourceMetadataManagerBean implements ResourceMetadataManagerLocal
existingType.setSubCategory(existingSubCat);
}
- existingType.setBundleType(resourceType.getBundleType());
-
existingType = entityManager.merge(existingType);
entityManager.flush();
} catch (NoResultException nre) {
@@ -921,6 +920,21 @@ public class ResourceMetadataManagerBean implements ResourceMetadataManagerLocal
* @param existingType old resource type with existing package definitions
*/
private void updateContentDefinitions(ResourceType newType, ResourceType existingType) {
+
+ // set the bundle type if one is defined
+ BundleType newBundleType = newType.getBundleType();
+ if (newBundleType != null) {
+ BundleType existingBundleType = existingType.getBundleType();
+ newBundleType.setResourceType(existingType);
+ if (existingBundleType != null) {
+ newBundleType.setId(existingBundleType.getId());
+ newBundleType = entityManager.merge(newBundleType);
+ }
+ existingType.setBundleType(newBundleType);
+ } else {
+ existingType.setBundleType(null);
+ }
+
// Easy case: If there are no package definitions in the new type, null out any in the existing and return
if ((newType.getPackageTypes() == null) || (newType.getPackageTypes().size() == 0)) {
existingType.setPackageTypes(null);
diff --git a/modules/enterprise/server/plugins/filetemplate-bundle/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/filetemplate-bundle/src/main/resources/META-INF/rhq-serverplugin.xml
index f60c92c..7cf19a4 100644
--- a/modules/enterprise/server/plugins/filetemplate-bundle/src/main/resources/META-INF/rhq-serverplugin.xml
+++ b/modules/enterprise/server/plugins/filetemplate-bundle/src/main/resources/META-INF/rhq-serverplugin.xml
@@ -23,6 +23,6 @@
description="A property my bundle plugin needs to be properly configured" />
</serverplugin:plugin-configuration>
- <bundle type="File Template"/>
+ <bundle type="File Template Bundle"/>
</bundle-plugin>
diff --git a/modules/plugins/filetemplate-bundle/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/filetemplate-bundle/src/main/resources/META-INF/rhq-plugin.xml
index 057335d..a07d411 100644
--- a/modules/plugins/filetemplate-bundle/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/filetemplate-bundle/src/main/resources/META-INF/rhq-plugin.xml
@@ -14,7 +14,7 @@
singleton="true"
description="This plugin is used to process File Template bundles">
- <bundle type="File Template" />
+ <bundle type="File Template Bundle" />
</server>
</plugin>
diff --git a/modules/plugins/virt/src/main/java/org/rhq/plugins/virt/VirtualizationNetworkComponent.java b/modules/plugins/virt/src/main/java/org/rhq/plugins/virt/VirtualizationNetworkComponent.java
index 9517074..0a0c82c 100644
--- a/modules/plugins/virt/src/main/java/org/rhq/plugins/virt/VirtualizationNetworkComponent.java
+++ b/modules/plugins/virt/src/main/java/org/rhq/plugins/virt/VirtualizationNetworkComponent.java
@@ -33,6 +33,7 @@ import org.rhq.core.pluginapi.configuration.ConfigurationFacet;
import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport;
import org.rhq.core.pluginapi.inventory.CreateChildResourceFacet;
import org.rhq.core.pluginapi.inventory.CreateResourceReport;
+import org.rhq.core.pluginapi.inventory.DeleteResourceFacet;
import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.inventory.ResourceContext;
@@ -45,7 +46,7 @@ import org.rhq.core.pluginapi.measurement.MeasurementFacet;
* @author Greg Hinkle
*/
public class VirtualizationNetworkComponent implements ResourceComponent<VirtualizationHostComponent>,
- MeasurementFacet, ConfigurationFacet, CreateChildResourceFacet {
+ MeasurementFacet, ConfigurationFacet, CreateChildResourceFacet, DeleteResourceFacet {
private Log log = LogFactory.getLog(VirtualizationDomainComponent.class);
private String networkName;
@@ -140,6 +141,10 @@ public class VirtualizationNetworkComponent implements ResourceComponent<Virtual
return report;
}
+ public void deleteResource() throws Exception {
+ // TODO Auto-generated method stub
+ }
+
public LibVirtConnection getConnection() throws LibvirtException {
return resourceContext.getParentResourceComponent().getConnection();
}
commit 232518450b4be54cc37903152040a010adee8f88
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Thu Feb 18 17:10:22 2010 -0500
remove extra parens from delete query
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/content/InstalledPackage.java b/modules/core/domain/src/main/java/org/rhq/core/domain/content/InstalledPackage.java
index 5889e09..b7550f4 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/content/InstalledPackage.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/content/InstalledPackage.java
@@ -69,7 +69,7 @@ import org.rhq.core.domain.resource.Resource;
+ "FROM InstalledPackage ip JOIN ip.resource res LEFT JOIN ip.packageVersion pv LEFT JOIN pv.generalPackage gp LEFT JOIN gp.packageType pt "
+ "WHERE res.id = :resourceId " + " AND gp.id = :generalPackageId"),
@NamedQuery(name = InstalledPackage.QUERY_DELETE_BY_RESOURCES, query = "DELETE FROM InstalledPackage ip "
- + " WHERE ip.resource.id IN ( :resourceIds ) )") })
+ + " WHERE ip.resource.id IN ( :resourceIds )") })
@SequenceGenerator(name = "SEQ", sequenceName = "RHQ_INSTALLED_PACKAGE_ID_SEQ")
@Table(name = "RHQ_INSTALLED_PACKAGE")
public class InstalledPackage implements Serializable {
commit 309ed71d68b779d2b1ca16702f12f3e6ccbff751
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Thu Feb 18 15:59:10 2010 -0500
add new base-perspective-jar to eclipse classpath
diff --git a/.classpath b/.classpath
index 2cb7235..92929a9 100644
--- a/.classpath
+++ b/.classpath
@@ -70,6 +70,7 @@
<classpathentry kind="src" path="modules/enterprise/gui/installer-war/src/main/java"/>
<classpathentry kind="src" path="modules/enterprise/gui/webdav-war/src/main/java"/>
<classpathentry kind="src" path="modules/enterprise/gui/content_http-war/src/main/java"/>
+ <classpathentry kind="src" path="modules/enterprise/gui/base-perspective-jar/src/main/java"/>
<classpathentry kind="src" path="modules/enterprise/remoting/cli/src/main/java"/>
<classpathentry kind="src" path="modules/enterprise/remoting/cli/src/test/java"/>
<classpathentry kind="src" path="modules/enterprise/remoting/webservices/src/main/java"/>
commit e31444b7f79cf6506abf96f2b6321fc68cc83225
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Thu Feb 18 15:56:21 2010 -0500
part of BZ 560803 - use distinct in having clause to speed up query
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementBaseline.java b/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementBaseline.java
index a1b3757..9b3e9ec 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementBaseline.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/measurement/MeasurementBaseline.java
@@ -140,7 +140,7 @@ public class MeasurementBaseline implements Serializable {
+ " AND ( data1h.TIME_STAMP BETWEEN ? AND ? ) " // ?2=startTime, ?3=endTime
+ " GROUP BY data1h.SCHEDULE_ID " // baselines are aggregates per schedule
// but only calculate baselines for schedules where we have data that fills (startTime, endTime)
- + " HAVING data1h.SCHEDULE_ID in ( SELECT mdata.SCHEDULE_ID "
+ + " HAVING data1h.SCHEDULE_ID in ( SELECT distinct (mdata.SCHEDULE_ID) "
+ " FROM RHQ_MEASUREMENT_DATA_NUM_1H mdata " //
+ " WHERE mdata.TIME_STAMP <= ? ) " // ?4=startTime
+ " LIMIT 100000 "; // batch at most 100K inserts at a time to shrink the xtn size
@@ -167,7 +167,7 @@ public class MeasurementBaseline implements Serializable {
+ " AND ROWNUM < 100001 " // batch at most 100K inserts at a time to shrink the xtn size
+ " GROUP BY data1h.SCHEDULE_ID " // baselines are aggregates per schedule
// but only calculate baselines for schedules where we have data that fills (startTime, endTime)
- + " HAVING data1h.SCHEDULE_ID in ( SELECT mdata.SCHEDULE_ID " //
+ + " HAVING data1h.SCHEDULE_ID in ( SELECT distinct (mdata.SCHEDULE_ID) " //
+ " FROM RHQ_MEASUREMENT_DATA_NUM_1H mdata "
+ " WHERE mdata.TIME_STAMP <= ? ) ) "; // ?4=startTime
@@ -190,7 +190,7 @@ public class MeasurementBaseline implements Serializable {
+ " AND ( data1h.TIME_STAMP BETWEEN ? AND ? ) " // ?2=startTime, ?3=endTime
+ " GROUP BY data1h.SCHEDULE_ID " // baselines are aggregates per schedule
// but only calculate baselines for schedules where we have data that fills (startTime, endTime)
- + " HAVING data1h.SCHEDULE_ID in ( SELECT mdata.SCHEDULE_ID " //
+ + " HAVING data1h.SCHEDULE_ID in ( SELECT distinct (mdata.SCHEDULE_ID) " //
+ " FROM RHQ_MEASUREMENT_DATA_NUM_1H mdata "
+ " WHERE mdata.TIME_STAMP <= ? ) "; // ?4=startTime
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java
index 37412a4..10bdbc7 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/measurement/MeasurementBaselineManagerBean.java
@@ -157,6 +157,30 @@ public class MeasurementBaselineManagerBean implements MeasurementBaselineManage
* 3) the user tended to import all new resources / platforms at the same time of day, thus bypassing
* the implicit optimization of trying to stagger the calculations by resource commit time
*
+ * 2/18/2010 NOTE: Limits weren't / aren't actually achieving the affect we want. The baseline query
+ * follows the general form of "insert into...select from <big query> having <subquery> limit X".
+ * In this case, the limit was reducing the number of rows inserted, but it was still taking the full
+ * cost of calculating everything that should have been inserted. The limit was intended as a cheap
+ * method of chunking or partitioning the work, but wasn't properly chunking the expensive
+ * part - the "big query". What we actually want to do is come of with a strategy that lessens the
+ * amount of data we need to select, thereby reducing the amount of time it takes to calculate the
+ * insertion list.
+ *
+ * One proposed strategy for this would be to chunk on the scheduleId. So if there were, say,
+ * 5M scheduleIds in the systems, we might take 500K of them at a time and then execute the
+ * baseline insertion job 10 times against a much smaller set of data each time. But the
+ * complication here is how to calculate precise groups of 500K schedules at a time, and then
+ * walk that chunked list.
+ *
+ * Another strategy would be to divy things up by resource type. Since a measurementSchedule is
+ * linked to a measurementDefinition which is linked to a resourceType, we could very easily chunk
+ * the insertion based off the schedules that belong to each resourceType. This would create
+ * one insert statement for each type of resource in system. The complication here, however,
+ * is that you may have millions of resources of one type, but hardly any resources of another.
+ * So there's still a chance that some insertions proceed slowly (in the worst case).
+ *
+ * In any event, an appropriate chunking solution needs to be found, and that partitioning strategy
+ * needs to replace the limits in the query today.
*/
int inserted = measurementBaselineManager._calculateAutoBaselinesINSERT(amountOfData);
totalInserted += inserted;
commit fd4cc59dbc5d571672121dcf8c37814fa02c8d74
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Thu Feb 18 15:55:42 2010 -0500
there is no longer etc/modules
diff --git a/.classpath b/.classpath
index e9a098f..2cb7235 100644
--- a/.classpath
+++ b/.classpath
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="modules/common/jboss-as/src/main/java"/>
- <classpathentry kind="src" path="etc/modules/base-perspective-war/src/main/java"/>
<classpathentry kind="src" path="modules/enterprise/server/plugins/jboss-software/src/test/java"/>
<classpathentry kind="src" path="modules/enterprise/server/plugins/jboss-software/src/main/java"/>
<classpathentry kind="src" path="modules/enterprise/remoting/client-api/src/main/java"/>
commit 46f559f3cb7e675b51125a50ae2c155212524b71
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Thu Feb 18 10:44:32 2010 -0500
Ensure rt log file is closed appropriately on read and truncate.
(not related to bundle work, just ended up here, sorry)
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/util/ResponseTimeLogParser.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/util/ResponseTimeLogParser.java
index 50419e3..6f825b2 100644
--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/util/ResponseTimeLogParser.java
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/util/ResponseTimeLogParser.java
@@ -1,25 +1,25 @@
- /*
- * 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, 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.
- */
+/*
+ * 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, version 2, as
+ * published by the Free Software Foundation, and/or the GNU Lesser
+ * General Public License, version 2.1, also as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License and the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the GNU Lesser General Public License along with this program;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
package org.rhq.core.pluginapi.util;
import java.io.BufferedReader;
@@ -86,53 +86,62 @@ public class ResponseTimeLogParser {
*/
public synchronized void parseLog(CallTimeData callTimeData) throws IOException {
log.debug("Parsing response-time log file " + this.logFile + "...");
- BufferedReader in;
+ BufferedReader in = null;
+
try {
in = new BufferedReader(new FileReader(this.logFile));
- } catch (FileNotFoundException e) {
- log.warn("Response-time log file '" + this.logFile + "' does not exist.");
- return;
- }
- in.skip(this.startingOffset);
- String currentLine;
- while ((currentLine = in.readLine()) != null) {
- LogEntry logEntry;
- try {
- logEntry = parseLine(currentLine);
- } catch (Exception e) {
- log.debug("Problem parsing line [" + currentLine + "] - cause: " + e);
- continue;
- }
+ in.skip(this.startingOffset);
- String url = logEntry.getUrl();
-
- // The URL should always begin with a slash. If it doesn't, log an error and skip the entry,
- // so we don't end up with bogus data in the DB.
- if (url.charAt(0) != '/') {
- String truncatedUrl = url.substring(0, Math.min(url.length(), 120));
- if (url.length() > 120)
- truncatedUrl += "...";
- log.error("URL ('" + truncatedUrl + "') parsed from response-time log file does not begin with '/'. "
- + "Line being parsed is [" + currentLine + "].");
- continue;
- }
+ String currentLine;
+ while ((currentLine = in.readLine()) != null) {
+ LogEntry logEntry;
+ try {
+ logEntry = parseLine(currentLine);
+ } catch (Exception e) {
+ log.debug("Problem parsing line [" + currentLine + "] - cause: " + e);
+ continue;
+ }
- if (isExcluded(url)) {
- continue;
- }
+ String url = logEntry.getUrl();
+
+ // The URL should always begin with a slash. If it doesn't, log an error and skip the entry,
+ // so we don't end up with bogus data in the DB.
+ if (url.charAt(0) != '/') {
+ String truncatedUrl = url.substring(0, Math.min(url.length(), 120));
+ if (url.length() > 120)
+ truncatedUrl += "...";
+ log.error("URL ('" + truncatedUrl
+ + "') parsed from response-time log file does not begin with '/'. " + "Line being parsed is ["
+ + currentLine + "].");
+ continue;
+ }
- // Only collect stats for successful (2xx or 3xx) requests...
- if ((logEntry.getStatusCode() != null)
- && ((logEntry.getStatusCode() < 200) || (logEntry.getStatusCode() >= 400))) {
- continue;
- }
+ if (isExcluded(url)) {
+ continue;
+ }
- String transformedUrl = applyTransforms(url);
- callTimeData.addCallData(transformedUrl, new Date(logEntry.getStartTime()), logEntry.getDuration());
- }
+ // Only collect stats for successful (2xx or 3xx) requests...
+ if ((logEntry.getStatusCode() != null)
+ && ((logEntry.getStatusCode() < 200) || (logEntry.getStatusCode() >= 400))) {
+ continue;
+ }
- in.close();
+ String transformedUrl = applyTransforms(url);
+ callTimeData.addCallData(transformedUrl, new Date(logEntry.getStartTime()), logEntry.getDuration());
+ }
+ } catch (FileNotFoundException e) {
+ log.warn("Response-time log file '" + this.logFile + "' does not exist.");
+ return;
+ } finally {
+ if (null != in) {
+ try {
+ in.close();
+ } catch (Exception e) {
+ log.error("Unable to close response-time log file.", e);
+ }
+ }
+ }
/*
* After we're done parsing the file, truncate it. This is kosher, assuming we own any file being parsed by this
@@ -210,11 +219,12 @@ public class ResponseTimeLogParser {
private void truncateLog(File logFile) throws IOException {
log.debug("Truncating response-time log file '" + logFile + "'...");
+ RandomAccessFile randomAccessFile = null;
+
try {
String mode = "rws";
- RandomAccessFile randomAccessFile = new RandomAccessFile(logFile, mode);
+ randomAccessFile = new RandomAccessFile(logFile, mode);
randomAccessFile.setLength(0);
- randomAccessFile.close();
} catch (SecurityException e) {
/* User doesn't have permission to change the length, so
* ignore this exception.
@@ -225,6 +235,14 @@ public class ResponseTimeLogParser {
* Could be a permission error. Log it.
*/
log.error("Unable to truncate response-time log file.", e);
+ } finally {
+ if (null != randomAccessFile) {
+ try {
+ randomAccessFile.close();
+ } catch (Exception e) {
+ log.error("Unable to close response-time log file.", e);
+ }
+ }
}
}
@@ -257,10 +275,8 @@ public class ResponseTimeLogParser {
}
public class LogEntry {
- public LogEntry(@NotNull
- String url, long startTime, long duration, @Nullable
- Integer statusCode, @Nullable
- String ipAddress) {
+ public LogEntry(@NotNull String url, long startTime, long duration, @Nullable Integer statusCode,
+ @Nullable String ipAddress) {
this.url = url;
this.startTime = startTime;
this.duration = duration;
commit 14c69192d35461bf0a4504290e4dfb410bd35879
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Wed Feb 17 09:53:12 2010 -0500
fix incorrect artifact name for dep
diff --git a/modules/enterprise/gui/base-perspective-war/pom.xml b/modules/enterprise/gui/base-perspective-war/pom.xml
index 1078a03..798a8ca 100644
--- a/modules/enterprise/gui/base-perspective-war/pom.xml
+++ b/modules/enterprise/gui/base-perspective-war/pom.xml
@@ -24,7 +24,7 @@
<dependency>
<groupId>org.rhq</groupId>
- <artifactId>rhq-enterprise-server-base-perspective-war-deps</artifactId>
+ <artifactId>rhq-enterprise-server-base-perspective-jar</artifactId>
<version>${project.version}</version>
<type>pom</type>
</dependency>
commit 037e333f07a2714ff48e4335b0c6612476e194ec
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Tue Feb 16 18:43:44 2010 -0500
create a new base-perspective-jar module, rather than using the warpath plugin, in order to pull the base perspective classes and libs into perspective WARs which extend the base perspective WAR
diff --git a/etc/samples/perspectives/sample-perspective/app/pom.xml b/etc/samples/perspectives/sample-perspective/app/pom.xml
index 7b4c684..eb531fc 100644
--- a/etc/samples/perspectives/sample-perspective/app/pom.xml
+++ b/etc/samples/perspectives/sample-perspective/app/pom.xml
@@ -28,7 +28,7 @@
<dependency>
<groupId>org.rhq</groupId>
<artifactId>rhq-enterprise-server-base-perspective-war</artifactId>
- <version>1.0.0-SNAPSHOT</version>
+ <version>3.0.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@@ -43,22 +43,24 @@
<dependency>
<groupId>org.rhq</groupId>
<artifactId>rhq-enterprise-server-base-perspective-war</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- <type>war</type>
+ <version>3.0.0-SNAPSHOT</version>
+ <type>war</type>
</dependency>
-
- <!-- This is used to pull in the war's classes and dependencies, which are not pulled in by the above dependency
- of type war (see http://jira.codehaus.org/browse/MNG-1991). -->
+
+ <!-- This is used to pull the base war's classes and dependencies into our
+ compile classpath, since they are not pulled in by the above war dependency
+ (see http://jira.codehaus.org/browse/MNG-1991). -->
<dependency>
<groupId>org.rhq</groupId>
- <artifactId>rhq-enterprise-server-base-perspective-war</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- <type>warpath</type>
+ <artifactId>rhq-enterprise-server-base-perspective-jar</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
</dependency>
+ <!-- Deps with provided scope are not transitive, so we need to specify
+ jsf-api.jar explicitly. -->
<dependency>
<groupId>javax.faces</groupId>
- <artifactId>jsf-api</artifactId>
+ <artifactId>jsf-api</artifactId>
<scope>provided</scope>
</dependency>
@@ -85,20 +87,6 @@
</configuration>
</plugin>
- <plugin>
- <groupId>org.appfuse</groupId>
- <artifactId>maven-warpath-plugin</artifactId>
- <version>2.0.2</version>
- <extensions>true</extensions>
- <executions>
- <execution>
- <goals>
- <goal>add-classes</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
-
</plugins>
</build>
diff --git a/modules/enterprise/gui/base-perspective-jar/pom.xml b/modules/enterprise/gui/base-perspective-jar/pom.xml
new file mode 100644
index 0000000..6514b7b
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-jar/pom.xml
@@ -0,0 +1,199 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-parent</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server-base-perspective-jar</artifactId>
+ <packaging>jar</packaging>
+
+ <name>RHQ Base Perspective Jar</name>
+ <description>the base perspective classes and dependencies</description>
+
+ <scm>
+ <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/gui/bas...</connection>
+ <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/gui/bas...</developerConnection>
+ </scm>
+
+ <properties>
+ <jsf.version>1.2_14</jsf.version>
+ <facelets.version>1.1.15.B1</facelets.version>
+ <!-- NOTE: Seam 2.1.2 and 2.2.0 can't be used in webapps deployed to the RHQ Server
+ due to https://jira.jboss.org/jira/browse/JBSEAM-4029. Seam 2.2.1 can be
+ used once it's released. -->
+ <seam.version>2.1.0.SP1</seam.version>
+ <jboss-el.version>1.0_02.CR5</jboss-el.version>
+ <richfaces.version>3.3.2.SR1</richfaces.version>
+ <rhq.version>3.0.0-SNAPSHOT</rhq.version>
+ </properties>
+
+ <dependencyManagement>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-remoting-client-api</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.sun.facelets</groupId>
+ <artifactId>jsf-facelets</artifactId>
+ <version>${facelets.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>jboss-seam</artifactId>
+ <version>${seam.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.el</groupId>
+ <artifactId>el-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>xml-apis</groupId>
+ <artifactId>xml-apis</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>jboss-seam-ui</artifactId>
+ <version>${seam.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.el</groupId>
+ <artifactId>jboss-el</artifactId>
+ <version>${jboss-el.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.el</groupId>
+ <artifactId>el-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.richfaces.framework</groupId>
+ <artifactId>richfaces-api</artifactId>
+ <version>${richfaces.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.richfaces.framework</groupId>
+ <artifactId>richfaces-impl</artifactId>
+ <version>${richfaces.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.richfaces.ui</groupId>
+ <artifactId>richfaces-ui</artifactId>
+ <version>${richfaces.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ <version>${jsf.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-gui</artifactId>
+ <version>${rhq.version}</version>
+ </dependency>
+
+ </dependencies>
+
+ </dependencyManagement>
+
+ <dependencies>
+
+ <!-- This will pull in all the jars we need for making remote calls to the RHQ Server. -->
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-remoting-client-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.sun.facelets</groupId>
+ <artifactId>jsf-facelets</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>jboss-seam</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>jboss-seam-ui</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>jboss-seam-debug</artifactId>
+ <version>${seam.version}</version>
+ <!-- we should be pulling this in directly ourselves, not relying
+ jboss-seam-debug to provide it -->
+ <exclusions>
+ <exclusion>
+ <groupId>com.sun.facelets</groupId>
+ <artifactId>jsf-facelets</artifactId>
+ </exclusion>
+ </exclusions>
+ <scope>runtime</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.el</groupId>
+ <artifactId>jboss-el</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.richfaces.framework</groupId>
+ <artifactId>richfaces-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.richfaces.framework</groupId>
+ <artifactId>richfaces-impl</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.richfaces.ui</groupId>
+ <artifactId>richfaces-ui</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-gui</artifactId>
+ </dependency>
+
+ </dependencies>
+
+ <repositories>
+ <repository>
+ <id>java.net-m1-releases</id>
+ <name>Java.net Maven1 Repository - for javax.faces, javax.el, com.sun.el, and com.sun.facelets releases</name>
+ <url>http://download.java.net/maven/1/</url>
+ <layout>legacy</layout>
+ </repository>
+ </repositories>
+
+</project>
diff --git a/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java b/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java
new file mode 100644
index 0000000..27629db
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java
@@ -0,0 +1,41 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2009-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.server.perspective;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.annotations.Create;
+import org.rhq.core.gui.table.bean.AbstractPagedDataUIBean;
+
+/**
+ * A base class for Seam components that utilize the RHQ remote API to retrieve a paged data set of objects, which are
+ * typically rendered using a dataTable component.
+ *
+ * @author Ian Springer
+ */
+public abstract class AbstractPerspectivePagedDataUIBean extends AbstractPagedDataUIBean {
+ protected PerspectiveClientUIBean perspectiveClient;
+
+ @Create
+ public void init() {
+ if (this.perspectiveClient == null) {
+ this.perspectiveClient = (PerspectiveClientUIBean) Component.getInstance(PerspectiveClientUIBean.class,
+ true);
+ }
+ }
+}
diff --git a/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java b/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java
new file mode 100644
index 0000000..b6ea66c
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java
@@ -0,0 +1,49 @@
+package org.rhq.enterprise.server.perspective;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.seam.annotations.web.RequestParameter;
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.criteria.ResourceCriteria;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.enterprise.client.RemoteClient;
+import org.rhq.enterprise.server.resource.ResourceManagerRemote;
+
+/**
+ * A base class for Seam components that utilize the RHQ remote API in the context of a specific Resource.
+ */
+public class AbstractPerspectiveResourceUIBean extends AbstractPerspectiveUIBean {
+ private final Log log = LogFactory.getLog(this.getClass());
+
+ @RequestParameter
+ private Integer rhqResourceId;
+
+ private Resource resource;
+
+ public Resource getResource() throws Exception {
+ if (this.resource == null) {
+ this.resource = loadResource();
+ log.debug("Retrieved current Resource " + this.resource);
+ }
+ return this.resource;
+ }
+
+ private Resource loadResource() throws Exception {
+ if (this.rhqResourceId == null) {
+ throw new IllegalStateException("The 'rhqResourceId' HTTP request parameter is required by this page.");
+ }
+ RemoteClient remoteClient = this.perspectiveClient.getRemoteClient();
+ Subject subject = this.perspectiveClient.getSubject();
+
+ // ***NOTE***: The javassist.NotFoundException stack traces that are logged by this call can be ignored.
+ ResourceManagerRemote resourceManager = remoteClient.getResourceManagerRemote();
+ ResourceCriteria resourceCriteria = new ResourceCriteria();
+ resourceCriteria.addFilterId(this.rhqResourceId);
+ PageList<Resource> resources = resourceManager.findResourcesByCriteria(subject, resourceCriteria);
+ if (resources.isEmpty()) {
+ throw new IllegalStateException("No Resource exists with the id " + this.rhqResourceId + ".");
+ }
+ return resources.get(0);
+ }
+}
diff --git a/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java b/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java
new file mode 100644
index 0000000..56034bb
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java
@@ -0,0 +1,41 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2009-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.server.perspective;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.annotations.Create;
+import org.jboss.seam.annotations.In;
+import org.jboss.seam.faces.FacesMessages;
+
+/**
+ * A base class for Seam components that utilize the RHQ remote API.
+ *
+ * @author Ian Springer
+ */
+public abstract class AbstractPerspectiveUIBean {
+ @In
+ protected FacesMessages facesMessages;
+
+ protected PerspectiveClientUIBean perspectiveClient;
+
+ @Create
+ public void init() {
+ this.perspectiveClient = (PerspectiveClientUIBean) Component.getInstance(PerspectiveClientUIBean.class, true);
+ }
+}
\ No newline at end of file
diff --git a/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java b/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java
new file mode 100644
index 0000000..59c9c63
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-jar/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java
@@ -0,0 +1,161 @@
+package org.rhq.enterprise.server.perspective;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.AutoCreate;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.web.RequestParameter;
+import org.jboss.seam.core.Conversation;
+import org.jetbrains.annotations.NotNull;
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.enterprise.client.RemoteClient;
+import org.rhq.enterprise.server.auth.SubjectManagerRemote;
+
+/**
+ * @author Ian Springer
+ */
+(a)Name(PerspectiveClientUIBean.NAME)
+(a)Scope(ScopeType.CONVERSATION)
+@AutoCreate
+public class PerspectiveClientUIBean {
+ public static final String NAME = "PerspectiveClientUIBean";
+
+ private static final String DEFAULT_SERVER_HOST = "127.0.0.1";
+ private static final int DEFAULT_SERVER_PORT = 7080;
+ private static final String DEFAULT_USERNAME = "rhqadmin";
+ private static final String DEFAULT_PASSWORD = "rhqadmin";
+
+ private final Log log = LogFactory.getLog(this.getClass());
+
+ @RequestParameter
+ private String rhqServerHost;
+ private String serverHost;
+
+ @RequestParameter
+ private Integer rhqServerPort;
+ private Integer serverPort;
+
+ @RequestParameter
+ private String rhqUsername;
+ private String username;
+
+ @RequestParameter
+ private String rhqPassword;
+ private String password;
+
+ @RequestParameter
+ private Integer rhqSessionId;
+
+ private RemoteClient remoteClient;
+ private Subject subject;
+ private String coreGuiBaseUrl;
+
+ @NotNull
+ public RemoteClient getRemoteClient() throws Exception {
+ if (this.remoteClient == null) {
+ this.remoteClient = new RemoteClient(null, getServerHost(), getServerPort());
+ }
+ if (!this.remoteClient.isConnected()) {
+ try {
+ this.remoteClient.connect();
+ } catch (Exception e) {
+ this.remoteClient = null;
+ log.info("Ending perspective client Conversation with id " + Conversation.instance().getId() + "...");
+ Conversation.instance().end();
+ throw e;
+ }
+ Conversation.instance().begin();
+ log.info("Began perspective client Conversation with id " + Conversation.instance().getId() + ".");
+ }
+ return this.remoteClient;
+ }
+
+ /**
+ * Returns the currently logged in RHQ user.
+ *
+ * @return the currently logged in RHQ user
+ *
+ * @throws Exception if we are unable to obtain the Subject - hopefully this will encourage callers to set a
+ * FacesMessage and return null to give the user a friendlier error
+ */
+ @NotNull
+ public Subject getSubject() throws Exception {
+ if (subject == null) {
+ RemoteClient remoteClient = getRemoteClient();
+ // ***NOTE***: The javassist.NotFoundException stack traces that are logged by this call can be ignored.
+ SubjectManagerRemote subjectManager = remoteClient.getSubjectManagerRemote();
+ if (this.rhqSessionId != null) {
+ log.info("Retrieving subject for user [" + getUsername() + "] and sessionId [" + this.rhqSessionId + "]...");
+ this.subject = subjectManager.getSubjectByNameAndSessionId(getUsername(), this.rhqSessionId);
+ } else {
+ log.info("Logging in as user [" + getUsername() + "] with password [" + getPassword() + "]...");
+ this.subject = subjectManager.login(getUsername(), getPassword());
+ }
+ }
+ return this.subject;
+ }
+
+ @NotNull
+ public String getCoreGuiBaseUrl() throws Exception {
+ if (this.coreGuiBaseUrl == null) {
+ RemoteClient remoteClient = getRemoteClient();
+ Subject subject = getSubject();
+ PerspectiveManagerRemote perspectiveManager = remoteClient.getPerspectiveManagerRemote();
+ this.coreGuiBaseUrl = perspectiveManager.getRootUrl(subject, true, false);
+ }
+ return this.coreGuiBaseUrl;
+ }
+
+ @NotNull
+ private String getServerHost() {
+ if (this.serverHost == null) {
+ if (this.rhqServerHost != null) {
+ this.serverHost = this.rhqServerHost;
+ } else {
+ return DEFAULT_SERVER_HOST;
+ }
+ } else {
+ if (this.rhqServerHost != null && this.serverHost.equals(this.rhqServerHost)) {
+
+ }
+ }
+ return this.serverHost;
+ }
+
+ private int getServerPort() {
+ if (this.serverPort == null) {
+ if (this.rhqServerPort != null) {
+ this.serverPort = this.rhqServerPort;
+ } else {
+ return DEFAULT_SERVER_PORT;
+ }
+ }
+ return this.serverPort;
+ }
+
+ @NotNull
+ private String getUsername() {
+ if (this.username == null) {
+ if (this.rhqUsername != null) {
+ this.username = this.rhqUsername;
+ } else {
+ return DEFAULT_USERNAME;
+ }
+ }
+ return this.username;
+ }
+
+ @NotNull
+ private String getPassword() {
+ if (this.password == null) {
+ if (this.rhqPassword != null) {
+ this.password = this.rhqPassword;
+ } else {
+ return DEFAULT_PASSWORD;
+ }
+ }
+ return this.password;
+ }
+}
diff --git a/modules/enterprise/gui/base-perspective-jar/src/main/resources/seam.properties b/modules/enterprise/gui/base-perspective-jar/src/main/resources/seam.properties
new file mode 100644
index 0000000..b97c770
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-jar/src/main/resources/seam.properties
@@ -0,0 +1,3 @@
+# NOTE: The presence of this file tells Seam to scan this WAR for Seam
+# components (i.e. classes with Name annotations) and to deploy
+# any that it finds.
diff --git a/modules/enterprise/gui/base-perspective-war/pom.xml b/modules/enterprise/gui/base-perspective-war/pom.xml
index 1f2ed83..1078a03 100644
--- a/modules/enterprise/gui/base-perspective-war/pom.xml
+++ b/modules/enterprise/gui/base-perspective-war/pom.xml
@@ -20,169 +20,13 @@
<developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/gui/bas...</developerConnection>
</scm>
- <properties>
- <jsf.version>1.2_14</jsf.version>
- <facelets.version>1.1.15.B1</facelets.version>
- <!-- NOTE: Seam 2.1.2 and 2.2.0 can't be used in webapps deployed to the RHQ Server
- due to https://jira.jboss.org/jira/browse/JBSEAM-4029. Seam 2.2.1 can be
- used once it's released. -->
- <seam.version>2.1.0.SP1</seam.version>
- <jboss-el.version>1.0_02.CR5</jboss-el.version>
- <richfaces.version>3.3.2.SR1</richfaces.version>
- <rhq.version>3.0.0-SNAPSHOT</rhq.version>
- </properties>
-
- <dependencyManagement>
-
- <dependencies>
-
- <dependency>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-remoting-client-api</artifactId>
- <version>${project.parent.version}</version>
- </dependency>
-
- <dependency>
- <groupId>com.sun.facelets</groupId>
- <artifactId>jsf-facelets</artifactId>
- <version>${facelets.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.seam</groupId>
- <artifactId>jboss-seam</artifactId>
- <version>${seam.version}</version>
- <exclusions>
- <exclusion>
- <groupId>javax.el</groupId>
- <artifactId>el-api</artifactId>
- </exclusion>
- <exclusion>
- <groupId>xml-apis</groupId>
- <artifactId>xml-apis</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.seam</groupId>
- <artifactId>jboss-seam-ui</artifactId>
- <version>${seam.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.el</groupId>
- <artifactId>jboss-el</artifactId>
- <version>${jboss-el.version}</version>
- <exclusions>
- <exclusion>
- <groupId>javax.el</groupId>
- <artifactId>el-api</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.richfaces.framework</groupId>
- <artifactId>richfaces-api</artifactId>
- <version>${richfaces.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.richfaces.framework</groupId>
- <artifactId>richfaces-impl</artifactId>
- <version>${richfaces.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.richfaces.ui</groupId>
- <artifactId>richfaces-ui</artifactId>
- <version>${richfaces.version}</version>
- </dependency>
-
- <dependency>
- <groupId>javax.faces</groupId>
- <artifactId>jsf-api</artifactId>
- <version>${jsf.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-core-gui</artifactId>
- <version>${rhq.version}</version>
- </dependency>
-
- </dependencies>
-
- </dependencyManagement>
-
<dependencies>
- <!-- This will pull in all the jars we need for making remote calls to the RHQ Server. -->
- <dependency>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-remoting-client-api</artifactId>
- </dependency>
-
- <dependency>
- <groupId>com.sun.facelets</groupId>
- <artifactId>jsf-facelets</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.seam</groupId>
- <artifactId>jboss-seam</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.seam</groupId>
- <artifactId>jboss-seam-ui</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.seam</groupId>
- <artifactId>jboss-seam-debug</artifactId>
- <version>${seam.version}</version>
- <!-- we should be pulling this in directly ourselves, not relying
- jboss-seam-debug to provide it -->
- <exclusions>
- <exclusion>
- <groupId>com.sun.facelets</groupId>
- <artifactId>jsf-facelets</artifactId>
- </exclusion>
- </exclusions>
- <scope>runtime</scope>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.el</groupId>
- <artifactId>jboss-el</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.richfaces.framework</groupId>
- <artifactId>richfaces-api</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.richfaces.framework</groupId>
- <artifactId>richfaces-impl</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.richfaces.ui</groupId>
- <artifactId>richfaces-ui</artifactId>
- </dependency>
-
- <dependency>
- <groupId>javax.faces</groupId>
- <artifactId>jsf-api</artifactId>
- <scope>provided</scope>
- </dependency>
-
<dependency>
<groupId>org.rhq</groupId>
- <artifactId>rhq-core-gui</artifactId>
+ <artifactId>rhq-enterprise-server-base-perspective-war-deps</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
</dependency>
</dependencies>
@@ -219,14 +63,5 @@
</plugins>
</build>
-
- <repositories>
- <repository>
- <id>java.net-m1-releases</id>
- <name>Java.net Maven1 Repository - for javax.faces, javax.el, com.sun.el, and com.sun.facelets releases</name>
- <url>http://download.java.net/maven/1/</url>
- <layout>legacy</layout>
- </repository>
- </repositories>
</project>
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java b/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java
deleted file mode 100644
index 27629db..0000000
--- a/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2009-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.server.perspective;
-
-import org.jboss.seam.Component;
-import org.jboss.seam.annotations.Create;
-import org.rhq.core.gui.table.bean.AbstractPagedDataUIBean;
-
-/**
- * A base class for Seam components that utilize the RHQ remote API to retrieve a paged data set of objects, which are
- * typically rendered using a dataTable component.
- *
- * @author Ian Springer
- */
-public abstract class AbstractPerspectivePagedDataUIBean extends AbstractPagedDataUIBean {
- protected PerspectiveClientUIBean perspectiveClient;
-
- @Create
- public void init() {
- if (this.perspectiveClient == null) {
- this.perspectiveClient = (PerspectiveClientUIBean) Component.getInstance(PerspectiveClientUIBean.class,
- true);
- }
- }
-}
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java b/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java
deleted file mode 100644
index b6ea66c..0000000
--- a/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package org.rhq.enterprise.server.perspective;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jboss.seam.annotations.web.RequestParameter;
-import org.rhq.core.domain.auth.Subject;
-import org.rhq.core.domain.criteria.ResourceCriteria;
-import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.util.PageList;
-import org.rhq.enterprise.client.RemoteClient;
-import org.rhq.enterprise.server.resource.ResourceManagerRemote;
-
-/**
- * A base class for Seam components that utilize the RHQ remote API in the context of a specific Resource.
- */
-public class AbstractPerspectiveResourceUIBean extends AbstractPerspectiveUIBean {
- private final Log log = LogFactory.getLog(this.getClass());
-
- @RequestParameter
- private Integer rhqResourceId;
-
- private Resource resource;
-
- public Resource getResource() throws Exception {
- if (this.resource == null) {
- this.resource = loadResource();
- log.debug("Retrieved current Resource " + this.resource);
- }
- return this.resource;
- }
-
- private Resource loadResource() throws Exception {
- if (this.rhqResourceId == null) {
- throw new IllegalStateException("The 'rhqResourceId' HTTP request parameter is required by this page.");
- }
- RemoteClient remoteClient = this.perspectiveClient.getRemoteClient();
- Subject subject = this.perspectiveClient.getSubject();
-
- // ***NOTE***: The javassist.NotFoundException stack traces that are logged by this call can be ignored.
- ResourceManagerRemote resourceManager = remoteClient.getResourceManagerRemote();
- ResourceCriteria resourceCriteria = new ResourceCriteria();
- resourceCriteria.addFilterId(this.rhqResourceId);
- PageList<Resource> resources = resourceManager.findResourcesByCriteria(subject, resourceCriteria);
- if (resources.isEmpty()) {
- throw new IllegalStateException("No Resource exists with the id " + this.rhqResourceId + ".");
- }
- return resources.get(0);
- }
-}
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java b/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java
deleted file mode 100644
index 56034bb..0000000
--- a/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2009-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.server.perspective;
-
-import org.jboss.seam.Component;
-import org.jboss.seam.annotations.Create;
-import org.jboss.seam.annotations.In;
-import org.jboss.seam.faces.FacesMessages;
-
-/**
- * A base class for Seam components that utilize the RHQ remote API.
- *
- * @author Ian Springer
- */
-public abstract class AbstractPerspectiveUIBean {
- @In
- protected FacesMessages facesMessages;
-
- protected PerspectiveClientUIBean perspectiveClient;
-
- @Create
- public void init() {
- this.perspectiveClient = (PerspectiveClientUIBean) Component.getInstance(PerspectiveClientUIBean.class, true);
- }
-}
\ No newline at end of file
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java b/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java
deleted file mode 100644
index 59c9c63..0000000
--- a/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java
+++ /dev/null
@@ -1,161 +0,0 @@
-package org.rhq.enterprise.server.perspective;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jboss.seam.ScopeType;
-import org.jboss.seam.annotations.AutoCreate;
-import org.jboss.seam.annotations.Name;
-import org.jboss.seam.annotations.Scope;
-import org.jboss.seam.annotations.web.RequestParameter;
-import org.jboss.seam.core.Conversation;
-import org.jetbrains.annotations.NotNull;
-import org.rhq.core.domain.auth.Subject;
-import org.rhq.enterprise.client.RemoteClient;
-import org.rhq.enterprise.server.auth.SubjectManagerRemote;
-
-/**
- * @author Ian Springer
- */
-(a)Name(PerspectiveClientUIBean.NAME)
-(a)Scope(ScopeType.CONVERSATION)
-@AutoCreate
-public class PerspectiveClientUIBean {
- public static final String NAME = "PerspectiveClientUIBean";
-
- private static final String DEFAULT_SERVER_HOST = "127.0.0.1";
- private static final int DEFAULT_SERVER_PORT = 7080;
- private static final String DEFAULT_USERNAME = "rhqadmin";
- private static final String DEFAULT_PASSWORD = "rhqadmin";
-
- private final Log log = LogFactory.getLog(this.getClass());
-
- @RequestParameter
- private String rhqServerHost;
- private String serverHost;
-
- @RequestParameter
- private Integer rhqServerPort;
- private Integer serverPort;
-
- @RequestParameter
- private String rhqUsername;
- private String username;
-
- @RequestParameter
- private String rhqPassword;
- private String password;
-
- @RequestParameter
- private Integer rhqSessionId;
-
- private RemoteClient remoteClient;
- private Subject subject;
- private String coreGuiBaseUrl;
-
- @NotNull
- public RemoteClient getRemoteClient() throws Exception {
- if (this.remoteClient == null) {
- this.remoteClient = new RemoteClient(null, getServerHost(), getServerPort());
- }
- if (!this.remoteClient.isConnected()) {
- try {
- this.remoteClient.connect();
- } catch (Exception e) {
- this.remoteClient = null;
- log.info("Ending perspective client Conversation with id " + Conversation.instance().getId() + "...");
- Conversation.instance().end();
- throw e;
- }
- Conversation.instance().begin();
- log.info("Began perspective client Conversation with id " + Conversation.instance().getId() + ".");
- }
- return this.remoteClient;
- }
-
- /**
- * Returns the currently logged in RHQ user.
- *
- * @return the currently logged in RHQ user
- *
- * @throws Exception if we are unable to obtain the Subject - hopefully this will encourage callers to set a
- * FacesMessage and return null to give the user a friendlier error
- */
- @NotNull
- public Subject getSubject() throws Exception {
- if (subject == null) {
- RemoteClient remoteClient = getRemoteClient();
- // ***NOTE***: The javassist.NotFoundException stack traces that are logged by this call can be ignored.
- SubjectManagerRemote subjectManager = remoteClient.getSubjectManagerRemote();
- if (this.rhqSessionId != null) {
- log.info("Retrieving subject for user [" + getUsername() + "] and sessionId [" + this.rhqSessionId + "]...");
- this.subject = subjectManager.getSubjectByNameAndSessionId(getUsername(), this.rhqSessionId);
- } else {
- log.info("Logging in as user [" + getUsername() + "] with password [" + getPassword() + "]...");
- this.subject = subjectManager.login(getUsername(), getPassword());
- }
- }
- return this.subject;
- }
-
- @NotNull
- public String getCoreGuiBaseUrl() throws Exception {
- if (this.coreGuiBaseUrl == null) {
- RemoteClient remoteClient = getRemoteClient();
- Subject subject = getSubject();
- PerspectiveManagerRemote perspectiveManager = remoteClient.getPerspectiveManagerRemote();
- this.coreGuiBaseUrl = perspectiveManager.getRootUrl(subject, true, false);
- }
- return this.coreGuiBaseUrl;
- }
-
- @NotNull
- private String getServerHost() {
- if (this.serverHost == null) {
- if (this.rhqServerHost != null) {
- this.serverHost = this.rhqServerHost;
- } else {
- return DEFAULT_SERVER_HOST;
- }
- } else {
- if (this.rhqServerHost != null && this.serverHost.equals(this.rhqServerHost)) {
-
- }
- }
- return this.serverHost;
- }
-
- private int getServerPort() {
- if (this.serverPort == null) {
- if (this.rhqServerPort != null) {
- this.serverPort = this.rhqServerPort;
- } else {
- return DEFAULT_SERVER_PORT;
- }
- }
- return this.serverPort;
- }
-
- @NotNull
- private String getUsername() {
- if (this.username == null) {
- if (this.rhqUsername != null) {
- this.username = this.rhqUsername;
- } else {
- return DEFAULT_USERNAME;
- }
- }
- return this.username;
- }
-
- @NotNull
- private String getPassword() {
- if (this.password == null) {
- if (this.rhqPassword != null) {
- this.password = this.rhqPassword;
- } else {
- return DEFAULT_PASSWORD;
- }
- }
- return this.password;
- }
-}
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/resources/seam.properties b/modules/enterprise/gui/base-perspective-war/src/main/resources/seam.properties
deleted file mode 100644
index b97c770..0000000
--- a/modules/enterprise/gui/base-perspective-war/src/main/resources/seam.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-# NOTE: The presence of this file tells Seam to scan this WAR for Seam
-# components (i.e. classes with Name annotations) and to deploy
-# any that it finds.
diff --git a/modules/enterprise/gui/pom.xml b/modules/enterprise/gui/pom.xml
index 1e39958..223b230 100644
--- a/modules/enterprise/gui/pom.xml
+++ b/modules/enterprise/gui/pom.xml
@@ -34,6 +34,7 @@
<modules>
<module>portal-war</module>
<module>installer-war</module>
+ <module>base-perspective-jar</module>
<module>base-perspective-war</module>
<module>webdav-war</module>
<module>content_http-war</module>
@@ -44,3 +45,4 @@
</profiles>
</project>
+
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/pom.xml b/modules/enterprise/server/plugins/perspectives/policy/app/pom.xml
index 27aa634..19af416 100644
--- a/modules/enterprise/server/plugins/perspectives/policy/app/pom.xml
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/pom.xml
@@ -45,16 +45,18 @@
<version>${project.version}</version>
<type>war</type>
</dependency>
-
- <!-- This is used to pull in the war's classes and dependencies, which are not pulled in by the above dependency
- of type war (see http://jira.codehaus.org/browse/MNG-1991). -->
+
+ <!-- This is used to pull the base war's classes and dependencies into our
+ compile classpath, since they are not pulled in by the above war dependency
+ (see http://jira.codehaus.org/browse/MNG-1991). -->
<dependency>
<groupId>org.rhq</groupId>
- <artifactId>rhq-enterprise-server-base-perspective-war</artifactId>
- <version>${project.version}</version>
- <type>warpath</type>
+ <artifactId>rhq-enterprise-server-base-perspective-jar</artifactId>
+ <version>${project.version}</version>
</dependency>
-
+
+ <!-- Deps with provided scope are not transitive, so we need to specify
+ jsf-api.jar explicitly. -->
<dependency>
<groupId>javax.faces</groupId>
<artifactId>jsf-api</artifactId>
@@ -84,20 +86,6 @@
</configuration>
</plugin>
- <plugin>
- <groupId>org.appfuse</groupId>
- <artifactId>maven-warpath-plugin</artifactId>
- <version>2.0.2</version>
- <extensions>true</extensions>
- <executions>
- <execution>
- <goals>
- <goal>add-classes</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
-
</plugins>
</build>
commit 3a8393f5940b3702d1d48679a565e08bc7e7275d
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Tue Feb 16 17:04:46 2010 -0500
move base-perspective-war module from etc/modules/ to modules/enterprise/gui/; deploy policy perspective by default
diff --git a/modules/enterprise/gui/base-perspective-war/pom.xml b/modules/enterprise/gui/base-perspective-war/pom.xml
new file mode 100644
index 0000000..1f2ed83
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-war/pom.xml
@@ -0,0 +1,232 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-parent</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server-base-perspective-war</artifactId>
+ <packaging>war</packaging>
+
+ <name>RHQ Base Perspective War</name>
+ <description>an abstract WAR that can be used by the maven war plugin as an overlay (i.e. base) for a perspective WAR</description>
+
+ <scm>
+ <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/gui/bas...</connection>
+ <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/gui/bas...</developerConnection>
+ </scm>
+
+ <properties>
+ <jsf.version>1.2_14</jsf.version>
+ <facelets.version>1.1.15.B1</facelets.version>
+ <!-- NOTE: Seam 2.1.2 and 2.2.0 can't be used in webapps deployed to the RHQ Server
+ due to https://jira.jboss.org/jira/browse/JBSEAM-4029. Seam 2.2.1 can be
+ used once it's released. -->
+ <seam.version>2.1.0.SP1</seam.version>
+ <jboss-el.version>1.0_02.CR5</jboss-el.version>
+ <richfaces.version>3.3.2.SR1</richfaces.version>
+ <rhq.version>3.0.0-SNAPSHOT</rhq.version>
+ </properties>
+
+ <dependencyManagement>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-remoting-client-api</artifactId>
+ <version>${project.parent.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.sun.facelets</groupId>
+ <artifactId>jsf-facelets</artifactId>
+ <version>${facelets.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>jboss-seam</artifactId>
+ <version>${seam.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.el</groupId>
+ <artifactId>el-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>xml-apis</groupId>
+ <artifactId>xml-apis</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>jboss-seam-ui</artifactId>
+ <version>${seam.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.el</groupId>
+ <artifactId>jboss-el</artifactId>
+ <version>${jboss-el.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.el</groupId>
+ <artifactId>el-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.richfaces.framework</groupId>
+ <artifactId>richfaces-api</artifactId>
+ <version>${richfaces.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.richfaces.framework</groupId>
+ <artifactId>richfaces-impl</artifactId>
+ <version>${richfaces.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.richfaces.ui</groupId>
+ <artifactId>richfaces-ui</artifactId>
+ <version>${richfaces.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ <version>${jsf.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-gui</artifactId>
+ <version>${rhq.version}</version>
+ </dependency>
+
+ </dependencies>
+
+ </dependencyManagement>
+
+ <dependencies>
+
+ <!-- This will pull in all the jars we need for making remote calls to the RHQ Server. -->
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-remoting-client-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.sun.facelets</groupId>
+ <artifactId>jsf-facelets</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>jboss-seam</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>jboss-seam-ui</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.seam</groupId>
+ <artifactId>jboss-seam-debug</artifactId>
+ <version>${seam.version}</version>
+ <!-- we should be pulling this in directly ourselves, not relying
+ jboss-seam-debug to provide it -->
+ <exclusions>
+ <exclusion>
+ <groupId>com.sun.facelets</groupId>
+ <artifactId>jsf-facelets</artifactId>
+ </exclusion>
+ </exclusions>
+ <scope>runtime</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.el</groupId>
+ <artifactId>jboss-el</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.richfaces.framework</groupId>
+ <artifactId>richfaces-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.richfaces.framework</groupId>
+ <artifactId>richfaces-impl</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.richfaces.ui</groupId>
+ <artifactId>richfaces-ui</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-core-gui</artifactId>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <finalName>rhq-base-perspective</finalName>
+
+ <plugins>
+
+ <plugin>
+ <artifactId>maven-war-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifest>
+ <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+ <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+ </manifest>
+ <manifestEntries>
+ <Build-Number>${buildNumber}</Build-Number>
+ </manifestEntries>
+ </archive>
+ <webResources>
+ <resource>
+ <filtering>true</filtering>
+ <directory>${basedir}/src/main/webapp</directory>
+ <includes>
+ <include>**/*.properties</include>
+ </includes>
+ </resource>
+ </webResources>
+ </configuration>
+ </plugin>
+
+ </plugins>
+
+ </build>
+
+ <repositories>
+ <repository>
+ <id>java.net-m1-releases</id>
+ <name>Java.net Maven1 Repository - for javax.faces, javax.el, com.sun.el, and com.sun.facelets releases</name>
+ <url>http://download.java.net/maven/1/</url>
+ <layout>legacy</layout>
+ </repository>
+ </repositories>
+
+</project>
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java b/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java
new file mode 100644
index 0000000..27629db
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java
@@ -0,0 +1,41 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2009-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.server.perspective;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.annotations.Create;
+import org.rhq.core.gui.table.bean.AbstractPagedDataUIBean;
+
+/**
+ * A base class for Seam components that utilize the RHQ remote API to retrieve a paged data set of objects, which are
+ * typically rendered using a dataTable component.
+ *
+ * @author Ian Springer
+ */
+public abstract class AbstractPerspectivePagedDataUIBean extends AbstractPagedDataUIBean {
+ protected PerspectiveClientUIBean perspectiveClient;
+
+ @Create
+ public void init() {
+ if (this.perspectiveClient == null) {
+ this.perspectiveClient = (PerspectiveClientUIBean) Component.getInstance(PerspectiveClientUIBean.class,
+ true);
+ }
+ }
+}
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java b/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java
new file mode 100644
index 0000000..b6ea66c
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java
@@ -0,0 +1,49 @@
+package org.rhq.enterprise.server.perspective;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.seam.annotations.web.RequestParameter;
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.criteria.ResourceCriteria;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.enterprise.client.RemoteClient;
+import org.rhq.enterprise.server.resource.ResourceManagerRemote;
+
+/**
+ * A base class for Seam components that utilize the RHQ remote API in the context of a specific Resource.
+ */
+public class AbstractPerspectiveResourceUIBean extends AbstractPerspectiveUIBean {
+ private final Log log = LogFactory.getLog(this.getClass());
+
+ @RequestParameter
+ private Integer rhqResourceId;
+
+ private Resource resource;
+
+ public Resource getResource() throws Exception {
+ if (this.resource == null) {
+ this.resource = loadResource();
+ log.debug("Retrieved current Resource " + this.resource);
+ }
+ return this.resource;
+ }
+
+ private Resource loadResource() throws Exception {
+ if (this.rhqResourceId == null) {
+ throw new IllegalStateException("The 'rhqResourceId' HTTP request parameter is required by this page.");
+ }
+ RemoteClient remoteClient = this.perspectiveClient.getRemoteClient();
+ Subject subject = this.perspectiveClient.getSubject();
+
+ // ***NOTE***: The javassist.NotFoundException stack traces that are logged by this call can be ignored.
+ ResourceManagerRemote resourceManager = remoteClient.getResourceManagerRemote();
+ ResourceCriteria resourceCriteria = new ResourceCriteria();
+ resourceCriteria.addFilterId(this.rhqResourceId);
+ PageList<Resource> resources = resourceManager.findResourcesByCriteria(subject, resourceCriteria);
+ if (resources.isEmpty()) {
+ throw new IllegalStateException("No Resource exists with the id " + this.rhqResourceId + ".");
+ }
+ return resources.get(0);
+ }
+}
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java b/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java
new file mode 100644
index 0000000..56034bb
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java
@@ -0,0 +1,41 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2009-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.server.perspective;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.annotations.Create;
+import org.jboss.seam.annotations.In;
+import org.jboss.seam.faces.FacesMessages;
+
+/**
+ * A base class for Seam components that utilize the RHQ remote API.
+ *
+ * @author Ian Springer
+ */
+public abstract class AbstractPerspectiveUIBean {
+ @In
+ protected FacesMessages facesMessages;
+
+ protected PerspectiveClientUIBean perspectiveClient;
+
+ @Create
+ public void init() {
+ this.perspectiveClient = (PerspectiveClientUIBean) Component.getInstance(PerspectiveClientUIBean.class, true);
+ }
+}
\ No newline at end of file
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java b/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java
new file mode 100644
index 0000000..59c9c63
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java
@@ -0,0 +1,161 @@
+package org.rhq.enterprise.server.perspective;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.AutoCreate;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.web.RequestParameter;
+import org.jboss.seam.core.Conversation;
+import org.jetbrains.annotations.NotNull;
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.enterprise.client.RemoteClient;
+import org.rhq.enterprise.server.auth.SubjectManagerRemote;
+
+/**
+ * @author Ian Springer
+ */
+(a)Name(PerspectiveClientUIBean.NAME)
+(a)Scope(ScopeType.CONVERSATION)
+@AutoCreate
+public class PerspectiveClientUIBean {
+ public static final String NAME = "PerspectiveClientUIBean";
+
+ private static final String DEFAULT_SERVER_HOST = "127.0.0.1";
+ private static final int DEFAULT_SERVER_PORT = 7080;
+ private static final String DEFAULT_USERNAME = "rhqadmin";
+ private static final String DEFAULT_PASSWORD = "rhqadmin";
+
+ private final Log log = LogFactory.getLog(this.getClass());
+
+ @RequestParameter
+ private String rhqServerHost;
+ private String serverHost;
+
+ @RequestParameter
+ private Integer rhqServerPort;
+ private Integer serverPort;
+
+ @RequestParameter
+ private String rhqUsername;
+ private String username;
+
+ @RequestParameter
+ private String rhqPassword;
+ private String password;
+
+ @RequestParameter
+ private Integer rhqSessionId;
+
+ private RemoteClient remoteClient;
+ private Subject subject;
+ private String coreGuiBaseUrl;
+
+ @NotNull
+ public RemoteClient getRemoteClient() throws Exception {
+ if (this.remoteClient == null) {
+ this.remoteClient = new RemoteClient(null, getServerHost(), getServerPort());
+ }
+ if (!this.remoteClient.isConnected()) {
+ try {
+ this.remoteClient.connect();
+ } catch (Exception e) {
+ this.remoteClient = null;
+ log.info("Ending perspective client Conversation with id " + Conversation.instance().getId() + "...");
+ Conversation.instance().end();
+ throw e;
+ }
+ Conversation.instance().begin();
+ log.info("Began perspective client Conversation with id " + Conversation.instance().getId() + ".");
+ }
+ return this.remoteClient;
+ }
+
+ /**
+ * Returns the currently logged in RHQ user.
+ *
+ * @return the currently logged in RHQ user
+ *
+ * @throws Exception if we are unable to obtain the Subject - hopefully this will encourage callers to set a
+ * FacesMessage and return null to give the user a friendlier error
+ */
+ @NotNull
+ public Subject getSubject() throws Exception {
+ if (subject == null) {
+ RemoteClient remoteClient = getRemoteClient();
+ // ***NOTE***: The javassist.NotFoundException stack traces that are logged by this call can be ignored.
+ SubjectManagerRemote subjectManager = remoteClient.getSubjectManagerRemote();
+ if (this.rhqSessionId != null) {
+ log.info("Retrieving subject for user [" + getUsername() + "] and sessionId [" + this.rhqSessionId + "]...");
+ this.subject = subjectManager.getSubjectByNameAndSessionId(getUsername(), this.rhqSessionId);
+ } else {
+ log.info("Logging in as user [" + getUsername() + "] with password [" + getPassword() + "]...");
+ this.subject = subjectManager.login(getUsername(), getPassword());
+ }
+ }
+ return this.subject;
+ }
+
+ @NotNull
+ public String getCoreGuiBaseUrl() throws Exception {
+ if (this.coreGuiBaseUrl == null) {
+ RemoteClient remoteClient = getRemoteClient();
+ Subject subject = getSubject();
+ PerspectiveManagerRemote perspectiveManager = remoteClient.getPerspectiveManagerRemote();
+ this.coreGuiBaseUrl = perspectiveManager.getRootUrl(subject, true, false);
+ }
+ return this.coreGuiBaseUrl;
+ }
+
+ @NotNull
+ private String getServerHost() {
+ if (this.serverHost == null) {
+ if (this.rhqServerHost != null) {
+ this.serverHost = this.rhqServerHost;
+ } else {
+ return DEFAULT_SERVER_HOST;
+ }
+ } else {
+ if (this.rhqServerHost != null && this.serverHost.equals(this.rhqServerHost)) {
+
+ }
+ }
+ return this.serverHost;
+ }
+
+ private int getServerPort() {
+ if (this.serverPort == null) {
+ if (this.rhqServerPort != null) {
+ this.serverPort = this.rhqServerPort;
+ } else {
+ return DEFAULT_SERVER_PORT;
+ }
+ }
+ return this.serverPort;
+ }
+
+ @NotNull
+ private String getUsername() {
+ if (this.username == null) {
+ if (this.rhqUsername != null) {
+ this.username = this.rhqUsername;
+ } else {
+ return DEFAULT_USERNAME;
+ }
+ }
+ return this.username;
+ }
+
+ @NotNull
+ private String getPassword() {
+ if (this.password == null) {
+ if (this.rhqPassword != null) {
+ this.password = this.rhqPassword;
+ } else {
+ return DEFAULT_PASSWORD;
+ }
+ }
+ return this.password;
+ }
+}
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/resources/seam.properties b/modules/enterprise/gui/base-perspective-war/src/main/resources/seam.properties
new file mode 100644
index 0000000..b97c770
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-war/src/main/resources/seam.properties
@@ -0,0 +1,3 @@
+# NOTE: The presence of this file tells Seam to scan this WAR for Seam
+# components (i.e. classes with Name annotations) and to deploy
+# any that it finds.
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/components.xml b/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/components.xml
new file mode 100644
index 0000000..4631d2e
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/components.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<components xmlns="http://jboss.com/products/seam/components"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:security="http://jboss.com/products/seam/security"
+ xsi:schemaLocation=
+ "http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.0.xsd
+ http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.0.xsd">
+
+ <component name="org.jboss.seam.core.init">
+ <property name="debug">false</property>
+ <!-- enable only when needed -->
+ <property name="transactionManagementEnabled">false</property>
+ </component>
+
+</components>
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/faces-config.xml b/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/faces-config.xml
new file mode 100644
index 0000000..f584c01
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/faces-config.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+
+<faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
+
+ <!-- If your perspective application utilizes JSF managed beans then copy
+ this file to your application and add declarations as needed.
+
+ <managed-bean>
+ <managed-bean-name>MyBeanName</managed-bean-name>
+ <managed-bean-class>my.package.MyBeanName</managed-bean-class>
+ <managed-bean-scope>session</managed-bean-scope>
+ </managed-bean>
+
+ -->
+
+ <!-- If youe perspective application utilizes JSF navigation rules then copy
+ this file to your application and add rules as needed.
+
+ <navigation-rule>
+ <from-tree-id></from-tree-id>
+ <navigation-case></navigation-case>
+ </navigation-rule>
+
+ -->
+
+</faces-config>
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/includes/pageControls.xhtml b/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/includes/pageControls.xhtml
new file mode 100644
index 0000000..2faad02
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/includes/pageControls.xhtml
@@ -0,0 +1,103 @@
+<?xml version="1.0"?>
+
+<ui:composition
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:fn="http://java.sun.com/jsp/jstl/functions"
+ xmlns:a4j="http://richfaces.org/a4j"
+ xmlns:rich="http://richfaces.org/rich"
+ xmlns:rhq="http://rhq-project.org/rhq"
+ xmlns:onc="http://jboss.org/on/component">
+
+ <ui:remove>
+ Usage: The following parameters must be set in the calling page:
+
+ pagedDataUIBean - an instance of AbstractPagedDataUIBean, which provides access to a data model, a page
+ control, and page control settings (valid page sizes, etc.)
+ dataTableName - name of the data table to be controlled
+ </ui:remove>
+
+ <h:panelGroup layout="block" style="float: right; margin-right: 30px">
+ <ui:param name="dataScrollerName" value="#{dataTableName}Scroller"/>
+ <ui:param name="dataModel" value="#{pagedDataUIBean.dataModel}"/>
+ <ui:param name="pageControl" value="#{pagedDataUIBean.pageControl}"/>
+
+ <table>
+ <tr>
+ <td nowrap="nowrap">
+
+ <h:outputText value="Total: #{dataModel.rowCount}"
+ style="margin-right: 2em; font-weight: bold; "/>
+
+ <h:panelGroup layout="block" rendered="#{dataModel.rowCount gt pagedDataUIBean.minimumPageSize
+ and pageControl.pageSize gt 0}">
+ <h:outputText value="Items Per Page: #{pageControl.pageSize}"
+ style="font-weight: bold; "
+ rendered="#{pagedDataUIBean.pageSizeCount le 1}"/>
+ <h:panelGroup layout="block" rendered="#{pagedDataUIBean.pageSizeCount gt 1}">
+ <h:outputText value="Items Per Page:"
+ style="margin-right: 1em; font-weight: bold; "/>
+ <h:selectOneListbox id="currentPageSize"
+ size="1"
+ value="#{pageControl.pageSize}">
+ <a4j:support event="onchange"
+ status="commonStatus"
+ reRender="#{dataTableName}, #{dataScrollerName}"/>
+ <f:selectItems value="#{pagedDataUIBean.pageSizeSelectItems}"/>
+ </h:selectOneListbox>
+ </h:panelGroup>
+ </h:panelGroup>
+
+ </td>
+
+ <td nowrap="nowrap">
+
+ <rich:datascroller id="#{dataScrollerName}"
+ for="#{dataTableName}"
+ status="commonStatus"
+ rendered="#{pageControl.pageSize gt 0}"
+ selectedStyle="font-weight: bold;"
+ inactiveStyle="font-weight: normal;"
+ stepControls="show"
+ fastControls="hide"
+ boundaryControls="hide"
+ maxPages="#{pagedDataUIBean.dataScrollerMaxPages}"
+ page="#{pagedDataUIBean.dataScrollerPage}">
+ <f:facet name="next">
+ <h:panelGroup>
+ <h:graphicImage value="http://127.0.0.1:7080/images/tbb_pageright.gif"
+ style="padding: 0px 5px 0px 7px;"/>
+ </h:panelGroup>
+ </f:facet>
+ <f:facet name="next_disabled">
+ <h:panelGroup>
+ <h:graphicImage value="http://127.0.0.1:7080/images/tbb_pageright_gray.gif"
+ style="padding: 0px 5px 0px 7px;"/>
+ </h:panelGroup>
+ </f:facet>
+ <f:facet name="previous">
+ <h:panelGroup>
+ <h:graphicImage value="http://127.0.0.1:7080/images/tbb_pageleft.gif"
+ style="padding: 0px 5px 0px 7px;"/>
+ </h:panelGroup>
+ </f:facet>
+ <f:facet name="previous_disabled">
+ <h:panelGroup>
+ <h:graphicImage value="http://127.0.0.1:7080/images/tbb_pageleft_gray.gif"
+ style="padding: 0px 5px 0px 7px;"/>
+ </h:panelGroup>
+ </f:facet>
+ </rich:datascroller>
+
+ </td>
+ </tr>
+ </table>
+
+ </h:panelGroup>
+
+ <div style="clear: both;"/>
+
+</ui:composition>
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/jboss-web.xml b/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/jboss-web.xml
new file mode 100644
index 0000000..d4b66f4
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/jboss-web.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE jboss-web PUBLIC
+ "-//JBoss//DTD Web Application 4.2//EN"
+ "http://www.jboss.org/j2ee/dtd/jboss-web_4_2.dtd">
+
+<!-- This is just a sample as needed by the Sample Perspective. Copy this file to your
+ application and modify the loader as needed.
+ -->
+
+<jboss-web>
+
+ <class-loading>
+ <loader-repository>
+ org.rhq:loader=sample-perspective
+ <loader-repository-config>java2ParentDelegation=false</loader-repository-config>
+ </loader-repository>
+ </class-loading>
+
+</jboss-web>
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/templates/mainTemplate.xhtml b/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/templates/mainTemplate.xhtml
new file mode 100644
index 0000000..21ec05f
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/templates/mainTemplate.xhtml
@@ -0,0 +1,70 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:fn="http://java.sun.com/jsp/jstl/functions"
+ xmlns:a4j="http://richfaces.org/a4j"
+ xmlns:rich="http://richfaces.org/rich"
+ xmlns:rhq="http://rhq-project.org/rhq"
+ xmlns:onc="http://jboss.org/on/component">
+
+<ui:remove>
+ <!-- Set the content type to "text/html" (overriding the default of "application/xhtml+xml") to force
+Firefox and other Gecko-based browsers to render the page in "Almost Standards" (i.e. transitional) mode. -->
+</ui:remove>
+<f:view contentType="text/html; charset=UTF-8">
+
+<head>
+ <title>${msg["product.shortName"]} - #{(!empty pageTitle) ? pageTitle : defaultPageTitle}</title>
+
+ <ui:insert name="metaHeaders"/>
+
+ <link rel="stylesheet" type="text/css" media="screen" href="#{PerspectiveClientUIBean.coreGuiBaseUrl}/css/win.css"/>
+ <link rel="stylesheet" type="text/css" media="screen" href="#{PerspectiveClientUIBean.coreGuiBaseUrl}/css/form-style.css"/>
+ <link rel="stylesheet" type="text/css" media="screen" href="#{PerspectiveClientUIBean.coreGuiBaseUrl}/css/menu.css"/>
+
+ <!-- Trims up the headers of RF toggle panel headers -->
+ <style type="text/css">
+ .BlockTitle {
+ padding-top: 3px;
+ padding-bottom: 3px;
+ }
+
+ HTML, BODY {
+ overflow: hidden;
+ }
+ </style>
+
+ <link rel="stylesheet" type="text/css" media="screen" href="#{PerspectiveClientUIBean.coreGuiBaseUrl}/css/tabular.css"/>
+ <link rel="stylesheet" type="text/css" media="screen" href="#{PerspectiveClientUIBean.coreGuiBaseUrl}/css/layout.css"/>
+
+ <script type="text/javascript">
+ var imagePath = "/images/";
+ </script>
+
+</head>
+
+<body bgcolor="#FFFFFF" style="height: 100%;">
+
+<h:panelGroup layout="block" style="font-weight: bold; margin-left: 15px; margin-bottom: 15px;">
+ <ui:insert name="breadcrumbs"/>
+</h:panelGroup>
+
+<rich:messages globalOnly="true"
+ infoClass="InfoBlock"
+ warnClass="WarnBlock"
+ errorClass="ErrorBlock"
+ fatalClass="FatalBlock" />
+
+<ui:insert name="body"/>
+
+</body>
+</f:view>
+</html>
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/web.xml b/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..fb66dca
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-war/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<web-app xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ version="2.5">
+
+ <display-name>RHQ Perspective Webapp</display-name>
+
+ <!--=== Seam ===-->
+
+ <listener>
+ <listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
+ </listener>
+
+ <!-- From Seam docs: The Seam master filter must be the first filter specified
+ in web.xml. This ensures it is run first. -->
+ <filter>
+ <filter-name>Seam Filter</filter-name>
+ <filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>
+ </filter>
+ <filter-mapping>
+ <filter-name>Seam Filter</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
+
+ <servlet>
+ <servlet-name>Seam Resource Servlet</servlet-name>
+ <servlet-class>org.jboss.seam.servlet.SeamResourceServlet</servlet-class>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>Seam Resource Servlet</servlet-name>
+ <url-pattern>/seam/resource/*</url-pattern>
+ </servlet-mapping>
+
+ <!-- flags for debugging during development -->
+ <context-param>
+ <param-name>com.sun.faces.validateXml</param-name>
+ <param-value>false</param-value>
+ </context-param>
+ <context-param>
+ <param-name>com.sun.faces.verifyObjects</param-name>
+ <param-value>false</param-value>
+ </context-param>
+
+ <!--=== JSF spec ===-->
+
+ <servlet>
+ <servlet-name>Faces Servlet</servlet-name>
+ <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <!-- serve Facelets pages (*.xhtml) via the JSF servlet -->
+ <servlet-mapping>
+ <servlet-name>Faces Servlet</servlet-name>
+ <url-pattern>*.seam</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name>Faces Servlet</servlet-name>
+ <url-pattern>*.xhtml</url-pattern>
+ </servlet-mapping>
+
+ <!-- the suffix for files containing JSF content (default is ".jsp") -->
+ <context-param>
+ <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
+ <param-value>.xhtml</param-value>
+ </context-param>
+
+ <!-- see http://www.jroller.com/page/mert?entry=state_saving_method_client_side for an explanation of the below param -->
+ <context-param>
+ <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
+ <param-value>server</param-value>
+ </context-param>
+
+ <!--=== Facelets ===-->
+
+ <!-- enable special debug output for development -->
+ <context-param>
+ <param-name>facelets.DEVELOPMENT</param-name>
+ <param-value>true</param-value>
+ </context-param>
+
+ <!--=== RichFaces ===-->
+
+ <!-- From Seam docs: If RichFaces is used in your project, Seam will install
+ the RichFaces Ajax filter for you, making sure to install it before all
+ other built-in filters. You don't need to install the RichFaces Ajax
+ filter in web.xml yourself. -->
+
+ <context-param>
+ <param-name>org.ajax4jsf.VIEW_HANDLERS</param-name>
+ <param-value>com.sun.facelets.FaceletViewHandler</param-value>
+ </context-param>
+
+ <!-- Temporarily uncomment the below context-param to disable compression of JavaScript files associated with
+ RichFaces components in order to debug those script files. -->
+ <context-param>
+ <param-name>org.ajax4jsf.COMPRESS_SCRIPT</param-name>
+ <param-value>false</param-value>
+ </context-param>
+
+ <welcome-file-list>
+ <welcome-file>index.xhtml</welcome-file>
+ </welcome-file-list>
+
+</web-app>
diff --git a/modules/enterprise/gui/base-perspective-war/src/main/webapp/index.xhtml b/modules/enterprise/gui/base-perspective-war/src/main/webapp/index.xhtml
new file mode 100644
index 0000000..a461356
--- /dev/null
+++ b/modules/enterprise/gui/base-perspective-war/src/main/webapp/index.xhtml
@@ -0,0 +1,36 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:s="http://jboss.com/products/seam/taglib"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:a4j="http://richfaces.org/a4j"
+ xmlns:rich="http://richfaces.org/rich">
+
+ <head>
+ <title>
+ Perspective Web Application
+ </title>
+ </head>
+
+ <body style="background-color: #FF66CC">
+
+ <ui:remove>
+ <!-- Set the content type to "text/html" to ensure "application/xhtml+xml", which would put Firefox and
+ other Gecko-based browsers into XML mode (which requires pages to be well-formed XML), is not used.
+ We also specify the charset/encoding here, since we cannot specify it via the xml prolog, since
+ including an xml prolog causes IE6 to go into the undesirable "quirks mode".
+ (see https://jira.jboss.org/jira/browse/EMBJOPR-19) -->
+ </ui:remove>
+
+ <f:view contentType="text/html; charset=UTF-8">
+
+ <h1>YOUR CONTENT GOES HERE.</h1>
+
+ </f:view>
+
+ </body>
+
+</html>
+
diff --git a/modules/enterprise/server/ear/pom.xml b/modules/enterprise/server/ear/pom.xml
index 175420d..26b0ab5 100644
--- a/modules/enterprise/server/ear/pom.xml
+++ b/modules/enterprise/server/ear/pom.xml
@@ -219,7 +219,7 @@
<executions>
<execution>
- <id>copy-core-plugins</id>
+ <id>copy-core-agent-plugins</id>
<phase>process-resources</phase>
<goals>
<goal>copy</goal>
@@ -252,7 +252,7 @@
</execution>
<execution>
- <id>copy-rhq-serverplugins</id>
+ <id>copy-core-server-plugins</id>
<phase>process-resources</phase>
<goals>
<goal>copy</goal>
@@ -284,6 +284,12 @@
<version>${project.version}</version>
</artifactItem>
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server-policy-perspective</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
</artifactItems>
<outputDirectory>${earDirectory}/rhq-serverplugins</outputDirectory>
</configuration>
commit 7406c901785c89068720da295aebfd83968a7f33
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Tue Feb 16 17:03:02 2010 -0500
move base-perspective-war module from etc/modules/ to modules/enterprise/gui/; deploy policy perspective by default
diff --git a/etc/modules/base-perspective-war/pom.xml b/etc/modules/base-perspective-war/pom.xml
deleted file mode 100644
index fa64c2f..0000000
--- a/etc/modules/base-perspective-war/pom.xml
+++ /dev/null
@@ -1,233 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-parent</artifactId>
- <version>3.0.0-SNAPSHOT</version>
- </parent>
-
- <groupId>org.rhq</groupId>
- <artifactId>rhq-enterprise-server-base-perspective-war</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- <packaging>war</packaging>
-
- <name>RHQ Base Perspective War</name>
- <description>an abstract WAR that can be used by the maven war plugin as an overlay (i.e. base) for a perspective WAR</description>
-
- <scm>
- <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/etc/modules/base-perspecti...</connection>
- <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/etc/modules/base-perspecti...</developerConnection>
- </scm>
-
- <properties>
- <jsf.version>1.2_14</jsf.version>
- <facelets.version>1.1.15.B1</facelets.version>
- <!-- NOTE: Seam 2.1.2 and 2.2.0 can't be used in webapps deployed to the RHQ Server
- due to https://jira.jboss.org/jira/browse/JBSEAM-4029. Seam 2.2.1 can be
- used once it's released. -->
- <seam.version>2.1.0.SP1</seam.version>
- <jboss-el.version>1.0_02.CR5</jboss-el.version>
- <richfaces.version>3.3.2.SR1</richfaces.version>
- <rhq.version>3.0.0-SNAPSHOT</rhq.version>
- </properties>
-
- <dependencyManagement>
-
- <dependencies>
-
- <dependency>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-remoting-client-api</artifactId>
- <version>${project.parent.version}</version>
- </dependency>
-
- <dependency>
- <groupId>com.sun.facelets</groupId>
- <artifactId>jsf-facelets</artifactId>
- <version>${facelets.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.seam</groupId>
- <artifactId>jboss-seam</artifactId>
- <version>${seam.version}</version>
- <exclusions>
- <exclusion>
- <groupId>javax.el</groupId>
- <artifactId>el-api</artifactId>
- </exclusion>
- <exclusion>
- <groupId>xml-apis</groupId>
- <artifactId>xml-apis</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.seam</groupId>
- <artifactId>jboss-seam-ui</artifactId>
- <version>${seam.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.el</groupId>
- <artifactId>jboss-el</artifactId>
- <version>${jboss-el.version}</version>
- <exclusions>
- <exclusion>
- <groupId>javax.el</groupId>
- <artifactId>el-api</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.richfaces.framework</groupId>
- <artifactId>richfaces-api</artifactId>
- <version>${richfaces.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.richfaces.framework</groupId>
- <artifactId>richfaces-impl</artifactId>
- <version>${richfaces.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.richfaces.ui</groupId>
- <artifactId>richfaces-ui</artifactId>
- <version>${richfaces.version}</version>
- </dependency>
-
- <dependency>
- <groupId>javax.faces</groupId>
- <artifactId>jsf-api</artifactId>
- <version>${jsf.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-core-gui</artifactId>
- <version>${rhq.version}</version>
- </dependency>
-
- </dependencies>
-
- </dependencyManagement>
-
- <dependencies>
-
- <!-- This will pull in all the jars we need for making remote calls to the RHQ Server. -->
- <dependency>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-remoting-client-api</artifactId>
- </dependency>
-
- <dependency>
- <groupId>com.sun.facelets</groupId>
- <artifactId>jsf-facelets</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.seam</groupId>
- <artifactId>jboss-seam</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.seam</groupId>
- <artifactId>jboss-seam-ui</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.seam</groupId>
- <artifactId>jboss-seam-debug</artifactId>
- <version>${seam.version}</version>
- <!-- we should be pulling this in directly ourselves, not relying
- jboss-seam-debug to provide it -->
- <exclusions>
- <exclusion>
- <groupId>com.sun.facelets</groupId>
- <artifactId>jsf-facelets</artifactId>
- </exclusion>
- </exclusions>
- <scope>runtime</scope>
- </dependency>
-
- <dependency>
- <groupId>org.jboss.el</groupId>
- <artifactId>jboss-el</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.richfaces.framework</groupId>
- <artifactId>richfaces-api</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.richfaces.framework</groupId>
- <artifactId>richfaces-impl</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.richfaces.ui</groupId>
- <artifactId>richfaces-ui</artifactId>
- </dependency>
-
- <dependency>
- <groupId>javax.faces</groupId>
- <artifactId>jsf-api</artifactId>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-core-gui</artifactId>
- </dependency>
-
- </dependencies>
-
- <build>
- <finalName>rhq-base-perspective</finalName>
-
- <plugins>
-
- <plugin>
- <artifactId>maven-war-plugin</artifactId>
- <configuration>
- <archive>
- <manifest>
- <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
- <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
- </manifest>
- <manifestEntries>
- <Build-Number>${buildNumber}</Build-Number>
- </manifestEntries>
- </archive>
- <webResources>
- <resource>
- <filtering>true</filtering>
- <directory>${basedir}/src/main/webapp</directory>
- <includes>
- <include>**/*.properties</include>
- </includes>
- </resource>
- </webResources>
- </configuration>
- </plugin>
-
- </plugins>
-
- </build>
-
- <repositories>
- <repository>
- <id>java.net-m1-releases</id>
- <name>Java.net Maven1 Repository - for javax.faces, javax.el, com.sun.el, and com.sun.facelets releases</name>
- <url>http://download.java.net/maven/1/</url>
- <layout>legacy</layout>
- </repository>
- </repositories>
-
-</project>
diff --git a/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java b/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java
deleted file mode 100644
index 27629db..0000000
--- a/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2009-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.server.perspective;
-
-import org.jboss.seam.Component;
-import org.jboss.seam.annotations.Create;
-import org.rhq.core.gui.table.bean.AbstractPagedDataUIBean;
-
-/**
- * A base class for Seam components that utilize the RHQ remote API to retrieve a paged data set of objects, which are
- * typically rendered using a dataTable component.
- *
- * @author Ian Springer
- */
-public abstract class AbstractPerspectivePagedDataUIBean extends AbstractPagedDataUIBean {
- protected PerspectiveClientUIBean perspectiveClient;
-
- @Create
- public void init() {
- if (this.perspectiveClient == null) {
- this.perspectiveClient = (PerspectiveClientUIBean) Component.getInstance(PerspectiveClientUIBean.class,
- true);
- }
- }
-}
diff --git a/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java b/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java
deleted file mode 100644
index b6ea66c..0000000
--- a/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveResourceUIBean.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package org.rhq.enterprise.server.perspective;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jboss.seam.annotations.web.RequestParameter;
-import org.rhq.core.domain.auth.Subject;
-import org.rhq.core.domain.criteria.ResourceCriteria;
-import org.rhq.core.domain.resource.Resource;
-import org.rhq.core.domain.util.PageList;
-import org.rhq.enterprise.client.RemoteClient;
-import org.rhq.enterprise.server.resource.ResourceManagerRemote;
-
-/**
- * A base class for Seam components that utilize the RHQ remote API in the context of a specific Resource.
- */
-public class AbstractPerspectiveResourceUIBean extends AbstractPerspectiveUIBean {
- private final Log log = LogFactory.getLog(this.getClass());
-
- @RequestParameter
- private Integer rhqResourceId;
-
- private Resource resource;
-
- public Resource getResource() throws Exception {
- if (this.resource == null) {
- this.resource = loadResource();
- log.debug("Retrieved current Resource " + this.resource);
- }
- return this.resource;
- }
-
- private Resource loadResource() throws Exception {
- if (this.rhqResourceId == null) {
- throw new IllegalStateException("The 'rhqResourceId' HTTP request parameter is required by this page.");
- }
- RemoteClient remoteClient = this.perspectiveClient.getRemoteClient();
- Subject subject = this.perspectiveClient.getSubject();
-
- // ***NOTE***: The javassist.NotFoundException stack traces that are logged by this call can be ignored.
- ResourceManagerRemote resourceManager = remoteClient.getResourceManagerRemote();
- ResourceCriteria resourceCriteria = new ResourceCriteria();
- resourceCriteria.addFilterId(this.rhqResourceId);
- PageList<Resource> resources = resourceManager.findResourcesByCriteria(subject, resourceCriteria);
- if (resources.isEmpty()) {
- throw new IllegalStateException("No Resource exists with the id " + this.rhqResourceId + ".");
- }
- return resources.get(0);
- }
-}
diff --git a/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java b/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java
deleted file mode 100644
index 56034bb..0000000
--- a/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectiveUIBean.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2009-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.server.perspective;
-
-import org.jboss.seam.Component;
-import org.jboss.seam.annotations.Create;
-import org.jboss.seam.annotations.In;
-import org.jboss.seam.faces.FacesMessages;
-
-/**
- * A base class for Seam components that utilize the RHQ remote API.
- *
- * @author Ian Springer
- */
-public abstract class AbstractPerspectiveUIBean {
- @In
- protected FacesMessages facesMessages;
-
- protected PerspectiveClientUIBean perspectiveClient;
-
- @Create
- public void init() {
- this.perspectiveClient = (PerspectiveClientUIBean) Component.getInstance(PerspectiveClientUIBean.class, true);
- }
-}
\ No newline at end of file
diff --git a/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java b/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java
deleted file mode 100644
index 59c9c63..0000000
--- a/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/PerspectiveClientUIBean.java
+++ /dev/null
@@ -1,161 +0,0 @@
-package org.rhq.enterprise.server.perspective;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jboss.seam.ScopeType;
-import org.jboss.seam.annotations.AutoCreate;
-import org.jboss.seam.annotations.Name;
-import org.jboss.seam.annotations.Scope;
-import org.jboss.seam.annotations.web.RequestParameter;
-import org.jboss.seam.core.Conversation;
-import org.jetbrains.annotations.NotNull;
-import org.rhq.core.domain.auth.Subject;
-import org.rhq.enterprise.client.RemoteClient;
-import org.rhq.enterprise.server.auth.SubjectManagerRemote;
-
-/**
- * @author Ian Springer
- */
-(a)Name(PerspectiveClientUIBean.NAME)
-(a)Scope(ScopeType.CONVERSATION)
-@AutoCreate
-public class PerspectiveClientUIBean {
- public static final String NAME = "PerspectiveClientUIBean";
-
- private static final String DEFAULT_SERVER_HOST = "127.0.0.1";
- private static final int DEFAULT_SERVER_PORT = 7080;
- private static final String DEFAULT_USERNAME = "rhqadmin";
- private static final String DEFAULT_PASSWORD = "rhqadmin";
-
- private final Log log = LogFactory.getLog(this.getClass());
-
- @RequestParameter
- private String rhqServerHost;
- private String serverHost;
-
- @RequestParameter
- private Integer rhqServerPort;
- private Integer serverPort;
-
- @RequestParameter
- private String rhqUsername;
- private String username;
-
- @RequestParameter
- private String rhqPassword;
- private String password;
-
- @RequestParameter
- private Integer rhqSessionId;
-
- private RemoteClient remoteClient;
- private Subject subject;
- private String coreGuiBaseUrl;
-
- @NotNull
- public RemoteClient getRemoteClient() throws Exception {
- if (this.remoteClient == null) {
- this.remoteClient = new RemoteClient(null, getServerHost(), getServerPort());
- }
- if (!this.remoteClient.isConnected()) {
- try {
- this.remoteClient.connect();
- } catch (Exception e) {
- this.remoteClient = null;
- log.info("Ending perspective client Conversation with id " + Conversation.instance().getId() + "...");
- Conversation.instance().end();
- throw e;
- }
- Conversation.instance().begin();
- log.info("Began perspective client Conversation with id " + Conversation.instance().getId() + ".");
- }
- return this.remoteClient;
- }
-
- /**
- * Returns the currently logged in RHQ user.
- *
- * @return the currently logged in RHQ user
- *
- * @throws Exception if we are unable to obtain the Subject - hopefully this will encourage callers to set a
- * FacesMessage and return null to give the user a friendlier error
- */
- @NotNull
- public Subject getSubject() throws Exception {
- if (subject == null) {
- RemoteClient remoteClient = getRemoteClient();
- // ***NOTE***: The javassist.NotFoundException stack traces that are logged by this call can be ignored.
- SubjectManagerRemote subjectManager = remoteClient.getSubjectManagerRemote();
- if (this.rhqSessionId != null) {
- log.info("Retrieving subject for user [" + getUsername() + "] and sessionId [" + this.rhqSessionId + "]...");
- this.subject = subjectManager.getSubjectByNameAndSessionId(getUsername(), this.rhqSessionId);
- } else {
- log.info("Logging in as user [" + getUsername() + "] with password [" + getPassword() + "]...");
- this.subject = subjectManager.login(getUsername(), getPassword());
- }
- }
- return this.subject;
- }
-
- @NotNull
- public String getCoreGuiBaseUrl() throws Exception {
- if (this.coreGuiBaseUrl == null) {
- RemoteClient remoteClient = getRemoteClient();
- Subject subject = getSubject();
- PerspectiveManagerRemote perspectiveManager = remoteClient.getPerspectiveManagerRemote();
- this.coreGuiBaseUrl = perspectiveManager.getRootUrl(subject, true, false);
- }
- return this.coreGuiBaseUrl;
- }
-
- @NotNull
- private String getServerHost() {
- if (this.serverHost == null) {
- if (this.rhqServerHost != null) {
- this.serverHost = this.rhqServerHost;
- } else {
- return DEFAULT_SERVER_HOST;
- }
- } else {
- if (this.rhqServerHost != null && this.serverHost.equals(this.rhqServerHost)) {
-
- }
- }
- return this.serverHost;
- }
-
- private int getServerPort() {
- if (this.serverPort == null) {
- if (this.rhqServerPort != null) {
- this.serverPort = this.rhqServerPort;
- } else {
- return DEFAULT_SERVER_PORT;
- }
- }
- return this.serverPort;
- }
-
- @NotNull
- private String getUsername() {
- if (this.username == null) {
- if (this.rhqUsername != null) {
- this.username = this.rhqUsername;
- } else {
- return DEFAULT_USERNAME;
- }
- }
- return this.username;
- }
-
- @NotNull
- private String getPassword() {
- if (this.password == null) {
- if (this.rhqPassword != null) {
- this.password = this.rhqPassword;
- } else {
- return DEFAULT_PASSWORD;
- }
- }
- return this.password;
- }
-}
diff --git a/etc/modules/base-perspective-war/src/main/resources/seam.properties b/etc/modules/base-perspective-war/src/main/resources/seam.properties
deleted file mode 100644
index b97c770..0000000
--- a/etc/modules/base-perspective-war/src/main/resources/seam.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-# NOTE: The presence of this file tells Seam to scan this WAR for Seam
-# components (i.e. classes with Name annotations) and to deploy
-# any that it finds.
diff --git a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/components.xml b/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/components.xml
deleted file mode 100644
index 4631d2e..0000000
--- a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/components.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<components xmlns="http://jboss.com/products/seam/components"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:security="http://jboss.com/products/seam/security"
- xsi:schemaLocation=
- "http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.0.xsd
- http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.0.xsd">
-
- <component name="org.jboss.seam.core.init">
- <property name="debug">false</property>
- <!-- enable only when needed -->
- <property name="transactionManagementEnabled">false</property>
- </component>
-
-</components>
diff --git a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/faces-config.xml b/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/faces-config.xml
deleted file mode 100644
index f584c01..0000000
--- a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/faces-config.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0"?>
-
-<faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
-
- <!-- If your perspective application utilizes JSF managed beans then copy
- this file to your application and add declarations as needed.
-
- <managed-bean>
- <managed-bean-name>MyBeanName</managed-bean-name>
- <managed-bean-class>my.package.MyBeanName</managed-bean-class>
- <managed-bean-scope>session</managed-bean-scope>
- </managed-bean>
-
- -->
-
- <!-- If youe perspective application utilizes JSF navigation rules then copy
- this file to your application and add rules as needed.
-
- <navigation-rule>
- <from-tree-id></from-tree-id>
- <navigation-case></navigation-case>
- </navigation-rule>
-
- -->
-
-</faces-config>
diff --git a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/includes/pageControls.xhtml b/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/includes/pageControls.xhtml
deleted file mode 100644
index 2faad02..0000000
--- a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/includes/pageControls.xhtml
+++ /dev/null
@@ -1,103 +0,0 @@
-<?xml version="1.0"?>
-
-<ui:composition
- xmlns="http://www.w3.org/1999/xhtml"
- xmlns:f="http://java.sun.com/jsf/core"
- xmlns:h="http://java.sun.com/jsf/html"
- xmlns:ui="http://java.sun.com/jsf/facelets"
- xmlns:c="http://java.sun.com/jstl/core"
- xmlns:fn="http://java.sun.com/jsp/jstl/functions"
- xmlns:a4j="http://richfaces.org/a4j"
- xmlns:rich="http://richfaces.org/rich"
- xmlns:rhq="http://rhq-project.org/rhq"
- xmlns:onc="http://jboss.org/on/component">
-
- <ui:remove>
- Usage: The following parameters must be set in the calling page:
-
- pagedDataUIBean - an instance of AbstractPagedDataUIBean, which provides access to a data model, a page
- control, and page control settings (valid page sizes, etc.)
- dataTableName - name of the data table to be controlled
- </ui:remove>
-
- <h:panelGroup layout="block" style="float: right; margin-right: 30px">
- <ui:param name="dataScrollerName" value="#{dataTableName}Scroller"/>
- <ui:param name="dataModel" value="#{pagedDataUIBean.dataModel}"/>
- <ui:param name="pageControl" value="#{pagedDataUIBean.pageControl}"/>
-
- <table>
- <tr>
- <td nowrap="nowrap">
-
- <h:outputText value="Total: #{dataModel.rowCount}"
- style="margin-right: 2em; font-weight: bold; "/>
-
- <h:panelGroup layout="block" rendered="#{dataModel.rowCount gt pagedDataUIBean.minimumPageSize
- and pageControl.pageSize gt 0}">
- <h:outputText value="Items Per Page: #{pageControl.pageSize}"
- style="font-weight: bold; "
- rendered="#{pagedDataUIBean.pageSizeCount le 1}"/>
- <h:panelGroup layout="block" rendered="#{pagedDataUIBean.pageSizeCount gt 1}">
- <h:outputText value="Items Per Page:"
- style="margin-right: 1em; font-weight: bold; "/>
- <h:selectOneListbox id="currentPageSize"
- size="1"
- value="#{pageControl.pageSize}">
- <a4j:support event="onchange"
- status="commonStatus"
- reRender="#{dataTableName}, #{dataScrollerName}"/>
- <f:selectItems value="#{pagedDataUIBean.pageSizeSelectItems}"/>
- </h:selectOneListbox>
- </h:panelGroup>
- </h:panelGroup>
-
- </td>
-
- <td nowrap="nowrap">
-
- <rich:datascroller id="#{dataScrollerName}"
- for="#{dataTableName}"
- status="commonStatus"
- rendered="#{pageControl.pageSize gt 0}"
- selectedStyle="font-weight: bold;"
- inactiveStyle="font-weight: normal;"
- stepControls="show"
- fastControls="hide"
- boundaryControls="hide"
- maxPages="#{pagedDataUIBean.dataScrollerMaxPages}"
- page="#{pagedDataUIBean.dataScrollerPage}">
- <f:facet name="next">
- <h:panelGroup>
- <h:graphicImage value="http://127.0.0.1:7080/images/tbb_pageright.gif"
- style="padding: 0px 5px 0px 7px;"/>
- </h:panelGroup>
- </f:facet>
- <f:facet name="next_disabled">
- <h:panelGroup>
- <h:graphicImage value="http://127.0.0.1:7080/images/tbb_pageright_gray.gif"
- style="padding: 0px 5px 0px 7px;"/>
- </h:panelGroup>
- </f:facet>
- <f:facet name="previous">
- <h:panelGroup>
- <h:graphicImage value="http://127.0.0.1:7080/images/tbb_pageleft.gif"
- style="padding: 0px 5px 0px 7px;"/>
- </h:panelGroup>
- </f:facet>
- <f:facet name="previous_disabled">
- <h:panelGroup>
- <h:graphicImage value="http://127.0.0.1:7080/images/tbb_pageleft_gray.gif"
- style="padding: 0px 5px 0px 7px;"/>
- </h:panelGroup>
- </f:facet>
- </rich:datascroller>
-
- </td>
- </tr>
- </table>
-
- </h:panelGroup>
-
- <div style="clear: both;"/>
-
-</ui:composition>
diff --git a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/jboss-web.xml b/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/jboss-web.xml
deleted file mode 100644
index d4b66f4..0000000
--- a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/jboss-web.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0"?>
-
-<!DOCTYPE jboss-web PUBLIC
- "-//JBoss//DTD Web Application 4.2//EN"
- "http://www.jboss.org/j2ee/dtd/jboss-web_4_2.dtd">
-
-<!-- This is just a sample as needed by the Sample Perspective. Copy this file to your
- application and modify the loader as needed.
- -->
-
-<jboss-web>
-
- <class-loading>
- <loader-repository>
- org.rhq:loader=sample-perspective
- <loader-repository-config>java2ParentDelegation=false</loader-repository-config>
- </loader-repository>
- </class-loading>
-
-</jboss-web>
diff --git a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/templates/mainTemplate.xhtml b/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/templates/mainTemplate.xhtml
deleted file mode 100644
index 21ec05f..0000000
--- a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/templates/mainTemplate.xhtml
+++ /dev/null
@@ -1,70 +0,0 @@
-<?xml version="1.0"?>
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-
-<html xmlns="http://www.w3.org/1999/xhtml"
- xmlns:f="http://java.sun.com/jsf/core"
- xmlns:h="http://java.sun.com/jsf/html"
- xmlns:ui="http://java.sun.com/jsf/facelets"
- xmlns:c="http://java.sun.com/jstl/core"
- xmlns:fn="http://java.sun.com/jsp/jstl/functions"
- xmlns:a4j="http://richfaces.org/a4j"
- xmlns:rich="http://richfaces.org/rich"
- xmlns:rhq="http://rhq-project.org/rhq"
- xmlns:onc="http://jboss.org/on/component">
-
-<ui:remove>
- <!-- Set the content type to "text/html" (overriding the default of "application/xhtml+xml") to force
-Firefox and other Gecko-based browsers to render the page in "Almost Standards" (i.e. transitional) mode. -->
-</ui:remove>
-<f:view contentType="text/html; charset=UTF-8">
-
-<head>
- <title>${msg["product.shortName"]} - #{(!empty pageTitle) ? pageTitle : defaultPageTitle}</title>
-
- <ui:insert name="metaHeaders"/>
-
- <link rel="stylesheet" type="text/css" media="screen" href="#{PerspectiveClientUIBean.coreGuiBaseUrl}/css/win.css"/>
- <link rel="stylesheet" type="text/css" media="screen" href="#{PerspectiveClientUIBean.coreGuiBaseUrl}/css/form-style.css"/>
- <link rel="stylesheet" type="text/css" media="screen" href="#{PerspectiveClientUIBean.coreGuiBaseUrl}/css/menu.css"/>
-
- <!-- Trims up the headers of RF toggle panel headers -->
- <style type="text/css">
- .BlockTitle {
- padding-top: 3px;
- padding-bottom: 3px;
- }
-
- HTML, BODY {
- overflow: hidden;
- }
- </style>
-
- <link rel="stylesheet" type="text/css" media="screen" href="#{PerspectiveClientUIBean.coreGuiBaseUrl}/css/tabular.css"/>
- <link rel="stylesheet" type="text/css" media="screen" href="#{PerspectiveClientUIBean.coreGuiBaseUrl}/css/layout.css"/>
-
- <script type="text/javascript">
- var imagePath = "/images/";
- </script>
-
-</head>
-
-<body bgcolor="#FFFFFF" style="height: 100%;">
-
-<h:panelGroup layout="block" style="font-weight: bold; margin-left: 15px; margin-bottom: 15px;">
- <ui:insert name="breadcrumbs"/>
-</h:panelGroup>
-
-<rich:messages globalOnly="true"
- infoClass="InfoBlock"
- warnClass="WarnBlock"
- errorClass="ErrorBlock"
- fatalClass="FatalBlock" />
-
-<ui:insert name="body"/>
-
-</body>
-</f:view>
-</html>
diff --git a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/web.xml b/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index fb66dca..0000000
--- a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,108 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<web-app xmlns="http://java.sun.com/xml/ns/javaee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
- version="2.5">
-
- <display-name>RHQ Perspective Webapp</display-name>
-
- <!--=== Seam ===-->
-
- <listener>
- <listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
- </listener>
-
- <!-- From Seam docs: The Seam master filter must be the first filter specified
- in web.xml. This ensures it is run first. -->
- <filter>
- <filter-name>Seam Filter</filter-name>
- <filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>Seam Filter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
-
- <servlet>
- <servlet-name>Seam Resource Servlet</servlet-name>
- <servlet-class>org.jboss.seam.servlet.SeamResourceServlet</servlet-class>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>Seam Resource Servlet</servlet-name>
- <url-pattern>/seam/resource/*</url-pattern>
- </servlet-mapping>
-
- <!-- flags for debugging during development -->
- <context-param>
- <param-name>com.sun.faces.validateXml</param-name>
- <param-value>false</param-value>
- </context-param>
- <context-param>
- <param-name>com.sun.faces.verifyObjects</param-name>
- <param-value>false</param-value>
- </context-param>
-
- <!--=== JSF spec ===-->
-
- <servlet>
- <servlet-name>Faces Servlet</servlet-name>
- <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <!-- serve Facelets pages (*.xhtml) via the JSF servlet -->
- <servlet-mapping>
- <servlet-name>Faces Servlet</servlet-name>
- <url-pattern>*.seam</url-pattern>
- </servlet-mapping>
-
- <servlet-mapping>
- <servlet-name>Faces Servlet</servlet-name>
- <url-pattern>*.xhtml</url-pattern>
- </servlet-mapping>
-
- <!-- the suffix for files containing JSF content (default is ".jsp") -->
- <context-param>
- <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
- <param-value>.xhtml</param-value>
- </context-param>
-
- <!-- see http://www.jroller.com/page/mert?entry=state_saving_method_client_side for an explanation of the below param -->
- <context-param>
- <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
- <param-value>server</param-value>
- </context-param>
-
- <!--=== Facelets ===-->
-
- <!-- enable special debug output for development -->
- <context-param>
- <param-name>facelets.DEVELOPMENT</param-name>
- <param-value>true</param-value>
- </context-param>
-
- <!--=== RichFaces ===-->
-
- <!-- From Seam docs: If RichFaces is used in your project, Seam will install
- the RichFaces Ajax filter for you, making sure to install it before all
- other built-in filters. You don't need to install the RichFaces Ajax
- filter in web.xml yourself. -->
-
- <context-param>
- <param-name>org.ajax4jsf.VIEW_HANDLERS</param-name>
- <param-value>com.sun.facelets.FaceletViewHandler</param-value>
- </context-param>
-
- <!-- Temporarily uncomment the below context-param to disable compression of JavaScript files associated with
- RichFaces components in order to debug those script files. -->
- <context-param>
- <param-name>org.ajax4jsf.COMPRESS_SCRIPT</param-name>
- <param-value>false</param-value>
- </context-param>
-
- <welcome-file-list>
- <welcome-file>index.xhtml</welcome-file>
- </welcome-file-list>
-
-</web-app>
diff --git a/etc/modules/base-perspective-war/src/main/webapp/index.xhtml b/etc/modules/base-perspective-war/src/main/webapp/index.xhtml
deleted file mode 100644
index a461356..0000000
--- a/etc/modules/base-perspective-war/src/main/webapp/index.xhtml
+++ /dev/null
@@ -1,36 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
- xmlns:h="http://java.sun.com/jsf/html"
- xmlns:f="http://java.sun.com/jsf/core"
- xmlns:s="http://jboss.com/products/seam/taglib"
- xmlns:ui="http://java.sun.com/jsf/facelets"
- xmlns:a4j="http://richfaces.org/a4j"
- xmlns:rich="http://richfaces.org/rich">
-
- <head>
- <title>
- Perspective Web Application
- </title>
- </head>
-
- <body style="background-color: #FF66CC">
-
- <ui:remove>
- <!-- Set the content type to "text/html" to ensure "application/xhtml+xml", which would put Firefox and
- other Gecko-based browsers into XML mode (which requires pages to be well-formed XML), is not used.
- We also specify the charset/encoding here, since we cannot specify it via the xml prolog, since
- including an xml prolog causes IE6 to go into the undesirable "quirks mode".
- (see https://jira.jboss.org/jira/browse/EMBJOPR-19) -->
- </ui:remove>
-
- <f:view contentType="text/html; charset=UTF-8">
-
- <h1>YOUR CONTENT GOES HERE.</h1>
-
- </f:view>
-
- </body>
-
-</html>
-
diff --git a/modules/enterprise/gui/pom.xml b/modules/enterprise/gui/pom.xml
index 0da70b7..1e39958 100644
--- a/modules/enterprise/gui/pom.xml
+++ b/modules/enterprise/gui/pom.xml
@@ -34,6 +34,7 @@
<modules>
<module>portal-war</module>
<module>installer-war</module>
+ <module>base-perspective-war</module>
<module>webdav-war</module>
<module>content_http-war</module>
<module>alert-migration</module>
diff --git a/modules/enterprise/pom.xml b/modules/enterprise/pom.xml
index 82e5209..7b3f967 100644
--- a/modules/enterprise/pom.xml
+++ b/modules/enterprise/pom.xml
@@ -61,9 +61,9 @@
<module>server/jar</module>
<module>server/safe-invoker</module>
<module>server/sars</module>
+ <module>remoting</module>
<module>gui</module>
<module>server/plugins</module>
- <module>remoting</module>
<module>server/ear</module>
<module>server/container-lib</module>
<module>server/container</module>
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/pom.xml b/modules/enterprise/server/plugins/perspectives/policy/app/pom.xml
index 3c53325..27aa634 100644
--- a/modules/enterprise/server/plugins/perspectives/policy/app/pom.xml
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/pom.xml
@@ -27,7 +27,7 @@
<dependency>
<groupId>org.rhq</groupId>
<artifactId>rhq-enterprise-server-base-perspective-war</artifactId>
- <version>1.0.0-SNAPSHOT</version>
+ <version>${project.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@@ -42,7 +42,7 @@
<dependency>
<groupId>org.rhq</groupId>
<artifactId>rhq-enterprise-server-base-perspective-war</artifactId>
- <version>1.0.0-SNAPSHOT</version>
+ <version>${project.version}</version>
<type>war</type>
</dependency>
@@ -51,7 +51,7 @@
<dependency>
<groupId>org.rhq</groupId>
<artifactId>rhq-enterprise-server-base-perspective-war</artifactId>
- <version>1.0.0-SNAPSHOT</version>
+ <version>${project.version}</version>
<type>warpath</type>
</dependency>
commit fe17e6f371b816d6b5cb453219246a18928c2f21
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Tue Feb 16 16:54:07 2010 -0500
add support for optional plugin profiles to ear/pom.xml and remove hudson module from linux-plugins profile in plugins/pom.xml
diff --git a/modules/enterprise/server/ear/pom.xml b/modules/enterprise/server/ear/pom.xml
index bb2ff06..175420d 100644
--- a/modules/enterprise/server/ear/pom.xml
+++ b/modules/enterprise/server/ear/pom.xml
@@ -219,7 +219,7 @@
<executions>
<execution>
- <id>copy-rhq-plugins</id>
+ <id>copy-core-plugins</id>
<phase>process-resources</phase>
<goals>
<goal>copy</goal>
@@ -229,159 +229,23 @@
<artifactItem>
<groupId>org.rhq</groupId>
- <artifactId>rhq-agent-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-aliases-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-apache-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-augeas-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-cron-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-database-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-grub-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-hosts-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-hudson-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-iis-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <!--
- TODO: Uncomment once errors from RHQ-1226 are fixed. <artifactItem>
- <groupId>org.rhq</groupId> <artifactId>rhq-jira-plugin</artifactId>
- <version>${project.version}</version> </artifactItem>
- -->
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-jmx-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-mysql-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-netservices-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-oracle-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-perftest-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
<artifactId>rhq-platform-plugin</artifactId>
<version>${project.version}</version>
</artifactItem>
<artifactItem>
<groupId>org.rhq</groupId>
- <artifactId>rhq-postfix-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-postgres-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-samba-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-script-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-snmptrapd-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-sshd-plugin</artifactId>
+ <artifactId>rhq-agent-plugin</artifactId>
<version>${project.version}</version>
</artifactItem>
<artifactItem>
<groupId>org.rhq</groupId>
- <artifactId>rhq-sudoers-plugin</artifactId>
+ <artifactId>rhq-jmx-plugin</artifactId>
<version>${project.version}</version>
</artifactItem>
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-virt-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
- <artifactItem>
- <groupId>org.rhq</groupId>
- <artifactId>rhq-kickstart-plugin</artifactId>
- <version>${project.version}</version>
- </artifactItem>
-
+ <!-- NOTE: The rest of the plugins are copied by enabled-by-default profiles defined below. -->
</artifactItems>
<outputDirectory>${earDirectory}/rhq-downloads/rhq-plugins</outputDirectory>
</configuration>
@@ -432,6 +296,308 @@
<profiles>
+ <profile>
+ <id>jboss-plugins</id>
+ <activation>
+ <property>
+ <name>java.home</name>
+ </property>
+ </activation>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+
+ <execution>
+ <id>copy-jboss-plugins</id>
+ <phase>process-resources</phase>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-augeas-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-apache-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.jboss.on</groupId>
+ <artifactId>jopr-tomcat-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.jboss.on</groupId>
+ <artifactId>jopr-jboss-as-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.jboss.on</groupId>
+ <artifactId>jopr-hibernate-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.jboss.on</groupId>
+ <artifactId>jopr-rhq-server-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.jboss.on</groupId>
+ <artifactId>jopr-jboss-cache-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.jboss.on</groupId>
+ <artifactId>jopr-jboss-as-5-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.jboss.on</groupId>
+ <artifactId>jopr-jboss-cache-v3-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ </artifactItems>
+ <outputDirectory>${earDirectory}/rhq-downloads/rhq-plugins</outputDirectory>
+ </configuration>
+ </execution>
+
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+
+ <profile>
+ <id>linux-plugins</id>
+ <activation>
+ <property>
+ <name>java.home</name>
+ </property>
+ </activation>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+
+ <execution>
+ <id>copy-linux-plugins</id>
+ <phase>process-resources</phase>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-augeas-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-cron-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-script-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-script2-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-grub-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-hosts-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-cobbler-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-sudoers-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-netservices-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-samba-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-postfix-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-aliases-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-sshd-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-virt-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-kickstart-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ </artifactItems>
+ <outputDirectory>${earDirectory}/rhq-downloads/rhq-plugins</outputDirectory>
+ </configuration>
+ </execution>
+
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ </profile>
+
+ <profile>
+ <id>misc-plugins</id>
+ <activation>
+ <property>
+ <name>java.home</name>
+ </property>
+ </activation>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+
+ <execution>
+ <id>copy-misc-plugins</id>
+ <phase>process-resources</phase>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-hudson-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-iis-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-database-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-postgres-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-mysql-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-oracle-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-snmptrapd-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-twitter-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-filetemplate-bundle-plugin</artifactId>
+ <version>${project.version}</version>
+ </artifactItem>
+
+ </artifactItems>
+ <outputDirectory>${earDirectory}/rhq-downloads/rhq-plugins</outputDirectory>
+ </configuration>
+ </execution>
+
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ </profile>
+
<profile>
<id>dev</id>
@@ -516,3 +682,4 @@
</profiles>
</project>
+
diff --git a/modules/plugins/pom.xml b/modules/plugins/pom.xml
index db7d4be..55e0546 100644
--- a/modules/plugins/pom.xml
+++ b/modules/plugins/pom.xml
@@ -128,9 +128,7 @@
<module>hosts</module>
<module>cobbler</module>
<module>sudoers</module>
- <module>hudson</module>
<module>netservices</module>
- <module>perftest</module>
<module>samba</module>
<module>postfix</module>
<module>aliases</module>
commit aca7641c34a3a79b50ce5dd44ee565948f3a0f46
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Tue Feb 16 09:24:33 2010 -0500
further work on policy persp bundle CRUD pages
diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/table/renderer/AllRowsSelectorRenderer.java b/modules/core/gui/src/main/java/org/rhq/core/gui/table/renderer/AllRowsSelectorRenderer.java
index 85d8ddc..40da965 100644
--- a/modules/core/gui/src/main/java/org/rhq/core/gui/table/renderer/AllRowsSelectorRenderer.java
+++ b/modules/core/gui/src/main/java/org/rhq/core/gui/table/renderer/AllRowsSelectorRenderer.java
@@ -18,7 +18,6 @@
*/
package org.rhq.core.gui.table.renderer;
-import com.sun.faces.util.MessageUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rhq.core.gui.table.component.AllRowsSelectorComponent;
@@ -57,6 +56,8 @@ public class AllRowsSelectorRenderer extends AbstractRenderer {
return;
}
+ // TODO: Do not render if the data model's row count is 0.
+
ResponseWriter writer = context.getResponseWriter();
writer.startElement("input", component);
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 530b91d..3045872 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
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2009 Red Hat, Inc.
+ * Copyright (C) 2005-2010 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -55,6 +55,7 @@ import org.rhq.enterprise.server.util.CriteriaQueryRunner;
* Manages the creation and usage of bundles.
*
* @author John Mazzitelli
+ * @author Ian Springer
*/
@Stateless
public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemote {
@@ -182,14 +183,25 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
Bundle bundle = new Bundle(UUID.randomUUID().toString(), bundleType);
+ bundle = createBundle(subject, bundle);
+
// Add 1 to 5 bundle versions.
int bundleVersionCount = random.nextInt(5) + 1;
for (int i = 0; i < bundleVersionCount; i++) {
String bundleVersionName = UUID.randomUUID().toString();
- BundleVersion bundleVersion = new BundleVersion(bundleVersionName, String.valueOf(i), null, "blah blah blah");
+ final String RECIPE = "repo rhel-x86_64-5\n" +
+ "package foo-1.25.rpm\n" +
+ "package bar-1.25.rpm\n" +
+ "script foo.bash -c some parameter\n" +
+ "deploy jboss.tar %{jboss.home.directory}\n" +
+ "realize %{jboss.home.directory}/server/default/setting.xml\n" +
+ "file example.setting /etc/some/setting.ini\n" +
+ "service example restart\n";
+ BundleVersion bundleVersion = new BundleVersion(bundleVersionName, String.valueOf(i + 1), null, RECIPE);
bundle.addBundleVersion(bundleVersion);
}
- return createBundle(subject, bundle);
+ bundle = entityManager.merge(bundle);
+ return bundle;
}
}
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 025d1cb..09408b3 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
@@ -28,9 +28,11 @@ import javax.jws.soap.SOAPBinding;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.Bundle;
+import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.criteria.BundleCriteria;
+import org.rhq.core.domain.criteria.BundleDeployDefinitionCriteria;
import org.rhq.core.domain.criteria.BundleVersionCriteria;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
@@ -53,6 +55,9 @@ public interface BundleManagerRemote {
PageList<BundleVersion> findBundleVersionsByCriteria(Subject subject, BundleVersionCriteria criteria);
+ PageList<BundleDeployDefinition> findBundleDeployDefinitionsByCriteria(Subject subject,
+ BundleDeployDefinitionCriteria criteria);
+
void deleteBundles(Subject subject, int[] bundleIds);
void deleteBundleVersions(Subject subject, int[] bundleVersionIds);
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundleDetailsUIBean.java b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundleDetailsUIBean.java
index d9e6db3..0dd1fb3 100644
--- a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundleDetailsUIBean.java
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundleDetailsUIBean.java
@@ -145,8 +145,8 @@ public class BundleDetailsUIBean extends AbstractPerspectivePagedDataUIBean {
}
BundleVersionCriteria bundleVersionCriteria = new BundleVersionCriteria();
- String bundleName = BundleDetailsUIBean.this.getBundle().getName();
bundleVersionCriteria.setPageControl(pageControl);
+ String bundleName = BundleDetailsUIBean.this.getBundle().getName();
bundleVersionCriteria.addFilterBundleName(bundleName);
// TODO: Implement user-specified filters.
PageList<BundleVersion> bundleVersions = bundleManager.findBundleVersionsByCriteria(subject,
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundleVersionDetailsUIBean.java b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundleVersionDetailsUIBean.java
new file mode 100644
index 0000000..b602595
--- /dev/null
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundleVersionDetailsUIBean.java
@@ -0,0 +1,163 @@
+/*
+ * 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.server.perspective.policy;
+
+import org.ajax4jsf.model.KeepAlive;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.web.RequestParameter;
+import org.jboss.seam.international.StatusMessage;
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.bundle.Bundle;
+import org.rhq.core.domain.bundle.BundleDeployDefinition;
+import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.criteria.BundleDeployDefinitionCriteria;
+import org.rhq.core.domain.criteria.BundleVersionCriteria;
+import org.rhq.core.domain.util.PageControl;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.core.gui.table.bean.AbstractPagedDataUIBean;
+import org.rhq.core.gui.table.model.PagedListDataModel;
+import org.rhq.enterprise.client.RemoteClient;
+import org.rhq.enterprise.server.bundle.BundleManagerRemote;
+import org.rhq.enterprise.server.perspective.AbstractPerspectivePagedDataUIBean;
+import org.rhq.enterprise.server.perspective.PerspectiveClientUIBean;
+
+import java.util.List;
+
+/**
+ * Provides details about a particular {@link org.rhq.core.domain.bundle.BundleVersion version} of a provisioning
+ * bundle, including CRUD operations on the {@link org.rhq.core.domain.bundle.BundleDeployDefinition deployment
+ * definition}s defined for that bundle version. The backing bean for bundleVersionDetails.xhtml.
+ *
+ * @author Ian Springer
+ */
+@Name("BundleVersionDetailsUIBean")
+(a)Scope(ScopeType.EVENT)
+@KeepAlive
+public class BundleVersionDetailsUIBean extends AbstractPerspectivePagedDataUIBean {
+ private List<BundleDeployDefinition> selectedBundleDeployDefinitions;
+
+ @RequestParameter
+ private int bundleVersionId;
+
+ private BundleVersion bundleVersion;
+
+ public BundleVersion getBundleVersion() {
+ if (this.bundleVersion == null) {
+ this.bundleVersion = loadBundleVersion();
+ }
+ return this.bundleVersion;
+ }
+
+ public Bundle getBundle() {
+ return getBundleVersion().getBundle();
+ }
+
+ @Override
+ public PagedListDataModel createDataModel() {
+ return new DataModel(this);
+ }
+
+ public List<BundleDeployDefinition> getSelectedBundleDeployDefinitions() {
+ return this.selectedBundleDeployDefinitions;
+ }
+
+ public void setSelectedBundleDeployDefinitions(List<BundleDeployDefinition> selectedBundleDeployDefinitions) {
+ this.selectedBundleDeployDefinitions = selectedBundleDeployDefinitions;
+ }
+
+ public void deleteSelectedBundleDeployDefinitions() throws Exception {
+ RemoteClient remoteClient;
+ Subject subject;
+ try {
+ remoteClient = this.perspectiveClient.getRemoteClient();
+ subject = this.perspectiveClient.getSubject();
+ } catch (Exception e) {
+ this.facesMessages.add(StatusMessage.Severity.FATAL, "Failed to connect to RHQ Server - cause: " + e);
+ return;
+ }
+
+ // ***NOTE***: The javassist.NotFoundException stack traces that are logged by this call can be ignored.
+ BundleManagerRemote bundleManager = remoteClient.getBundleManagerRemote();
+
+ int[] selectedBundleDeployDefinitionIds = new int[this.selectedBundleDeployDefinitions.size()];
+ for (int i = 0, selectedBundlesSize = this.selectedBundleDeployDefinitions.size(); i < selectedBundlesSize; i++) {
+ BundleDeployDefinition selectedBundleDeployDefinition = this.selectedBundleDeployDefinitions.get(i);
+ selectedBundleDeployDefinitionIds[i] = selectedBundleDeployDefinition.getId();
+ }
+
+ //bundleManager.deleteBundleDeploymentDefinitions(subject, selectedBundleDeploymentDefinitionsIds);
+
+ // Add message to tell the user the uninventory was a success.
+ String pluralizer = (this.selectedBundleDeployDefinitions.size() == 1) ? "" : "s";
+ this.facesMessages.add("Deleted " + this.selectedBundleDeployDefinitions.size() + " bundle deployment definition" + pluralizer + ".");
+
+ // Reset the data model, so the current page will get refreshed to reflect the Resources we just uninventoried.
+ // This is essential, since we are CONVERSATION-scoped and will live on beyond this request.
+ setDataModel(null);
+ }
+
+ private BundleVersion loadBundleVersion() {
+ BundleManagerRemote bundleManager;
+ Subject subject;
+ try {
+ bundleManager = this.perspectiveClient.getRemoteClient().getBundleManagerRemote();
+ subject = this.perspectiveClient.getSubject();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ BundleVersionCriteria bundleVersionCriteria = new BundleVersionCriteria();
+ bundleVersionCriteria.addFilterId(this.bundleVersionId);
+ PageList<BundleVersion> bundleVersions = bundleManager.findBundleVersionsByCriteria(subject, bundleVersionCriteria);
+ if (bundleVersions.isEmpty()) {
+ throw new IllegalStateException("Bundle version with id " + this.bundleVersionId + " not found.");
+ }
+ return bundleVersions.get(0);
+ }
+
+ private class DataModel extends PagedListDataModel<BundleDeployDefinition> {
+ private DataModel(AbstractPagedDataUIBean pagedDataBean) {
+ super(pagedDataBean);
+ }
+
+ @Override
+ public PageList<BundleDeployDefinition> fetchPage(PageControl pageControl) {
+ PerspectiveClientUIBean perspectiveClient = BundleVersionDetailsUIBean.this.perspectiveClient;
+ BundleManagerRemote bundleManager;
+ Subject subject;
+ try {
+ bundleManager = perspectiveClient.getRemoteClient().getBundleManagerRemote();
+ subject = BundleVersionDetailsUIBean.this.perspectiveClient.getSubject();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ BundleDeployDefinitionCriteria bundleDeployDefinitionCriteria = new BundleDeployDefinitionCriteria();
+ bundleDeployDefinitionCriteria.setPageControl(pageControl);
+ // TODO
+ //bundleDeployDefinitionCriteria.addFilterVersionId(BundleVersionDetailsUIBean.this.bundleVersionId);
+ bundleDeployDefinitionCriteria.fetchBundle(true);
+ // TODO: Implement user-specified filters.
+ PageList<BundleDeployDefinition> bundleDeployDefinitions = bundleManager.findBundleDeployDefinitionsByCriteria(subject,
+ bundleDeployDefinitionCriteria);
+ return bundleDeployDefinitions;
+ }
+ }
+}
\ No newline at end of file
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundleDetails.xhtml b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundleDetails.xhtml
index 64d78bd..a0b504d 100644
--- a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundleDetails.xhtml
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundleDetails.xhtml
@@ -23,20 +23,22 @@
<ui:define name="body">
- <div><h:panelGroup layout="block" rendered="#{ServerInfoUIBean.debugModeEnabled}">
- <b>Id:</b> #{bundle.id}
- </h:panelGroup></div>
- <div><h:panelGroup layout="block">
- <b>Name:</b> #{bundle.name}
- </h:panelGroup></div>
- <div><h:panelGroup layout="block">
- <b>Type:</b> #{bundle.bundleType.name}
- </h:panelGroup></div>
+ <rich:panel>
+ <div><h:panelGroup layout="block" rendered="#{ServerInfoUIBean.debugModeEnabled}">
+ <b>Id:</b> #{bundle.id}
+ </h:panelGroup></div>
+ <div><h:panelGroup layout="block">
+ <b>Name:</b> #{bundle.name}
+ </h:panelGroup></div>
+ <div><h:panelGroup layout="block">
+ <b>Type:</b> #{bundle.bundleType.name}
+ </h:panelGroup></div>
+ </rich:panel>
<ui:remove><!-- NOTE: The table needs to be surrounded by a form for paging and sorting to work! --></ui:remove>
<a4j:form ajaxSubmit="false" reRender="bundlesVersionsDataTable">
- <f:param name="bundleId" value="#{bundleId}"/>
+ <f:param name="bundleId" value="#{param.bundleId}"/>
<rich:dataTable id="bundleVersionsDataTable"
value="#{BundleDetailsUIBean.dataModel}" var="bundleVersion"
@@ -77,7 +79,7 @@
</rhq:sortableColumnHeader>
</f:facet>
- <h:outputLink value="bundleDeploymentDefinitions.seam">
+ <h:outputLink value="bundleVersionDetails.seam">
<f:param name="bundleVersionId" value="#{bundleVersion.id}"/>
<h:outputText value="#{bundleVersion.name}"/>
</h:outputLink>
@@ -88,7 +90,8 @@
<rich:column colspan="3">
<rhq:selectedRowsCommandButton
value="DELETE"
- action="#{BundleDetailsUIBean.deleteSelectedBundleVersions}"/>
+ action="#{BundleDetailsUIBean.deleteSelectedBundleVersions}"
+ rendered="#{BundleDetailsUIBean.dataModel.rowCount gt 0}"/>
<ui:include src="/WEB-INF/includes/pageControls.xhtml">
<ui:param name="pagedDataUIBean" value="#{BundleDetailsUIBean}"/>
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundleVersionDetails.xhtml b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundleVersionDetails.xhtml
new file mode 100644
index 0000000..76d5d74
--- /dev/null
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundleVersionDetails.xhtml
@@ -0,0 +1,120 @@
+<?xml version="1.0"?>
+
+<ui:composition
+ template="/WEB-INF/templates/mainTemplate.xhtml"
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:fn="http://java.sun.com/jsp/jstl/functions"
+ xmlns:a4j="http://richfaces.org/a4j"
+ xmlns:rich="http://richfaces.org/rich"
+ xmlns:rhq="http://rhq-project.org/rhq"
+ xmlns:onc="http://jboss.org/on/component">
+
+ <ui:param name="bundleVersion" value="#{BundleVersionDetailsUIBean.bundleVersion}"/>
+ <ui:param name="bundle" value="#{BundleVersionDetailsUIBean.bundle}"/>
+
+ <ui:define name="breadcrumbs">
+ Administration >
+ <h:outputLink value="bundles.seam">Provisioning Bundles</h:outputLink> >
+ <h:outputLink value="bundleDetails.seam">
+ <f:param name="bundleId" value="#{bundle.id}"/>
+ #{bundle.bundleType.name} Bundle '#{bundle.name}'
+ </h:outputLink> >
+ Version #{bundleVersion.version}
+ </ui:define>
+
+ <ui:define name="body">
+
+ <rich:panel>
+ <div><h:panelGroup layout="block" rendered="#{ServerInfoUIBean.debugModeEnabled}">
+ <b>Id:</b> #{bundleVersion.id}
+ </h:panelGroup></div>
+ <div><h:panelGroup layout="block">
+ <b>Version:</b> #{bundleVersion.version}
+ </h:panelGroup></div>
+ <div><h:panelGroup layout="block">
+ <b>Name:</b> #{bundleVersion.name}
+ </h:panelGroup></div>
+ </rich:panel>
+
+ <rich:panel>
+ <f:facet name="header">
+ Recipe
+ </f:facet>
+ <h:inputTextarea value="#{bundleVersion.recipe}" cols="80" rows="10" disabled="true"/>
+ </rich:panel>
+
+ <ui:remove><!-- NOTE: The table needs to be surrounded by a form for paging and sorting to work! --></ui:remove>
+ <a4j:form ajaxSubmit="false" reRender="bundleDeployDefinitionsDataTable">
+
+ <f:param name="bundleVersionId" value="#{param.bundleVersionId}"/>
+
+ <rich:dataTable id="bundleDeployDefinitionsDataTable"
+ value="#{BundleVersionDetailsUIBean.dataModel}" var="bundleDeployDefinition"
+ first="#{BundleVersionDetailsUIBean.pageControl.pageNumber}"
+ rows="#{BundleVersionDetailsUIBean.pageControl.pageSize}"
+ sortMode="multi"
+ width="100%">
+
+ <f:facet name="header">
+ <h:outputText value="Deployment Definitions"/>
+ </f:facet>
+
+ <rich:column width="20">
+ <f:facet name="header">
+ <rhq:allRowsSelector/>
+ </f:facet>
+ <rhq:rowSelector value="#{BundleVersionDetailsUIBean.selectedBundleDeployDefinitions}"/>
+ </rich:column>
+
+ <rich:column width="125">
+ <f:facet name="header">
+ <rhq:sortableColumnHeader sortBy="BundleDeployDefinition.name">
+ <a4j:support event="onclick"
+ actionListener="#{BundleVersionDetailsUIBean.ajaxSortListener}"/>
+ <h:outputText value="Name"/>
+ </rhq:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputLink value="bundleDeployDefinitionDetails.seam">
+ <f:param name="bundleDeployDefinitionId" value="#{bundleDeployDefinition.id}"/>
+ <h:outputText value="#{bundleDeployDefinition.name}"/>
+ </h:outputLink>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <rhq:sortableColumnHeader sortBy="BundleDeployDefinition.description">
+ <a4j:support event="onclick"
+ actionListener="#{BundleVersionDetailsUIBean.ajaxSortListener}"/>
+ <h:outputText value="Description"/>
+ </rhq:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{bundleDeployDefinition.description}"/>
+ </rich:column>
+
+ <f:facet name="footer">
+ <rich:columnGroup>
+ <rich:column colspan="3">
+ <rhq:selectedRowsCommandButton
+ value="DELETE"
+ action="#{BundleVersionDetailsUIBean.deleteSelectedBundleDeployDefinitions}"
+ rendered="#{BundleVersionDetailsUIBean.dataModel.rowCount gt 0}"/>
+
+ <ui:include src="/WEB-INF/includes/pageControls.xhtml">
+ <ui:param name="pagedDataUIBean" value="#{BundleVersionDetailsUIBean}"/>
+ <ui:param name="dataTableName" value="bundleDeployDefinitionsDataTable"/>
+ </ui:include>
+ </rich:column>
+ </rich:columnGroup>
+ </f:facet>
+ </rich:dataTable>
+ </a4j:form>
+
+ </ui:define>
+
+</ui:composition>
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml
index 8c9b809..b680fe3 100644
--- a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml
@@ -69,7 +69,8 @@
<rich:column colspan="3">
<rhq:selectedRowsCommandButton
value="DELETE"
- action="#{BundlesUIBean.deleteSelectedBundles}"/>
+ action="#{BundlesUIBean.deleteSelectedBundles}"
+ rendered="#{BundlesUIBean.dataModel.rowCount gt 0}"/>
<ui:include src="/WEB-INF/includes/pageControls.xhtml">
<ui:param name="pagedDataUIBean" value="#{BundlesUIBean}"/>
commit a4a0aefc4b2cdf83d3011f591e7eecddeba2e0c1
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Mon Feb 15 18:30:00 2010 -0500
fix bug in fetchPageGuarded()'s check for pageControl that's inconsistent w/ the results
diff --git a/modules/core/gui/src/main/java/org/rhq/core/gui/table/model/PagedListDataModel.java b/modules/core/gui/src/main/java/org/rhq/core/gui/table/model/PagedListDataModel.java
index efb5f56..c327c7b 100644
--- a/modules/core/gui/src/main/java/org/rhq/core/gui/table/model/PagedListDataModel.java
+++ b/modules/core/gui/src/main/java/org/rhq/core/gui/table/model/PagedListDataModel.java
@@ -213,9 +213,10 @@ public abstract class PagedListDataModel<T> extends DataModel {
* RF components, the DataTable component does not see this change. so, we have to explicitly
* update the page control to get the view consistent with the backend once again.
*/
- if (results.getTotalSize() <= pageControl.getStartRow() || (results.isEmpty() && pageControl.getPageNumber() != 0)) {
+ if ((results.getTotalSize() != 0 && results.getTotalSize() <= pageControl.getStartRow()) ||
+ (results.isEmpty() && pageControl.getPageNumber() != 0)) {
if (log.isTraceEnabled()) {
- if (results.getTotalSize() <= pageControl.getStartRow()) {
+ if (results.getTotalSize() != 0 && results.getTotalSize() <= pageControl.getStartRow()) {
//log.trace(pageControlView + ": Results size[" + results.getTotalSize()
// + "] was less than PageControl startRow[" + pageControl.getStartRow() + "]");
} else {
commit b174715037e064aafd8d20ba8d10634673625c2e
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Mon Feb 15 18:28:46 2010 -0500
add bundleDetails.xhtml page and associated UIBean to policy perspective
diff --git a/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java b/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java
index 1430a79..27629db 100644
--- a/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java
+++ b/etc/modules/base-perspective-war/src/main/java/org/rhq/enterprise/server/perspective/AbstractPerspectivePagedDataUIBean.java
@@ -33,6 +33,9 @@ public abstract class AbstractPerspectivePagedDataUIBean extends AbstractPagedDa
@Create
public void init() {
- this.perspectiveClient = (PerspectiveClientUIBean) Component.getInstance(PerspectiveClientUIBean.class, true);
+ if (this.perspectiveClient == null) {
+ this.perspectiveClient = (PerspectiveClientUIBean) Component.getInstance(PerspectiveClientUIBean.class,
+ true);
+ }
}
}
diff --git a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/templates/mainTemplate.xhtml b/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/templates/mainTemplate.xhtml
index 9b7826e..21ec05f 100644
--- a/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/templates/mainTemplate.xhtml
+++ b/etc/modules/base-perspective-war/src/main/webapp/WEB-INF/templates/mainTemplate.xhtml
@@ -53,7 +53,9 @@ Firefox and other Gecko-based browsers to render the page in "Almost Standards"
<body bgcolor="#FFFFFF" style="height: 100%;">
-<h1>#{(!empty pageTitle) ? pageTitle : defaultPageTitle}</h1>
+<h:panelGroup layout="block" style="font-weight: bold; margin-left: 15px; margin-bottom: 15px;">
+ <ui:insert name="breadcrumbs"/>
+</h:panelGroup>
<rich:messages globalOnly="true"
infoClass="InfoBlock"
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/perspective/main.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/perspective/main.xhtml
index 72f70b8..31cb447 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/perspective/main.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/perspective/main.xhtml
@@ -20,7 +20,7 @@
value="PERSPECTIVE PAGE" />
<ui:define name="breadcrumbs">
- <h:outputLink value="/">Custom</h:outputLink>
+ <ui:remove><!-- Leave this empty, so the embedded page can render the breadcrumbs itself. --></ui:remove>
</ui:define>
<ui:define name="body">
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 7c95fdd..530b91d 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
@@ -157,6 +157,13 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
}
+ public void deleteBundleVersions(Subject subject, int[] bundleVersionIds) {
+ for (int bundleVersionId : bundleVersionIds) {
+ BundleVersion bundleVersion = this.entityManager.find(BundleVersion.class, bundleVersionId);
+ this.entityManager.remove(bundleVersion);
+ }
+ }
+
public BundleType createMockBundleType(Subject subject) {
ResourceType linuxPlatformResourceType = this.resourceTypeManager.getResourceTypeByNameAndPlugin("Linux",
"Platforms");
@@ -165,15 +172,24 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
public Bundle createMockBundle(Subject subject, List<BundleType> bundleTypes) {
+ Random random = new Random();
BundleType bundleType;
if (bundleTypes.isEmpty()) {
bundleType = createMockBundleType(subject);
} else {
- Random random = new Random();
int randomIndex = random.nextInt(bundleTypes.size());
bundleType = bundleTypes.get(randomIndex);
}
Bundle bundle = new Bundle(UUID.randomUUID().toString(), bundleType);
+
+ // Add 1 to 5 bundle versions.
+ int bundleVersionCount = random.nextInt(5) + 1;
+ for (int i = 0; i < bundleVersionCount; i++) {
+ String bundleVersionName = UUID.randomUUID().toString();
+ BundleVersion bundleVersion = new BundleVersion(bundleVersionName, String.valueOf(i), null, "blah blah blah");
+ bundle.addBundleVersion(bundleVersion);
+ }
+
return createBundle(subject, bundle);
}
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
index 4542574..9cfc099 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
@@ -65,4 +65,6 @@ public interface BundleManagerLocal {
List<BundleType> getAllBundleTypes(Subject subject);
void deleteBundles(Subject subject, int[] bundleIds);
+
+ void deleteBundleVersions(Subject subject, int[] bundleVersionIds);
}
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 3b6454a..025d1cb 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
@@ -29,7 +29,9 @@ import javax.jws.soap.SOAPBinding;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleType;
+import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.criteria.BundleCriteria;
+import org.rhq.core.domain.criteria.BundleVersionCriteria;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.system.ServerVersion;
@@ -49,5 +51,9 @@ public interface BundleManagerRemote {
PageList<Bundle> findBundlesByCriteria(Subject subject, BundleCriteria criteria);
+ PageList<BundleVersion> findBundleVersionsByCriteria(Subject subject, BundleVersionCriteria criteria);
+
void deleteBundles(Subject subject, int[] bundleIds);
+
+ void deleteBundleVersions(Subject subject, int[] bundleVersionIds);
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginManager.java
index 85aa235..88153a6 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginManager.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/PerspectiveServerPluginManager.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2009 Red Hat, Inc.
+ * Copyright (C) 2005-2010 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -26,6 +26,7 @@ import java.util.Collections;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
+import javax.management.MBeanException;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.naming.Context;
@@ -106,29 +107,25 @@ public class PerspectiveServerPluginManager extends ServerPluginManager {
}
}
} catch (Exception e) {
- getLog().error("Failed to deploy " + env.getPluginKey().getPluginName() + "#" + name, e);
+ Throwable t = (e instanceof MBeanException) ? e.getCause() : e;
+ log.error("Failed to deploy " + env.getPluginKey().getPluginName() + "#" + name, t);
}
}
- private void deployWar(ServerPluginEnvironment env, String name, InputStream iStream) {
- try {
- // Save the war file to the plugins data directory. This survives restarts and will
- // act as our deploy directory.
- File deployFile = writeWarToFile(getDeployFile(env, name), iStream);
-
- // get reference to MBean server
- Context ic = new InitialContext();
- MBeanServerConnection server = (MBeanServerConnection) ic.lookup("jmx/invoker/RMIAdaptor");
+ private void deployWar(ServerPluginEnvironment env, String name, InputStream iStream) throws Exception {
+ // Save the war file to the plugins data directory. This survives restarts and will
+ // act as our deploy directory.
+ File deployFile = writeWarToFile(getDeployFile(env, name), iStream);
- // get reference to MainDeployer MBean
- ObjectName mainDeployer = new ObjectName("jboss.system:service=MainDeployer");
+ // get reference to MBean server
+ Context ic = new InitialContext();
+ MBeanServerConnection server = (MBeanServerConnection) ic.lookup("jmx/invoker/RMIAdaptor");
- server.invoke(mainDeployer, "deploy", new Object[] { deployFile.getAbsolutePath() },
- new String[] { String.class.getName() });
+ // get reference to MainDeployer MBean
+ ObjectName mainDeployer = new ObjectName("jboss.system:service=MainDeployer");
- } catch (Exception e) {
- e.printStackTrace();
- }
+ server.invoke(mainDeployer, "deploy", new Object[] { deployFile.getAbsolutePath() },
+ new String[] { String.class.getName() });
}
private File getDeployFile(ServerPluginEnvironment env, String name) throws IOException {
@@ -260,5 +257,4 @@ public class PerspectiveServerPluginManager extends ServerPluginManager {
log.error("Failed to undeploy perspective WAR [" + deployFile + "].", e);
}
}
-
}
\ No newline at end of file
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundleDetailsUIBean.java b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundleDetailsUIBean.java
new file mode 100644
index 0000000..d9e6db3
--- /dev/null
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundleDetailsUIBean.java
@@ -0,0 +1,157 @@
+/*
+ * 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.server.perspective.policy;
+
+import org.ajax4jsf.model.KeepAlive;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.web.RequestParameter;
+import org.jboss.seam.international.StatusMessage;
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.bundle.Bundle;
+import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.criteria.BundleCriteria;
+import org.rhq.core.domain.criteria.BundleVersionCriteria;
+import org.rhq.core.domain.util.PageControl;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.core.gui.table.bean.AbstractPagedDataUIBean;
+import org.rhq.core.gui.table.model.PagedListDataModel;
+import org.rhq.enterprise.client.RemoteClient;
+import org.rhq.enterprise.server.bundle.BundleManagerRemote;
+import org.rhq.enterprise.server.perspective.AbstractPerspectivePagedDataUIBean;
+import org.rhq.enterprise.server.perspective.PerspectiveClientUIBean;
+
+import java.util.List;
+
+/**
+ * Provides details about a particular provisioning {@link Bundle bundle}, including CRUD operations on
+ * the {@link org.rhq.core.domain.bundle.BundleVersion version}s defined for that bundle. The backing bean for
+ * bundleDetails.xhtml.
+ *
+ * @author Ian Springer
+ */
+@Name("BundleDetailsUIBean")
+(a)Scope(ScopeType.EVENT)
+@KeepAlive
+public class BundleDetailsUIBean extends AbstractPerspectivePagedDataUIBean {
+ private List<BundleVersion> selectedBundleVersions;
+
+ @RequestParameter
+ private int bundleId;
+
+ private Bundle bundle;
+
+ public Bundle getBundle() {
+ if (this.bundle == null) {
+ this.bundle = loadBundle();
+ }
+ return this.bundle;
+ }
+
+ @Override
+ public PagedListDataModel createDataModel() {
+ return new DataModel(this);
+ }
+
+ public List<BundleVersion> getSelectedBundleVersions() {
+ return this.selectedBundleVersions;
+ }
+
+ public void setSelectedBundleVersions(List<BundleVersion> selectedBundleVersions) {
+ this.selectedBundleVersions = selectedBundleVersions;
+ }
+
+ public void deleteSelectedBundles() throws Exception {
+ RemoteClient remoteClient;
+ Subject subject;
+ try {
+ remoteClient = this.perspectiveClient.getRemoteClient();
+ subject = this.perspectiveClient.getSubject();
+ } catch (Exception e) {
+ this.facesMessages.add(StatusMessage.Severity.FATAL, "Failed to connect to RHQ Server - cause: " + e);
+ return;
+ }
+
+ // ***NOTE***: The javassist.NotFoundException stack traces that are logged by this call can be ignored.
+ BundleManagerRemote bundleManager = remoteClient.getBundleManagerRemote();
+
+ int[] selectedBundleVersionIds = new int[this.selectedBundleVersions.size()];
+ for (int i = 0, selectedBundlesSize = this.selectedBundleVersions.size(); i < selectedBundlesSize; i++) {
+ BundleVersion selectedBundleVersion = this.selectedBundleVersions.get(i);
+ selectedBundleVersionIds[i] = selectedBundleVersion.getId();
+ }
+
+ bundleManager.deleteBundleVersions(subject, selectedBundleVersionIds);
+
+ // Add message to tell the user the uninventory was a success.
+ String pluralizer = (this.selectedBundleVersions.size() == 1) ? "" : "s";
+ this.facesMessages.add("Deleted " + this.selectedBundleVersions.size() + " bundle version" + pluralizer + ".");
+
+ // Reset the data model, so the current page will get refreshed to reflect the Resources we just uninventoried.
+ // This is essential, since we are CONVERSATION-scoped and will live on beyond this request.
+ setDataModel(null);
+ }
+
+ private Bundle loadBundle() {
+ BundleManagerRemote bundleManager;
+ Subject subject;
+ try {
+ bundleManager = this.perspectiveClient.getRemoteClient().getBundleManagerRemote();
+ subject = this.perspectiveClient.getSubject();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ BundleCriteria bundleCriteria = new BundleCriteria();
+ bundleCriteria.addFilterId(this.bundleId);
+ PageList<Bundle> bundles = bundleManager.findBundlesByCriteria(subject, bundleCriteria);
+ if (bundles.isEmpty()) {
+ throw new IllegalStateException("Bundle with id " + this.bundleId + " not found.");
+ }
+ return bundles.get(0);
+ }
+
+ private class DataModel extends PagedListDataModel<BundleVersion> {
+ private DataModel(AbstractPagedDataUIBean pagedDataBean) {
+ super(pagedDataBean);
+ }
+
+ @Override
+ public PageList<BundleVersion> fetchPage(PageControl pageControl) {
+ PerspectiveClientUIBean perspectiveClient = BundleDetailsUIBean.this.perspectiveClient;
+ BundleManagerRemote bundleManager;
+ Subject subject;
+ try {
+ bundleManager = perspectiveClient.getRemoteClient().getBundleManagerRemote();
+ subject = BundleDetailsUIBean.this.perspectiveClient.getSubject();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ BundleVersionCriteria bundleVersionCriteria = new BundleVersionCriteria();
+ String bundleName = BundleDetailsUIBean.this.getBundle().getName();
+ bundleVersionCriteria.setPageControl(pageControl);
+ bundleVersionCriteria.addFilterBundleName(bundleName);
+ // TODO: Implement user-specified filters.
+ PageList<BundleVersion> bundleVersions = bundleManager.findBundleVersionsByCriteria(subject,
+ bundleVersionCriteria);
+ return bundleVersions;
+ }
+ }
+}
\ No newline at end of file
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java
index 1cc14dd..3cd1959 100644
--- a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java
@@ -110,7 +110,8 @@ public class BundlesUIBean extends AbstractPerspectivePagedDataUIBean {
}
BundleCriteria bundleCriteria = new BundleCriteria();
- // TODO: Implement filtering.
+ bundleCriteria.setPageControl(pageControl);
+ // TODO: Implement user-specified filters.
PageList<Bundle> bundles = bundleManager.findBundlesByCriteria(subject, bundleCriteria);
return bundles;
}
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundleDetails.xhtml b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundleDetails.xhtml
new file mode 100644
index 0000000..64d78bd
--- /dev/null
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundleDetails.xhtml
@@ -0,0 +1,105 @@
+<?xml version="1.0"?>
+
+<ui:composition
+ template="/WEB-INF/templates/mainTemplate.xhtml"
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:fn="http://java.sun.com/jsp/jstl/functions"
+ xmlns:a4j="http://richfaces.org/a4j"
+ xmlns:rich="http://richfaces.org/rich"
+ xmlns:rhq="http://rhq-project.org/rhq"
+ xmlns:onc="http://jboss.org/on/component">
+
+ <ui:param name="bundle" value="#{BundleDetailsUIBean.bundle}"/>
+
+ <ui:define name="breadcrumbs">
+ Administration >
+ <h:outputLink value="bundles.seam">Provisioning Bundles</h:outputLink> >
+ #{bundle.bundleType.name} Bundle '#{bundle.name}'
+ </ui:define>
+
+ <ui:define name="body">
+
+ <div><h:panelGroup layout="block" rendered="#{ServerInfoUIBean.debugModeEnabled}">
+ <b>Id:</b> #{bundle.id}
+ </h:panelGroup></div>
+ <div><h:panelGroup layout="block">
+ <b>Name:</b> #{bundle.name}
+ </h:panelGroup></div>
+ <div><h:panelGroup layout="block">
+ <b>Type:</b> #{bundle.bundleType.name}
+ </h:panelGroup></div>
+
+ <ui:remove><!-- NOTE: The table needs to be surrounded by a form for paging and sorting to work! --></ui:remove>
+ <a4j:form ajaxSubmit="false" reRender="bundlesVersionsDataTable">
+
+ <f:param name="bundleId" value="#{bundleId}"/>
+
+ <rich:dataTable id="bundleVersionsDataTable"
+ value="#{BundleDetailsUIBean.dataModel}" var="bundleVersion"
+ first="#{BundleDetailsUIBean.pageControl.pageNumber}"
+ rows="#{BundleDetailsUIBean.pageControl.pageSize}"
+ sortMode="multi"
+ width="100%">
+
+ <f:facet name="header">
+ <h:outputText value="Versions"/>
+ </f:facet>
+
+ <rich:column width="20">
+ <f:facet name="header">
+ <rhq:allRowsSelector/>
+ </f:facet>
+ <rhq:rowSelector value="#{BundleDetailsUIBean.selectedBundleVersions}"/>
+ </rich:column>
+
+ <rich:column width="70">
+ <f:facet name="header">
+ <rhq:sortableColumnHeader sortBy="BundleVersion.version">
+ <a4j:support event="onclick"
+ actionListener="#{BundleDetailsUIBean.ajaxSortListener}"/>
+ <h:outputText value="Version"/>
+ </rhq:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{bundleVersion.version}"/>
+ </rich:column>
+
+ <rich:column>
+ <f:facet name="header">
+ <rhq:sortableColumnHeader sortBy="BundleVersion.name">
+ <a4j:support event="onclick"
+ actionListener="#{BundleDetailsUIBean.ajaxSortListener}"/>
+ <h:outputText value="Name"/>
+ </rhq:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputLink value="bundleDeploymentDefinitions.seam">
+ <f:param name="bundleVersionId" value="#{bundleVersion.id}"/>
+ <h:outputText value="#{bundleVersion.name}"/>
+ </h:outputLink>
+ </rich:column>
+
+ <f:facet name="footer">
+ <rich:columnGroup>
+ <rich:column colspan="3">
+ <rhq:selectedRowsCommandButton
+ value="DELETE"
+ action="#{BundleDetailsUIBean.deleteSelectedBundleVersions}"/>
+
+ <ui:include src="/WEB-INF/includes/pageControls.xhtml">
+ <ui:param name="pagedDataUIBean" value="#{BundleDetailsUIBean}"/>
+ <ui:param name="dataTableName" value="bundleVersionsDataTable"/>
+ </ui:include>
+ </rich:column>
+ </rich:columnGroup>
+ </f:facet>
+ </rich:dataTable>
+ </a4j:form>
+
+ </ui:define>
+
+</ui:composition>
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml
index cf34d97..8c9b809 100644
--- a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml
@@ -11,12 +11,11 @@
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
xmlns:rhq="http://rhq-project.org/rhq"
- xmlns:onc="http://jboss.org/on/component">
-
- <ui:param name="pageTitle" value="Provisioning Bundles"/>
+ xmlns:onc="http://jboss.org/on/component">
<ui:define name="breadcrumbs">
- <h:outputText value="Provisioning Bundles"/>
+ Administration >
+ Provisioning Bundles
</ui:define>
<ui:define name="body">
@@ -40,14 +39,14 @@
<rich:column width="235">
<f:facet name="header">
- <rhq:sortableColumnHeader sortBy="b.name">
+ <rhq:sortableColumnHeader sortBy="Bundle.name">
<a4j:support event="onclick"
actionListener="#{BundlesUIBean.ajaxSortListener}"/>
<h:outputText value="Name"/>
</rhq:sortableColumnHeader>
</f:facet>
- <h:outputLink value="bundleVersions.seam">
+ <h:outputLink value="bundleDetails.seam">
<f:param name="bundleId" value="#{bundle.id}"/>
<h:outputText value="#{bundle.name}"/>
</h:outputLink>
@@ -55,7 +54,7 @@
<rich:column>
<f:facet name="header">
- <rhq:sortableColumnHeader sortBy="b.bundleType.name">
+ <rhq:sortableColumnHeader sortBy="Bundle.bundleType.name">
<a4j:support event="onclick"
actionListener="#{BundlesUIBean.ajaxSortListener}"/>
<h:outputText value="Type"/>
diff --git a/modules/enterprise/server/plugins/perspectives/policy/perspective/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/perspectives/policy/perspective/src/main/resources/META-INF/rhq-serverplugin.xml
index 6053d09..ded5e86 100644
--- a/modules/enterprise/server/plugins/perspectives/policy/perspective/src/main/resources/META-INF/rhq-serverplugin.xml
+++ b/modules/enterprise/server/plugins/perspectives/policy/perspective/src/main/resources/META-INF/rhq-serverplugin.xml
@@ -19,7 +19,7 @@
<!-- Administration > Provisioning -->
<menu-item
name="administration.provisioning"
- displayName="Provisioning"
+ displayName="Provisioning Bundles"
application="policy"
url="bundles.seam">
<position
commit 4c95a2fada6ade201ee88006be2280fb5ba7dcf5
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Mon Feb 15 10:15:30 2010 -0500
get rid of calls to t.printStackTrace() - use logging instead
diff --git a/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClientProxy.java b/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClientProxy.java
index 36dbf2b..a1ecc61 100644
--- a/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClientProxy.java
+++ b/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClientProxy.java
@@ -30,6 +30,8 @@ import javassist.CtNewMethod;
import javassist.NotFoundException;
import javassist.bytecode.ParameterAnnotationsAttribute;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.jboss.remoting.invocation.NameBasedInvocation;
import org.rhq.core.domain.auth.Subject;
@@ -39,11 +41,11 @@ import org.rhq.core.domain.util.serial.ExternalizableStrategy;
* This class acts as a local SLSB proxy to make remote invocations
* to SLSB Remotes over a remoting invoker.
*
- *
* @author Greg Hinkle
*/
@SuppressWarnings("unchecked")
public class RemoteClientProxy implements InvocationHandler {
+ private static final Log LOG = LogFactory.getLog(RemoteClientProxy.class);
private RemoteClient client;
private RemoteClient.Manager manager;
@@ -78,13 +80,14 @@ public class RemoteClientProxy implements InvocationHandler {
String simpleName = intf.getName() + "Simple";
try {
+ @SuppressWarnings({"UnusedDeclaration"})
CtClass cached = cp.get(simpleName);
return Class.forName(simpleName, false, cp.getClassLoader());
} catch (NotFoundException e) {
// ok... load it
} catch (ClassNotFoundException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ LOG.debug("Class [" + simpleName + "] not found - cause: " + e);
}
CtClass cc = cp.get(intf.getName());
@@ -121,11 +124,10 @@ public class RemoteClientProxy implements InvocationHandler {
.getAnnotations();
javassist.bytecode.annotation.Annotation[][] newAnnotations = new javassist.bytecode.annotation.Annotation[originalAnnotations.length - 1][];
- int i = 1;
- for (int x = 1; x < originalAnnotations.length; x++) {
- newAnnotations[x - 1] = new javassist.bytecode.annotation.Annotation[originalAnnotations[x].length];
- System.arraycopy(originalAnnotations[x], 0, newAnnotations[x - 1], 0,
- originalAnnotations[x].length);
+ for (int i = 1; i < originalAnnotations.length; i++) {
+ newAnnotations[i - 1] = new javassist.bytecode.annotation.Annotation[originalAnnotations[i].length];
+ System.arraycopy(originalAnnotations[i], 0, newAnnotations[i - 1], 0,
+ originalAnnotations[i].length);
}
ParameterAnnotationsAttribute newAnnotationsAttribute = new ParameterAnnotationsAttribute(
@@ -144,9 +146,9 @@ public class RemoteClientProxy implements InvocationHandler {
return cz.toClass();
} catch (NotFoundException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ LOG.debug("Failed to simplify " + intf + " - cause: " + e);
} catch (CannotCompileException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ LOG.error("Failed to simplify " + intf + ".", e);
}
return intf;
}
@@ -164,7 +166,7 @@ public class RemoteClientProxy implements InvocationHandler {
try {
Class[] interfaces = method.getDeclaringClass().getInterfaces();
- Class originalClass = null;
+ Class originalClass;
if (interfaces != null && interfaces.length > 0) {
originalClass = interfaces[0];
} else {
@@ -215,5 +217,4 @@ public class RemoteClientProxy implements InvocationHandler {
}
return paramSig;
}
-
}
commit e2209f9015bb1f29eed75674fc2c1e5147c63c84
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 15 11:52:23 2010 -0500
Fix up BundleTest
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
index 0cb550a..783b707 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
@@ -50,9 +50,12 @@ import javax.xml.bind.annotation.XmlAccessorType;
*/
@Entity
@NamedQueries( {
- @NamedQuery(name = Bundle.QUERY_FIND_ALL, query = "SELECT b FROM Bundle b"), //
- @NamedQuery(name = Bundle.QUERY_FIND_BY_TYPE_AND_NAME, query = "SELECT b FROM Bundle b WHERE " +
- "(:type = b.bundleType.name OR :type IS NULL) AND (:name = b.name OR :name IS NULL)")
+ // Below queries primarily used for domain test code.
+ @NamedQuery(name = Bundle.QUERY_FIND_ALL, query = "SELECT b FROM Bundle b"), //
+ @NamedQuery(name = Bundle.QUERY_FIND_BY_NAME, query = "SELECT b FROM Bundle b WHERE :name = b.name"),
+ @NamedQuery(name = Bundle.QUERY_FIND_BY_TYPE_AND_NAME, query = "SELECT b FROM Bundle b WHERE "
+ + "(:type = b.bundleType.name OR :type IS NULL) AND (:name = b.name OR :name IS NULL)")
+
})
@SequenceGenerator(name = "SEQ", sequenceName = "RHQ_BUNDLE_ID_SEQ")
@Table(name = "RHQ_BUNDLE")
@@ -61,6 +64,7 @@ public class Bundle implements Serializable {
private static final long serialVersionUID = 1L;
public static final String QUERY_FIND_ALL = "Bundle.findAll";
+ public static final String QUERY_FIND_BY_NAME = "Bundle.findByName";
public static final String QUERY_FIND_BY_TYPE_AND_NAME = "Bundle.findByTypeAndName";
@Column(name = "ID", nullable = false)
diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/bundle/test/BundleTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/bundle/test/BundleTest.java
index e229fef..83b9f9f 100644
--- a/modules/core/domain/src/test/java/org/rhq/core/domain/bundle/test/BundleTest.java
+++ b/modules/core/domain/src/test/java/org/rhq/core/domain/bundle/test/BundleTest.java
@@ -42,6 +42,7 @@ import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.test.AbstractEJB3Test;
@Test
+@SuppressWarnings("unchecked")
public class BundleTest extends AbstractEJB3Test {
public void testBundleVersionRepo() throws Throwable {
getTransactionManager().begin();
@@ -50,7 +51,7 @@ public class BundleTest extends AbstractEJB3Test {
int id;
String name = "BundleTest-testBundleVersionRepo";
- String action = "action/script/recipe is here";
+ String recipe = "action/script/recipe is here";
Repo repo1 = new Repo(name + "-Repo1");
Repo repo2 = new Repo(name + "-Repo2");
@@ -65,11 +66,10 @@ public class BundleTest extends AbstractEJB3Test {
q.setParameter("id", repo2.getId());
assert q.getResultList().size() == 0 : "should not have repo2 mapping in the db yet";
- BundleType bundleType = new BundleType(name + "-Type", createResourceType(em));
+ BundleType bundleType = createBundleType(em, name + "-Type", createResourceType(em));
Bundle bundle = new Bundle(name + "-Bundle", bundleType);
em.persist(bundle);
- BundleVersion bundleVersion = new BundleVersion(name, "1.0.0.BETA", bundle);
- bundleVersion.setAction(action);
+ BundleVersion bundleVersion = new BundleVersion(name, "1.0.0.BETA", bundle, recipe);
em.persist(bundleVersion);
id = bundleVersion.getId();
assert id > 0;
@@ -127,17 +127,16 @@ public class BundleTest extends AbstractEJB3Test {
int id;
String name = "BundleTest-testBundleVersion";
- String action = "action/script/recipe is here";
+ String recipe = "action/script/recipe is here";
- BundleType bundleType = new BundleType(name + "-Type", createResourceType(em));
+ BundleType bundleType = createBundleType(em, name + "-Type", createResourceType(em));
Bundle bundle = new Bundle(name + "-Bundle", bundleType);
em.persist(bundle);
id = bundle.getId();
assert id > 0;
assert bundle.getBundleType().getId() != 0 : "bundleType should have been cascade persisted too";
- BundleVersion bv = new BundleVersion(name, "1.0.0.BETA", bundle);
- bv.setAction(action);
+ BundleVersion bv = new BundleVersion(name, "1.0.0.BETA", bundle, recipe);
Query q = em.createNamedQuery(BundleVersion.QUERY_FIND_BY_NAME);
q.setParameter("name", bv.getName());
assert q.getResultList().size() == 0; // not in the db yet
@@ -148,6 +147,7 @@ public class BundleTest extends AbstractEJB3Test {
q = em.createNamedQuery(BundleVersion.QUERY_FIND_BY_NAME);
q.setParameter("name", bv.getName());
+ q.setParameter("name", bv.getName());
assert q.getResultList().size() == 1;
assert ((BundleVersion) q.getSingleResult()).getName().equals(bv.getName());
@@ -156,7 +156,7 @@ public class BundleTest extends AbstractEJB3Test {
assert bvFind.getId() == bv.getId();
assert bvFind.getName().equals(bv.getName());
assert bvFind.getVersion().equals(bv.getVersion());
- assert bvFind.getAction().equals(bv.getAction());
+ assert bvFind.getRecipe().equals(bv.getRecipe());
assert bvFind.getBundle().equals(bv.getBundle());
assert bvFind.equals(bv);
assert bvFind.hashCode() == bv.hashCode();
@@ -234,7 +234,7 @@ public class BundleTest extends AbstractEJB3Test {
q.setParameter("name", name);
assert q.getResultList().size() == 0; // not in the db yet
- BundleType bundleType = new BundleType(name + "-Type", createResourceType(em));
+ BundleType bundleType = createBundleType(em, name + "-Type", createResourceType(em));
Bundle b = new Bundle(name, bundleType);
em.persist(b);
@@ -307,9 +307,8 @@ public class BundleTest extends AbstractEJB3Test {
q.setParameter("name", name);
assert q.getResultList().size() == 0; // not in the db yet
- BundleType bt = new BundleType(name, createResourceType(em));
+ BundleType bt = createBundleType(em, name, createResourceType(em));
- em.persist(bt);
id = bt.getId();
assert id > 0;
@@ -357,6 +356,12 @@ public class BundleTest extends AbstractEJB3Test {
return rt;
}
+ private BundleType createBundleType(EntityManager em, String name, ResourceType rt) throws Exception {
+ BundleType bt = new BundleType(name, rt);
+ em.persist(bt);
+ return bt;
+ }
+
private ResourceType deleteResourceType(EntityManager em, ResourceType rt) {
rt = em.find(ResourceType.class, rt.getId());
em.remove(rt);
commit 6b3a0e331baa5a4bee4b6356555058fce2b24aba
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 15 11:10:53 2010 -0500
Add test for BundleVersionCriteria search.
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
index 155eca6..4003c40 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
@@ -183,7 +183,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
assertEquals(b, bv.getBundle());
}
- @Test(enabled = false)
+ @Test(enabled = ENABLED)
public void testfindBundleVersionsByCriteria() throws Exception {
Bundle b1 = createBundle("one");
BundleVersion bv1 = createBundleVersion(b1.getName(), "1.0", b1);
@@ -215,7 +215,8 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
assertEquals(bv2, bv);
assertEquals(bv.getBundle(), b1);
assertNull(bv.getDistribution());
- assertNull(bv.getBundleDeployDefinitions());
+ assertNotNull(bv.getBundleDeployDefinitions());
+ assertTrue(bv.getBundleDeployDefinitions().isEmpty());
}
private BundleType createBundleType(String name) throws Exception {
commit 4df3bcecbbc460a596784819356832cf70455c9c
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 15 11:10:34 2010 -0500
bundle field is lazy loaded so remove bundle field from hashcode/equals.
Name+Version should be a sufficient key.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java
index 7bc3dea..125baa7 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java
@@ -193,7 +193,6 @@ public class BundleVersion implements Serializable {
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((version == null) ? 0 : version.hashCode());
- result = prime * result + ((bundle == null) ? 0 : bundle.hashCode());
return result;
}
@@ -224,14 +223,6 @@ public class BundleVersion implements Serializable {
return false;
}
- if (bundle == null) {
- if (other.bundle != null) {
- return false;
- }
- } else if (!bundle.equals(other.bundle)) {
- return false;
- }
-
return true;
}
}
\ No newline at end of file
commit 4450158f44bf351a4aa820f8925899f07c010106
Merge: 712ba06... b6a25ca...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 15 09:42:37 2010 -0500
Merge branch 'bundle' into bundle-jay
Conflicts:
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
diff --cc modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java
index 471b0d6,19d17c2..7c95fdd
--- 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
@@@ -18,17 -18,8 +18,19 @@@
*/
package org.rhq.enterprise.server.bundle;
+import java.util.List;
++import java.util.Random;
++import java.util.UUID;
+
+import javax.ejb.EJB;
+import javax.ejb.Stateless;
+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.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
@@@ -38,8 -29,9 +40,10 @@@ import org.rhq.core.domain.bundle.Bundl
import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleDeployDefinitionCriteria;
import org.rhq.core.domain.criteria.BundleDeploymentCriteria;
+import org.rhq.core.domain.criteria.BundleVersionCriteria;
+ import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.util.PageList;
+ import org.rhq.core.domain.util.PersistenceUtility;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.authz.AuthorizationManagerLocal;
import org.rhq.enterprise.server.authz.PermissionException;
@@@ -113,19 -118,51 +121,59 @@@ public class BundleManagerBean implemen
return queryRunner.execute();
}
+ public PageList<BundleVersion> findBundleVersionsByCriteria(Subject subject, BundleVersionCriteria criteria) {
+ CriteriaQueryGenerator generator = new CriteriaQueryGenerator(criteria);
+
+ CriteriaQueryRunner<BundleVersion> queryRunner = new CriteriaQueryRunner<BundleVersion>(criteria, generator,
+ entityManager);
+ return queryRunner.execute();
+ }
+
public PageList<Bundle> findBundlesByCriteria(Subject subject, BundleCriteria criteria) {
- Query totalCountQuery = PersistenceUtility.createCountQuery(entityManager,
- Bundle.QUERY_FIND_ALL);
++ Query totalCountQuery = PersistenceUtility.createCountQuery(entityManager, Bundle.QUERY_FIND_ALL);
+ long totalCount = (Long) totalCountQuery.getSingleResult();
+ if (totalCount == 0) {
+ List<BundleType> bundleTypes = getAllBundleTypes(subject);
+ for (int i = 0; i < 50; i++) {
+ createMockBundle(subject, bundleTypes);
+ }
+ }
+
CriteriaQueryGenerator generator = new CriteriaQueryGenerator(criteria);
CriteriaQueryRunner<Bundle> queryRunner = new CriteriaQueryRunner<Bundle>(criteria, generator, entityManager);
return queryRunner.execute();
}
+ public PageList<BundleDeployment> findBundleDeploymentsByCriteria(BundleDeploymentCriteria criteria) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void deleteBundles(Subject subject, int[] bundleIds) {
+ for (int bundleId : bundleIds) {
+ Bundle bundle = this.entityManager.find(Bundle.class, bundleId);
+ this.entityManager.remove(bundle);
+ }
+ }
+
+ public BundleType createMockBundleType(Subject subject) {
- ResourceType linuxPlatformResourceType = this.resourceTypeManager.getResourceTypeByNameAndPlugin("Linux", "Platforms");
++ ResourceType linuxPlatformResourceType = this.resourceTypeManager.getResourceTypeByNameAndPlugin("Linux",
++ "Platforms");
+ BundleType bundleType = new BundleType(UUID.randomUUID().toString(), linuxPlatformResourceType);
+ return createBundleType(subject, bundleType);
+ }
+
+ public Bundle createMockBundle(Subject subject, List<BundleType> bundleTypes) {
+ BundleType bundleType;
+ if (bundleTypes.isEmpty()) {
+ bundleType = createMockBundleType(subject);
+ } else {
+ Random random = new Random();
+ int randomIndex = random.nextInt(bundleTypes.size());
+ bundleType = bundleTypes.get(randomIndex);
+ }
+ Bundle bundle = new Bundle(UUID.randomUUID().toString(), bundleType);
+ return createBundle(subject, bundle);
+ }
}
commit 712ba06393292d96353700d3ed347e9483c3a256
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 15 09:33:05 2010 -0500
More work on criteria search for bundle domain
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleVersionCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleVersionCriteria.java
new file mode 100644
index 0000000..72c07ed
--- /dev/null
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleVersionCriteria.java
@@ -0,0 +1,81 @@
+/*
+ * 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.core.domain.criteria;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.rhq.core.domain.bundle.BundleVersion;
+
+/**
+ * @author Jay Shaughnessy
+ */
+@XmlRootElement
+(a)XmlAccessorType(XmlAccessType.FIELD)
+@SuppressWarnings("unused")
+public class BundleVersionCriteria extends Criteria {
+ private static final long serialVersionUID = 1L;
+
+ private Integer filterId;
+ private String filterName;
+ private String filterVersion;
+ private String filterBundleName; // needs override
+
+ private boolean fetchBundle;
+ private boolean fetchBundleDeployDefinitions;
+ private boolean fetchDistribution;
+ private boolean fetchConfigurationDefinition;
+
+ public BundleVersionCriteria() {
+ super(BundleVersion.class);
+
+ filterOverrides.put("bundleName", "bundle.name like ?");
+ }
+
+ public void addFilterId(Integer filterId) {
+ this.filterId = filterId;
+ }
+
+ public void addFilterName(String filterName) {
+ this.filterName = filterName;
+ }
+
+ public void addFilterBundleName(String filterBundleName) {
+ this.filterBundleName = filterBundleName;
+ }
+
+ public void addFilterVersion(String filterVersion) {
+ this.filterVersion = filterVersion;
+ }
+
+ public void fetchBundle(boolean fetchBundle) {
+ this.fetchBundle = fetchBundle;
+ }
+
+ public void fetchDistribution(boolean fetchDistribution) {
+ this.fetchDistribution = fetchDistribution;
+ }
+
+ public void fetchBundleDeployDefinitions(boolean fetchBundleDeployDefinitions) {
+ this.fetchBundleDeployDefinitions = fetchBundleDeployDefinitions;
+ }
+
+}
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 c25c0b9..471b0d6 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
@@ -38,6 +38,7 @@ import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleDeployDefinitionCriteria;
import org.rhq.core.domain.criteria.BundleDeploymentCriteria;
+import org.rhq.core.domain.criteria.BundleVersionCriteria;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.authz.AuthorizationManagerLocal;
@@ -112,6 +113,14 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
return queryRunner.execute();
}
+ public PageList<BundleVersion> findBundleVersionsByCriteria(Subject subject, BundleVersionCriteria criteria) {
+ CriteriaQueryGenerator generator = new CriteriaQueryGenerator(criteria);
+
+ CriteriaQueryRunner<BundleVersion> queryRunner = new CriteriaQueryRunner<BundleVersion>(criteria, generator,
+ entityManager);
+ return queryRunner.execute();
+ }
+
public PageList<Bundle> findBundlesByCriteria(Subject subject, BundleCriteria criteria) {
CriteriaQueryGenerator generator = new CriteriaQueryGenerator(criteria);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
index ee808d0..33afd50 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
@@ -31,6 +31,7 @@ import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleDeployDefinitionCriteria;
import org.rhq.core.domain.criteria.BundleDeploymentCriteria;
+import org.rhq.core.domain.criteria.BundleVersionCriteria;
import org.rhq.core.domain.util.PageList;
/**
@@ -58,6 +59,8 @@ public interface BundleManagerLocal {
PageList<BundleDeployment> findBundleDeploymentsByCriteria(Subject subject, BundleDeploymentCriteria criteria);
+ PageList<BundleVersion> findBundleVersionsByCriteria(Subject subject, BundleVersionCriteria criteria);
+
PageList<Bundle> findBundlesByCriteria(Subject subject, BundleCriteria criteria);
List<BundleType> getAllBundleTypes(Subject subject);
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
index 35666db..155eca6 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
@@ -36,6 +36,7 @@ import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.criteria.BundleCriteria;
+import org.rhq.core.domain.criteria.BundleVersionCriteria;
import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.util.PageList;
@@ -45,7 +46,7 @@ import org.rhq.enterprise.server.util.LookupUtil;
/**
* @author John Mazzitelli
*/
-@SuppressWarnings("unchecked")
+@SuppressWarnings( { "unchecked", "unused" })
@Test
public class BundleManagerBeanTest extends AbstractEJB3Test {
@@ -167,6 +168,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
// return bundle "two" using all criteria and with all optional data
c.addFilterId(b.getId());
c.addFilterName(b.getName());
+ c.addFilterBundleTypeName(b.getName());
c.fetchBundleVersions(true);
bundles = bundleManagerBean.findBundlesByCriteria(getOverlord(), c);
assertNotNull(bundles);
@@ -181,6 +183,41 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
assertEquals(b, bv.getBundle());
}
+ @Test(enabled = false)
+ public void testfindBundleVersionsByCriteria() throws Exception {
+ Bundle b1 = createBundle("one");
+ BundleVersion bv1 = createBundleVersion(b1.getName(), "1.0", b1);
+ BundleVersion bv2 = createBundleVersion(b1.getName(), "2.0", b1);
+ BundleVersion bv3 = createBundleVersion(b1.getName(), "2.1", b1);
+ BundleVersionCriteria c = new BundleVersionCriteria();
+ PageList<BundleVersion> bvs = null;
+ BundleVersion bv = null;
+
+ // return all with no optional data
+ bvs = bundleManagerBean.findBundleVersionsByCriteria(getOverlord(), c);
+ bv = bvs.get(1);
+ assertNotNull(bvs);
+ assertEquals(3, bvs.size());
+ assertEquals(bv2, bv);
+
+ // return bundle version using all criteria and with all optional data
+ c.addFilterId(bv.getId());
+ c.addFilterName(bv.getName());
+ c.addFilterBundleName("one");
+ c.addFilterVersion(bv.getVersion());
+ c.fetchBundle(true);
+ c.fetchDistribution(true);
+ c.fetchBundleDeployDefinitions(true);
+ bvs = bundleManagerBean.findBundleVersionsByCriteria(getOverlord(), c);
+ assertNotNull(bvs);
+ assertEquals(1, bvs.size());
+ bv = bvs.get(0);
+ assertEquals(bv2, bv);
+ assertEquals(bv.getBundle(), b1);
+ assertNull(bv.getDistribution());
+ assertNull(bv.getBundleDeployDefinitions());
+ }
+
private BundleType createBundleType(String name) throws Exception {
final String fullName = TEST_PREFIX + "-type-" + name;
BundleType bt = new BundleType(fullName, createResourceType(name));
commit 79f799ed6bb0514c23ee469c9cf03dc24242b4ae
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 15 09:32:19 2010 -0500
Added access to deploy defs
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java
index 202eeac..7bc3dea 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java
@@ -23,6 +23,8 @@
package org.rhq.core.domain.bundle;
import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
@@ -35,6 +37,7 @@ import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
+import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlAccessType;
@@ -88,6 +91,9 @@ public class BundleVersion implements Serializable {
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private ConfigurationDefinition configurationDefinition;
+ @OneToMany(mappedBy = "bundleVersion", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
+ private List<BundleDeployDefinition> bundleDeployDefinitions = new ArrayList<BundleDeployDefinition>();
+
public BundleVersion() {
// for JPA use
}
@@ -163,6 +169,19 @@ public class BundleVersion implements Serializable {
this.configurationDefinition = configurationDefinition;
}
+ public List<BundleDeployDefinition> getBundleDeployDefinitions() {
+ return bundleDeployDefinitions;
+ }
+
+ public void addBundleDeployDefinition(BundleDeployDefinition bundleDeployDefinition) {
+ this.bundleDeployDefinitions.add(bundleDeployDefinition);
+ bundleDeployDefinition.setBundleVersion(this);
+ }
+
+ public void setBundleDeployDefinitions(List<BundleDeployDefinition> bundleDeployDefinitions) {
+ this.bundleDeployDefinitions = bundleDeployDefinitions;
+ }
+
@Override
public String toString() {
return "BundleVersion[id=" + id + ",name=" + name + ",version=" + version + ",bundle=" + bundle + "]";
commit fdaa9f42925f293aaa36004a69f6d1f492a91970
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 15 09:31:47 2010 -0500
Added filters for bundle type
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java
index d446891..5c40cd0 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java
@@ -35,18 +35,31 @@ public class BundleCriteria extends Criteria {
private static final long serialVersionUID = 1L;
private Integer filterId;
+ private Integer filterBundleTypeId; // needs override
+ private String filterBundleTypeName; // needs override
private String filterName;
private boolean fetchBundleVersions;
public BundleCriteria() {
super(Bundle.class);
+
+ filterOverrides.put("bundleTypeId", "bundleType.id = ?");
+ filterOverrides.put("bundleTypeName", "bundleType.name like ?");
}
public void addFilterId(Integer filterId) {
this.filterId = filterId;
}
+ public void addFilterBundleTypeId(Integer filterBundleTypeId) {
+ this.filterBundleTypeId = filterBundleTypeId;
+ }
+
+ public void addFilterBundleTypeName(String filterBundleTypeName) {
+ this.filterName = filterBundleTypeName;
+ }
+
public void addFilterName(String filterName) {
this.filterName = filterName;
}
commit b6a25ca1049c094e09e8c24678cbf009de81f699
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Fri Feb 12 18:26:55 2010 -0500
deploy policy perspective by default; misc minor changes
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
index 0dc6eb9..beecf66 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
@@ -47,11 +47,11 @@ public interface BundleManagerLocal {
BundleVersion createBundleVersion(Subject subject, BundleVersion bundleVersion);
- // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
- // The following are shared with the Remote Interface
+ // The remaining methods are shared with the Remote Interface.
//
- // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
PageList<BundleDeployDefinition> findBundleDeployDefinitionsByCriteria(Subject subject,
BundleDeployDefinitionCriteria criteria);
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java
index 73b8026..1cc14dd 100644
--- a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java
@@ -1,3 +1,21 @@
+/*
+ * 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.server.perspective.policy;
import org.ajax4jsf.model.KeepAlive;
@@ -8,7 +26,6 @@ import org.jboss.seam.international.StatusMessage;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.criteria.BundleCriteria;
-import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.gui.table.bean.AbstractPagedDataUIBean;
@@ -17,12 +34,13 @@ import org.rhq.enterprise.client.RemoteClient;
import org.rhq.enterprise.server.bundle.BundleManagerRemote;
import org.rhq.enterprise.server.perspective.AbstractPerspectivePagedDataUIBean;
import org.rhq.enterprise.server.perspective.PerspectiveClientUIBean;
-import org.rhq.enterprise.server.resource.ResourceManagerRemote;
import java.util.List;
/**
- * Provides CRUD operations for provisioning {@link Bundle}s. The backing bean for bundles.xhtml.
+ * Provides CRUD operations on provisioning {@link Bundle}s. The backing bean for bundles.xhtml.
+ *
+ * @author Ian Springer
*/
@Name("BundlesUIBean")
@Scope(ScopeType.EVENT)
@@ -74,7 +92,6 @@ public class BundlesUIBean extends AbstractPerspectivePagedDataUIBean {
setDataModel(null);
}
-
private class DataModel extends PagedListDataModel<Bundle> {
private DataModel(AbstractPagedDataUIBean pagedDataBean) {
super(pagedDataBean);
commit a32d94232ca13734c93437ce4d69bfa715103af6
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Fri Feb 12 17:54:05 2010 -0500
change start() so it sets isStarted even if one or more perspectives fail to deploy - that way, the redeploy logic will call start() when a plugin is hot-deployed even if the initial call to start() failed to deploy one or more perspectives
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java
index 72d62b5..2d39f87 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/perspective/metadata/PerspectivePluginMetadataManager.java
@@ -99,12 +99,14 @@ public class PerspectivePluginMetadataManager {
// TODO: Init lists of global tasks and resource tasks.
this.pageLinks = new ArrayList<PageLink>();
- // Always process the Core perspective first as other perspectives may remove extensions it defines.
- processCorePerspective();
- processNonCorePerspectives();
-
- this.isStarted = true;
- this.lastModifiedTime = System.currentTimeMillis();
+ // Always process the Core perspective first, as other perspectives may remove extensions it defines.
+ try {
+ processCorePerspective();
+ processNonCorePerspectives();
+ } finally {
+ this.isStarted = true;
+ this.lastModifiedTime = System.currentTimeMillis();
+ }
}
public synchronized void stop() {
@@ -119,24 +121,26 @@ public class PerspectivePluginMetadataManager {
private void processCorePerspective() {
PerspectivePluginDescriptorType corePerspectiveDescriptor = this.loadedPlugins.get(CORE_PERSPECTIVE_NAME);
if (corePerspectiveDescriptor == null) {
- throw new IllegalStateException("Core perspective must be loaded. Invalid startup. Load: "
- + CORE_PERSPECTIVE_NAME);
+ throw new IllegalStateException("Core perspective is required but is missing.");
+ }
+ try {
+ processPerspective(corePerspectiveDescriptor);
+ } catch (Exception e) {
+ throw new IllegalStateException("Failed to load core perspective.", e);
}
- processPerspective(corePerspectiveDescriptor);
-
- // TODO: remove this debug code
- //printMenu(this.menu, "");
}
private void processNonCorePerspectives() {
- for (String key : this.loadedPlugins.keySet()) {
- if (!CORE_PERSPECTIVE_NAME.equals(key)) {
- processPerspective(this.loadedPlugins.get(key));
+ for (String perspectiveName : this.loadedPlugins.keySet()) {
+ if (!CORE_PERSPECTIVE_NAME.equals(perspectiveName)) {
+ PerspectivePluginDescriptorType pluginDescriptor = this.loadedPlugins.get(perspectiveName);
+ try {
+ processPerspective(pluginDescriptor);
+ } catch (Exception e) {
+ log.error("Failed to load perspective [" + perspectiveName + "].", e);
+ }
}
}
-
- // TODO: remove this debug code
- //printMenu(this.menu, "");
}
private void processPerspective(PerspectivePluginDescriptorType perspective) {
commit cd68ab94767f2561f5ea658739e2147db8d9473b
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Fri Feb 12 17:51:49 2010 -0500
add ability to exclude subsets of agent plugins from the reactor
diff --git a/modules/plugins/pom.xml b/modules/plugins/pom.xml
index 104a373..db7d4be 100644
--- a/modules/plugins/pom.xml
+++ b/modules/plugins/pom.xml
@@ -81,54 +81,106 @@
<modules>
<!-- core plugins -->
<module>platform</module>
- <module>jmx</module>
<module>rhq-agent</module>
- <module>apache</module>
- <module>iis</module>
- <module>database</module>
- <module>postgres</module>
-
- <!-- jboss plugins (order is important) -->
- <module>tomcat</module>
- <module>jboss-as</module>
- <module>hibernate</module>
- <module>rhq-server</module>
- <module>jboss-cache</module>
- <module>jboss-as-5</module>
- <module>jboss-cache-v3</module>
- <!-- was not in Jopr build at merge time <module>jbossOSGi</module> -->
-
- <!-- other, possibly experimental plugins -->
- <module>augeas</module>
- <module>cron</module>
- <module>script</module>
- <module>script2</module>
- <module>grub</module>
- <!-- not behaving <module>hardware</module> -->
- <module>hosts</module>
- <module>cobbler</module>
- <module>sudoers</module>
- <module>hudson</module>
- <!-- error in code generation (see RHQ-1225) <module>jira</module> -->
- <module>mysql</module>
- <module>netservices</module>
- <!-- non-public dependency <module>onewire</module> -->
- <module>oracle</module>
- <module>perftest</module>
- <module>samba</module>
- <module>postfix</module>
- <module>aliases</module>
- <module>snmptrapd</module>
- <module>sshd</module>
- <module>twitter</module>
- <module>virt</module>
- <module>kickstart</module>
-
- <!-- bundle plugins -->
- <module>filetemplate-bundle</module>
-
- <!-- make this the last - it will validate all the plugins -->
- <module>validate-all-plugins</module>
+ <module>jmx</module>
</modules>
+ <profiles>
+
+ <profile>
+ <id>jboss-plugins</id>
+ <activation>
+ <property>
+ <name>java.home</name>
+ </property>
+ </activation>
+
+ <modules>
+ <!-- NOTE: Order is important. -->
+ <module>augeas</module>
+ <module>apache</module>
+ <module>tomcat</module>
+ <module>jboss-as</module>
+ <module>hibernate</module>
+ <module>rhq-server</module>
+ <module>jboss-cache</module>
+ <module>jboss-as-5</module>
+ <module>jboss-cache-v3</module>
+ <!-- was not in Jopr build at merge time <module>jbossOSGi</module> -->
+ </modules>
+ </profile>
+
+ <profile>
+ <id>linux-plugins</id>
+ <activation>
+ <property>
+ <name>java.home</name>
+ </property>
+ </activation>
+
+ <modules>
+ <module>augeas</module>
+ <module>cron</module>
+ <module>script</module>
+ <module>script2</module>
+ <module>grub</module>
+ <!-- not behaving <module>hardware</module> -->
+ <module>hosts</module>
+ <module>cobbler</module>
+ <module>sudoers</module>
+ <module>hudson</module>
+ <module>netservices</module>
+ <module>perftest</module>
+ <module>samba</module>
+ <module>postfix</module>
+ <module>aliases</module>
+ <module>sshd</module>
+ <module>virt</module>
+ <module>kickstart</module>
+ </modules>
+ </profile>
+
+ <profile>
+ <id>misc-plugins</id>
+ <activation>
+ <property>
+ <name>java.home</name>
+ </property>
+ </activation>
+
+ <modules>
+ <module>iis</module>
+ <module>database</module>
+ <module>postgres</module>
+ <module>hudson</module>
+ <!-- error in code generation (see RHQ-1225) <module>jira</module> -->
+ <module>mysql</module>
+ <!-- non-public dependency <module>onewire</module> -->
+ <module>oracle</module>
+ <module>perftest</module>
+ <module>snmptrapd</module>
+ <module>twitter</module>
+
+ <!-- bundle plugins -->
+ <module>filetemplate-bundle</module>
+ </modules>
+ </profile>
+
+ <profile>
+ <id>validate-plugins</id>
+ <activation>
+ <property>
+ <name>java.home</name>
+ </property>
+ </activation>
+
+ <modules>
+ <!-- make this the last - it will validate all the plugins -->
+ <module>validate-all-plugins</module>
+ </modules>
+ </profile>
+
+ </profiles>
+
</project>
+
commit 0bc6fca702f94c3989e9917bb647054ddf965574
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Fri Feb 12 17:50:59 2010 -0500
more work on SLSB methods and perspective-based GUI for listing bundles
diff --git a/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml
index dff673e..e5dfb1d 100644
--- a/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml
+++ b/modules/enterprise/server/plugins/perspectives/core/perspective/src/main/resources/META-INF/rhq-serverplugin.xml
@@ -293,8 +293,8 @@
placement="after" />
</menu-item>
<menu-item
- name="administration.download"
- displayName="Download"
+ name="administration.downloads"
+ displayName="Downloads"
iconUrl="/images/icons/Save_16.png"
url="/rhq/admin/downloads.xhtml">
<position
@@ -306,7 +306,7 @@
displayName="License"
url="/admin/license/LicenseAdmin.do?mode=view">
<position
- name="administration.download"
+ name="administration.downloads"
placement="after" />
<activators>
<global-permission
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java
index 10344d9..73b8026 100644
--- a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java
@@ -2,17 +2,22 @@ package org.rhq.enterprise.server.perspective.policy;
import org.ajax4jsf.model.KeepAlive;
import org.jboss.seam.ScopeType;
-import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.international.StatusMessage;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.Bundle;
+import org.rhq.core.domain.criteria.BundleCriteria;
+import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.gui.table.bean.AbstractPagedDataUIBean;
import org.rhq.core.gui.table.model.PagedListDataModel;
+import org.rhq.enterprise.client.RemoteClient;
import org.rhq.enterprise.server.bundle.BundleManagerRemote;
import org.rhq.enterprise.server.perspective.AbstractPerspectivePagedDataUIBean;
+import org.rhq.enterprise.server.perspective.PerspectiveClientUIBean;
+import org.rhq.enterprise.server.resource.ResourceManagerRemote;
import java.util.List;
@@ -23,18 +28,8 @@ import java.util.List;
@Scope(ScopeType.EVENT)
@KeepAlive
public class BundlesUIBean extends AbstractPerspectivePagedDataUIBean {
- private BundleManagerRemote bundleManager;
private List<Bundle> selectedBundles;
- @Create
- public void init() {
- try {
- this.bundleManager = this.perspectiveClient.getRemoteClient().getBundleManagerRemote();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
@Override
public PagedListDataModel createDataModel() {
return new DataModel(this);
@@ -48,6 +43,38 @@ public class BundlesUIBean extends AbstractPerspectivePagedDataUIBean {
this.selectedBundles = selectedResources;
}
+ public void deleteSelectedBundles() throws Exception {
+ RemoteClient remoteClient;
+ Subject subject;
+ try {
+ remoteClient = this.perspectiveClient.getRemoteClient();
+ subject = this.perspectiveClient.getSubject();
+ } catch (Exception e) {
+ this.facesMessages.add(StatusMessage.Severity.FATAL, "Failed to connect to RHQ Server - cause: " + e);
+ return;
+ }
+
+ // ***NOTE***: The javassist.NotFoundException stack traces that are logged by this call can be ignored.
+ BundleManagerRemote bundleManager = remoteClient.getBundleManagerRemote();
+
+ int[] selectedBundleIds = new int[this.selectedBundles.size()];
+ for (int i = 0, selectedBundlesSize = this.selectedBundles.size(); i < selectedBundlesSize; i++) {
+ Bundle selectedBundle = this.selectedBundles.get(i);
+ selectedBundleIds[i] = selectedBundle.getId();
+ }
+
+ bundleManager.deleteBundles(subject, selectedBundleIds);
+
+ // Add message to tell the user the uninventory was a success.
+ String pluralizer = (this.selectedBundles.size() == 1) ? "" : "s";
+ this.facesMessages.add("Deleted " + this.selectedBundles.size() + " bundle" + pluralizer + ".");
+
+ // Reset the data model, so the current page will get refreshed to reflect the Resources we just uninventoried.
+ // This is essential, since we are CONVERSATION-scoped and will live on beyond this request.
+ setDataModel(null);
+ }
+
+
private class DataModel extends PagedListDataModel<Bundle> {
private DataModel(AbstractPagedDataUIBean pagedDataBean) {
super(pagedDataBean);
@@ -55,14 +82,19 @@ public class BundlesUIBean extends AbstractPerspectivePagedDataUIBean {
@Override
public PageList<Bundle> fetchPage(PageControl pageControl) {
+ PerspectiveClientUIBean perspectiveClient = BundlesUIBean.this.perspectiveClient;
+ BundleManagerRemote bundleManager;
Subject subject;
try {
+ bundleManager = perspectiveClient.getRemoteClient().getBundleManagerRemote();
subject = BundlesUIBean.this.perspectiveClient.getSubject();
} catch (Exception e) {
throw new RuntimeException(e);
}
+
+ BundleCriteria bundleCriteria = new BundleCriteria();
// TODO: Implement filtering.
- PageList<Bundle> bundles = BundlesUIBean.this.bundleManager.findBundlesByCriteria(subject, null, null, pageControl);
+ PageList<Bundle> bundles = bundleManager.findBundlesByCriteria(subject, bundleCriteria);
return bundles;
}
}
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml
index 102e407..cf34d97 100644
--- a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml
@@ -38,7 +38,7 @@
<rhq:rowSelector value="#{BundlesUIBean.selectedBundles}"/>
</rich:column>
- <rich:column width="235" sortBy="b.name">
+ <rich:column width="235">
<f:facet name="header">
<rhq:sortableColumnHeader sortBy="b.name">
<a4j:support event="onclick"
@@ -47,13 +47,13 @@
</rhq:sortableColumnHeader>
</f:facet>
- <h:outputLink value="#{bundle.name}">
+ <h:outputLink value="bundleVersions.seam">
<f:param name="bundleId" value="#{bundle.id}"/>
- <h:outputText value="#{resource.id}"/>
+ <h:outputText value="#{bundle.name}"/>
</h:outputLink>
</rich:column>
- <rich:column width="235">
+ <rich:column>
<f:facet name="header">
<rhq:sortableColumnHeader sortBy="b.bundleType.name">
<a4j:support event="onclick"
@@ -67,10 +67,10 @@
<f:facet name="footer">
<rich:columnGroup>
- <rich:column colspan="4">
+ <rich:column colspan="3">
<rhq:selectedRowsCommandButton
value="DELETE"
- action="#{BundlesUIBean.deleteBundle}"/>
+ action="#{BundlesUIBean.deleteSelectedBundles}"/>
<ui:include src="/WEB-INF/includes/pageControls.xhtml">
<ui:param name="pagedDataUIBean" value="#{BundlesUIBean}"/>
commit 259fbad99c29554896fd6b6b94019e88b09526a1
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Fri Feb 12 11:37:47 2010 -0500
start of SLSB methods and perspective-based GUI for listing bundles
diff --git a/dev-cli b/dev-cli
new file mode 120000
index 0000000..9e0363b
--- /dev/null
+++ b/dev-cli
@@ -0,0 +1 @@
+modules/enterprise/remoting/cli/target/rhq-remoting-cli-1.4.0-SNAPSHOT
\ No newline at end of file
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
index 7c5cda5..0cb550a 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
@@ -49,8 +49,10 @@ import javax.xml.bind.annotation.XmlAccessorType;
* @author John Mazzitelli
*/
@Entity
-@NamedQueries( { @NamedQuery(name = Bundle.QUERY_FIND_ALL, query = "SELECT b FROM Bundle b"), //
- @NamedQuery(name = Bundle.QUERY_FIND_BY_NAME, query = "SELECT b FROM Bundle b WHERE b.name = :name") //
+@NamedQueries( {
+ @NamedQuery(name = Bundle.QUERY_FIND_ALL, query = "SELECT b FROM Bundle b"), //
+ @NamedQuery(name = Bundle.QUERY_FIND_BY_TYPE_AND_NAME, query = "SELECT b FROM Bundle b WHERE " +
+ "(:type = b.bundleType.name OR :type IS NULL) AND (:name = b.name OR :name IS NULL)")
})
@SequenceGenerator(name = "SEQ", sequenceName = "RHQ_BUNDLE_ID_SEQ")
@Table(name = "RHQ_BUNDLE")
@@ -59,7 +61,7 @@ public class Bundle implements Serializable {
private static final long serialVersionUID = 1L;
public static final String QUERY_FIND_ALL = "Bundle.findAll";
- public static final String QUERY_FIND_BY_NAME = "Bundle.findByName";
+ public static final String QUERY_FIND_BY_TYPE_AND_NAME = "Bundle.findByTypeAndName";
@Column(name = "ID", nullable = false)
@GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ")
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 c25c0b9..19d17c2 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
@@ -18,17 +18,8 @@
*/
package org.rhq.enterprise.server.bundle;
-import java.util.List;
-
-import javax.ejb.EJB;
-import javax.ejb.Stateless;
-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.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
@@ -38,13 +29,25 @@ import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleDeployDefinitionCriteria;
import org.rhq.core.domain.criteria.BundleDeploymentCriteria;
+import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.util.PageList;
+import org.rhq.core.domain.util.PersistenceUtility;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.authz.AuthorizationManagerLocal;
import org.rhq.enterprise.server.authz.PermissionException;
+import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal;
import org.rhq.enterprise.server.util.CriteriaQueryGenerator;
import org.rhq.enterprise.server.util.CriteriaQueryRunner;
+import javax.ejb.EJB;
+import javax.ejb.Stateless;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
+import java.util.List;
+import java.util.Random;
+import java.util.UUID;
+
/**
* Manages the creation and usage of bundles.
*
@@ -60,6 +63,9 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
@EJB
private AuthorizationManagerLocal authorizationManager;
+ @EJB
+ private ResourceTypeManagerLocal resourceTypeManager;
+
public Bundle createBundle(Subject subject, Bundle bundle) {
entityManager.persist(bundle);
return bundle;
@@ -113,10 +119,50 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
}
public PageList<Bundle> findBundlesByCriteria(Subject subject, BundleCriteria criteria) {
+ Query totalCountQuery = PersistenceUtility.createCountQuery(entityManager,
+ Bundle.QUERY_FIND_ALL);
+ long totalCount = (Long) totalCountQuery.getSingleResult();
+ if (totalCount == 0) {
+ List<BundleType> bundleTypes = getAllBundleTypes(subject);
+ for (int i = 0; i < 50; i++) {
+ createMockBundle(subject, bundleTypes);
+ }
+ }
+
CriteriaQueryGenerator generator = new CriteriaQueryGenerator(criteria);
CriteriaQueryRunner<Bundle> queryRunner = new CriteriaQueryRunner<Bundle>(criteria, generator, entityManager);
return queryRunner.execute();
}
+ public PageList<BundleDeployment> findBundleDeploymentsByCriteria(BundleDeploymentCriteria criteria) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void deleteBundles(Subject subject, int[] bundleIds) {
+ for (int bundleId : bundleIds) {
+ Bundle bundle = this.entityManager.find(Bundle.class, bundleId);
+ this.entityManager.remove(bundle);
+ }
+ }
+
+ public BundleType createMockBundleType(Subject subject) {
+ ResourceType linuxPlatformResourceType = this.resourceTypeManager.getResourceTypeByNameAndPlugin("Linux", "Platforms");
+ BundleType bundleType = new BundleType(UUID.randomUUID().toString(), linuxPlatformResourceType);
+ return createBundleType(subject, bundleType);
+ }
+
+ public Bundle createMockBundle(Subject subject, List<BundleType> bundleTypes) {
+ BundleType bundleType;
+ if (bundleTypes.isEmpty()) {
+ bundleType = createMockBundleType(subject);
+ } else {
+ Random random = new Random();
+ int randomIndex = random.nextInt(bundleTypes.size());
+ bundleType = bundleTypes.get(randomIndex);
+ }
+ Bundle bundle = new Bundle(UUID.randomUUID().toString(), bundleType);
+ return createBundle(subject, bundle);
+ }
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
index ee808d0..0dc6eb9 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
@@ -31,6 +31,7 @@ import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleDeployDefinitionCriteria;
import org.rhq.core.domain.criteria.BundleDeploymentCriteria;
+import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
/**
@@ -40,7 +41,6 @@ import org.rhq.core.domain.util.PageList;
*/
@Local
public interface BundleManagerLocal {
-
Bundle createBundle(Subject subject, Bundle b);
BundleType createBundleType(Subject subject, BundleType bundleType);
@@ -61,4 +61,6 @@ public interface BundleManagerLocal {
PageList<Bundle> findBundlesByCriteria(Subject subject, BundleCriteria criteria);
List<BundleType> getAllBundleTypes(Subject subject);
+
+ void deleteBundles(Subject subject, int[] bundleIds);
}
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 a4fd8fe..3b6454a 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
@@ -27,7 +27,11 @@ import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleType;
+import org.rhq.core.domain.criteria.BundleCriteria;
+import org.rhq.core.domain.util.PageControl;
+import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.system.ServerVersion;
/**
@@ -42,4 +46,8 @@ public interface BundleManagerRemote {
@WebMethod
List<BundleType> getAllBundleTypes( //
@WebParam(name = "subject") Subject subject);
+
+ PageList<Bundle> findBundlesByCriteria(Subject subject, BundleCriteria criteria);
+
+ void deleteBundles(Subject subject, int[] bundleIds);
}
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/pom.xml b/modules/enterprise/server/plugins/perspectives/policy/app/pom.xml
new file mode 100644
index 0000000..3c53325
--- /dev/null
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/pom.xml
@@ -0,0 +1,106 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-parent</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server-policy-perspective-war</artifactId>
+ <packaging>war</packaging>
+
+ <name>RHQ Policy Perspective War</name>
+
+ <scm>
+ <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/etc/samples/sample-perspec...</connection>
+ <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/etc/samples/sample-perspec...</developerConnection>
+ </scm>
+
+ <dependencyManagement>
+
+ <dependencies>
+
+ <!-- This will pull in the managed dependencies from the base-perspective-war pom. -->
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server-base-perspective-war</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+
+ </dependencies>
+
+ </dependencyManagement>
+
+ <dependencies>
+
+ <!-- This is needed by the war plugin for the overlay functionality. -->
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server-base-perspective-war</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <type>war</type>
+ </dependency>
+
+ <!-- This is used to pull in the war's classes and dependencies, which are not pulled in by the above dependency
+ of type war (see http://jira.codehaus.org/browse/MNG-1991). -->
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server-base-perspective-war</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <type>warpath</type>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <finalName>rhq-policy-perspective</finalName>
+
+ <plugins>
+
+ <plugin>
+ <artifactId>maven-war-plugin</artifactId>
+ <configuration>
+ <overlays>
+ <overlay>
+ <!-- empty groupId/artifactId detected as the current build.
+ earlier overlays win over later overlays, so put ourselves first. -->
+ </overlay>
+ <overlay>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server-base-perspective-war</artifactId>
+ </overlay>
+ </overlays>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.appfuse</groupId>
+ <artifactId>maven-warpath-plugin</artifactId>
+ <version>2.0.2</version>
+ <extensions>true</extensions>
+ <executions>
+ <execution>
+ <goals>
+ <goal>add-classes</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ </plugins>
+
+ </build>
+
+</project>
+
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java
new file mode 100644
index 0000000..10344d9
--- /dev/null
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/java/org/rhq/enterprise/server/perspective/policy/BundlesUIBean.java
@@ -0,0 +1,69 @@
+package org.rhq.enterprise.server.perspective.policy;
+
+import org.ajax4jsf.model.KeepAlive;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Create;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.bundle.Bundle;
+import org.rhq.core.domain.util.PageControl;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.core.gui.table.bean.AbstractPagedDataUIBean;
+import org.rhq.core.gui.table.model.PagedListDataModel;
+import org.rhq.enterprise.server.bundle.BundleManagerRemote;
+import org.rhq.enterprise.server.perspective.AbstractPerspectivePagedDataUIBean;
+
+import java.util.List;
+
+/**
+ * Provides CRUD operations for provisioning {@link Bundle}s. The backing bean for bundles.xhtml.
+ */
+@Name("BundlesUIBean")
+(a)Scope(ScopeType.EVENT)
+@KeepAlive
+public class BundlesUIBean extends AbstractPerspectivePagedDataUIBean {
+ private BundleManagerRemote bundleManager;
+ private List<Bundle> selectedBundles;
+
+ @Create
+ public void init() {
+ try {
+ this.bundleManager = this.perspectiveClient.getRemoteClient().getBundleManagerRemote();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public PagedListDataModel createDataModel() {
+ return new DataModel(this);
+ }
+
+ public List<Bundle> getSelectedBundles() {
+ return this.selectedBundles;
+ }
+
+ public void setSelectedBundles(List<Bundle> selectedResources) {
+ this.selectedBundles = selectedResources;
+ }
+
+ private class DataModel extends PagedListDataModel<Bundle> {
+ private DataModel(AbstractPagedDataUIBean pagedDataBean) {
+ super(pagedDataBean);
+ }
+
+ @Override
+ public PageList<Bundle> fetchPage(PageControl pageControl) {
+ Subject subject;
+ try {
+ subject = BundlesUIBean.this.perspectiveClient.getSubject();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ // TODO: Implement filtering.
+ PageList<Bundle> bundles = BundlesUIBean.this.bundleManager.findBundlesByCriteria(subject, null, null, pageControl);
+ return bundles;
+ }
+ }
+}
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/resources/seam.properties b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/resources/seam.properties
new file mode 100644
index 0000000..b97c770
--- /dev/null
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/resources/seam.properties
@@ -0,0 +1,3 @@
+# NOTE: The presence of this file tells Seam to scan this WAR for Seam
+# components (i.e. classes with Name annotations) and to deploy
+# any that it finds.
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/WEB-INF/components.xml b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/WEB-INF/components.xml
new file mode 100644
index 0000000..4631d2e
--- /dev/null
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/WEB-INF/components.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<components xmlns="http://jboss.com/products/seam/components"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:security="http://jboss.com/products/seam/security"
+ xsi:schemaLocation=
+ "http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.0.xsd
+ http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.0.xsd">
+
+ <component name="org.jboss.seam.core.init">
+ <property name="debug">false</property>
+ <!-- enable only when needed -->
+ <property name="transactionManagementEnabled">false</property>
+ </component>
+
+</components>
diff --git a/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml
new file mode 100644
index 0000000..102e407
--- /dev/null
+++ b/modules/enterprise/server/plugins/perspectives/policy/app/src/main/webapp/bundles.xhtml
@@ -0,0 +1,87 @@
+<?xml version="1.0"?>
+
+<ui:composition
+ template="/WEB-INF/templates/mainTemplate.xhtml"
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:c="http://java.sun.com/jstl/core"
+ xmlns:fn="http://java.sun.com/jsp/jstl/functions"
+ xmlns:a4j="http://richfaces.org/a4j"
+ xmlns:rich="http://richfaces.org/rich"
+ xmlns:rhq="http://rhq-project.org/rhq"
+ xmlns:onc="http://jboss.org/on/component">
+
+ <ui:param name="pageTitle" value="Provisioning Bundles"/>
+
+ <ui:define name="breadcrumbs">
+ <h:outputText value="Provisioning Bundles"/>
+ </ui:define>
+
+ <ui:define name="body">
+
+ <ui:remove><!-- NOTE: The table needs to be surrounded by a form for paging and sorting to work! --></ui:remove>
+ <a4j:form ajaxSubmit="false" reRender="bundlesDataTable">
+
+ <rich:dataTable id="bundlesDataTable"
+ value="#{BundlesUIBean.dataModel}" var="bundle"
+ first="#{BundlesUIBean.pageControl.pageNumber}"
+ rows="#{BundlesUIBean.pageControl.pageSize}"
+ sortMode="multi"
+ width="100%">
+
+ <rich:column width="20">
+ <f:facet name="header">
+ <rhq:allRowsSelector/>
+ </f:facet>
+ <rhq:rowSelector value="#{BundlesUIBean.selectedBundles}"/>
+ </rich:column>
+
+ <rich:column width="235" sortBy="b.name">
+ <f:facet name="header">
+ <rhq:sortableColumnHeader sortBy="b.name">
+ <a4j:support event="onclick"
+ actionListener="#{BundlesUIBean.ajaxSortListener}"/>
+ <h:outputText value="Name"/>
+ </rhq:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputLink value="#{bundle.name}">
+ <f:param name="bundleId" value="#{bundle.id}"/>
+ <h:outputText value="#{resource.id}"/>
+ </h:outputLink>
+ </rich:column>
+
+ <rich:column width="235">
+ <f:facet name="header">
+ <rhq:sortableColumnHeader sortBy="b.bundleType.name">
+ <a4j:support event="onclick"
+ actionListener="#{BundlesUIBean.ajaxSortListener}"/>
+ <h:outputText value="Type"/>
+ </rhq:sortableColumnHeader>
+ </f:facet>
+
+ <h:outputText value="#{bundle.bundleType.name}"/>
+ </rich:column>
+
+ <f:facet name="footer">
+ <rich:columnGroup>
+ <rich:column colspan="4">
+ <rhq:selectedRowsCommandButton
+ value="DELETE"
+ action="#{BundlesUIBean.deleteBundle}"/>
+
+ <ui:include src="/WEB-INF/includes/pageControls.xhtml">
+ <ui:param name="pagedDataUIBean" value="#{BundlesUIBean}"/>
+ <ui:param name="dataTableName" value="bundlesDataTable"/>
+ </ui:include>
+ </rich:column>
+ </rich:columnGroup>
+ </f:facet>
+ </rich:dataTable>
+ </a4j:form>
+
+ </ui:define>
+
+</ui:composition>
diff --git a/modules/enterprise/server/plugins/perspectives/policy/perspective/pom.xml b/modules/enterprise/server/plugins/perspectives/policy/perspective/pom.xml
new file mode 100644
index 0000000..2039f89
--- /dev/null
+++ b/modules/enterprise/server/plugins/perspectives/policy/perspective/pom.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0"?>
+
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-parent</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server-policy-perspective</artifactId>
+ <packaging>jar</packaging>
+
+ <name>RHQ Policy Perspective</name>
+ <description>a perspective that adds support to the GUI for policy and provisioning</description>
+
+ <dependencies>
+
+ <!-- Below are the apps packaged with this perspective plugin -->
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server-policy-perspective-war</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ <type>war</type>
+ </dependency>
+
+ <!-- Below are the core modules that are required dependencies of all server plugins -->
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope> <!-- provided by the server/plugin-container -->
+ </dependency>
+
+
+ <!-- uncomment the one of the three logging systems your plugin uses: log4j, commons-logging or i18nlog -->
+ <!-- all three are provided to your plugin by the server/plugin-container -->
+ <!--
+ <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.14</version>
+ <scope>provided</scope> </dependency>
+ -->
+
+ <!--
+ <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1</version>
+ <scope>provided</scope> </dependency>
+ -->
+
+ <!--
+ <dependency> <groupId>i18nlog</groupId> <artifactId>i18nlog</artifactId> <version>1.0.9</version> </dependency>
+ -->
+
+ <!-- Define any third-party dependencies your plugin has here. -->
+ <!--
+ <dependency> <groupId>group-id-of-dependency-goes-here</groupId>
+ <artifactId>artifact-id-of-dependency-goes-here</artifactId> <version>version-of-dependency-goes-here</version>
+ </dependency>
+ -->
+
+ </dependencies>
+
+ <build>
+ <plugins>
+
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.1</version>
+ <executions>
+
+ <execution>
+ <id>add-war</id>
+ <phase>verify</phase>
+ <configuration>
+ <tasks>
+ <property
+ name="classes.dir"
+ location="${rhq.deploymentDir}/WEB-INF/classes" />
+ <jar
+ update="yes"
+ destfile="${basedir}/target/${project.artifactId}-${project.version}.jar"
+ basedir="${basedir}/../app/target"
+ includes="*.war" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>dev</id>
+
+ <properties>
+ <rhq.rootDir>../../../../..</rhq.rootDir>
+ <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir>
+ <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/rhq-serverplugins</rhq.deploymentDir>
+ </properties>
+
+ <build>
+ <plugins>
+
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.1</version>
+ <executions>
+
+ <execution>
+ <id>deploy</id>
+ <phase>install</phase>
+ <configuration>
+ <tasks>
+ <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
+ <echo>*** Updating ${deployment.file}...</echo>
+ <copy file="${basedir}/target/${project.build.finalName}.jar" toDir="${rhq.deploymentDir}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ <execution>
+ <id>undeploy</id>
+ <phase>clean</phase>
+ <configuration>
+ <tasks>
+ <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
+ <echo>*** Deleting ${deployment.file}...</echo>
+ <delete file="${deployment.file}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ </executions>
+ </plugin>
+
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+</project>
diff --git a/modules/enterprise/server/plugins/perspectives/policy/perspective/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/perspectives/policy/perspective/src/main/resources/META-INF/rhq-serverplugin.xml
new file mode 100644
index 0000000..6053d09
--- /dev/null
+++ b/modules/enterprise/server/plugins/perspectives/policy/perspective/src/main/resources/META-INF/rhq-serverplugin.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<perspective-plugin
+ apiVersion="1.0"
+ version="1.0"
+ description="a perspective that adds support to the GUI for policy and provisioning"
+ displayName="Policy Perspective"
+ name="PolicyPerspective"
+ package="org.rhq.perspective.sample"
+ xmlns="urn:xmlns:rhq-serverplugin.perspective"
+ xmlns:serverplugin="urn:xmlns:rhq-serverplugin"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <!-- Declare supporting applications for this perspective -->
+ <application
+ name="policy"
+ baseUrl="/rhq-policy-perspective" />
+
+ <!-- Administration > Provisioning -->
+ <menu-item
+ name="administration.provisioning"
+ displayName="Provisioning"
+ application="policy"
+ url="bundles.seam">
+ <position
+ name="administration.content"
+ placement="after" />
+ </menu-item>
+
+</perspective-plugin>
\ No newline at end of file
diff --git a/modules/enterprise/server/plugins/perspectives/policy/pom.xml b/modules/enterprise/server/plugins/perspectives/policy/pom.xml
new file mode 100644
index 0000000..87b03cb
--- /dev/null
+++ b/modules/enterprise/server/plugins/perspectives/policy/pom.xml
@@ -0,0 +1,28 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-parent</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-server-policy-perspective-parent</artifactId>
+ <packaging>pom</packaging>
+
+ <name>RHQ Policy Perspective Parent</name>
+ <description>parent POM for modules comprising the RHQ Policy Perspective</description>
+
+ <scm>
+ <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/plugins...</connection>
+ <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/plugins...</developerConnection>
+ </scm>
+
+ <modules>
+ <module>perspective</module>
+ <module>app</module>
+ </modules>
+
+</project>
diff --git a/modules/enterprise/server/plugins/pom.xml b/modules/enterprise/server/plugins/pom.xml
index abec716..8a66c49 100644
--- a/modules/enterprise/server/plugins/pom.xml
+++ b/modules/enterprise/server/plugins/pom.xml
@@ -64,23 +64,24 @@
</dependency>
</dependencies>
- <modules>
- <module>disk</module>
- <module>yum</module>
- <module>url</module>
- <module>rhnhosted</module>
- <module>jboss-software</module>
- <module>perspectives/core</module>
- <module>alert-email</module>
- <module>alert-irc</module>
- <module>alert-mobicents</module>
- <module>alert-microblog</module>
- <module>alert-roles</module>
- <module>alert-snmp</module>
- <module>alert-subject</module>
- <module>cobbler</module>
- <module>filetemplate-bundle</module>
- <module>validate-all-serverplugins</module>
- </modules>
+ <modules>
+ <module>disk</module>
+ <module>yum</module>
+ <module>url</module>
+ <module>rhnhosted</module>
+ <module>jboss-software</module>
+ <module>perspectives/core</module>
+ <module>perspectives/policy</module>
+ <module>alert-email</module>
+ <module>alert-irc</module>
+ <module>alert-mobicents</module>
+ <module>alert-microblog</module>
+ <module>alert-roles</module>
+ <module>alert-snmp</module>
+ <module>alert-subject</module>
+ <module>cobbler</module>
+ <module>filetemplate-bundle</module>
+ <module>validate-all-serverplugins</module>
+ </modules>
-</project>
\ No newline at end of file
+</project>
commit 092d7140fd628e2ea84d112757f1c41146b43e27
Merge: f9f9338... 65b7f84...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri Feb 12 16:18:54 2010 -0500
Merge branch 'bundle' of ssh://git.fedorahosted.org/git/rhq/rhq into bundle
commit f9f93387bdf2b3fb3c193fd7320ebc710a4ac806
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri Feb 12 16:15:58 2010 -0500
Added BundleCriteria and other criteria search. BundleCriteria is tested.
More testing tbd for the others.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java
new file mode 100644
index 0000000..d446891
--- /dev/null
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/BundleCriteria.java
@@ -0,0 +1,57 @@
+/*
+ * 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.core.domain.criteria;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.rhq.core.domain.bundle.Bundle;
+
+/**
+ * @author Jay Shaughnessy
+ */
+@XmlRootElement
+(a)XmlAccessorType(XmlAccessType.FIELD)
+@SuppressWarnings("unused")
+public class BundleCriteria extends Criteria {
+ private static final long serialVersionUID = 1L;
+
+ private Integer filterId;
+ private String filterName;
+
+ private boolean fetchBundleVersions;
+
+ public BundleCriteria() {
+ super(Bundle.class);
+ }
+
+ public void addFilterId(Integer filterId) {
+ this.filterId = filterId;
+ }
+
+ public void addFilterName(String filterName) {
+ this.filterName = filterName;
+ }
+
+ public void fetchBundleVersions(boolean fetchBundleVersions) {
+ this.fetchBundleVersions = fetchBundleVersions;
+ }
+}
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 ea5d2b2..c25c0b9 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
@@ -20,6 +20,7 @@ package org.rhq.enterprise.server.bundle;
import java.util.List;
+import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@@ -33,10 +34,16 @@ import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleDeployment;
import org.rhq.core.domain.bundle.BundleType;
+import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleDeployDefinitionCriteria;
import org.rhq.core.domain.criteria.BundleDeploymentCriteria;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.RHQConstants;
+import org.rhq.enterprise.server.authz.AuthorizationManagerLocal;
+import org.rhq.enterprise.server.authz.PermissionException;
+import org.rhq.enterprise.server.util.CriteriaQueryGenerator;
+import org.rhq.enterprise.server.util.CriteriaQueryRunner;
/**
* Manages the creation and usage of bundles.
@@ -50,14 +57,22 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
@PersistenceContext(unitName = RHQConstants.PERSISTENCE_UNIT_NAME)
private EntityManager entityManager;
- public BundleType createBundleType(BundleType bundleType) {
+ @EJB
+ private AuthorizationManagerLocal authorizationManager;
+
+ public Bundle createBundle(Subject subject, Bundle bundle) {
+ entityManager.persist(bundle);
+ return bundle;
+ }
+
+ public BundleType createBundleType(Subject subject, BundleType bundleType) {
entityManager.persist(bundleType);
return bundleType;
}
- public Bundle createBundle(Bundle bundle) {
- entityManager.persist(bundle);
- return bundle;
+ public BundleVersion createBundleVersion(Subject subject, BundleVersion bundleVersion) {
+ entityManager.persist(bundleVersion);
+ return bundleVersion;
}
@SuppressWarnings("unchecked")
@@ -68,15 +83,40 @@ public class BundleManagerBean implements BundleManagerLocal, BundleManagerRemot
return types;
}
- public PageList<BundleDeployDefinition> findBundleDeployDefinitionsByCriteria(
+ public PageList<BundleDeployDefinition> findBundleDeployDefinitionsByCriteria(Subject subject,
BundleDeployDefinitionCriteria criteria) {
- // TODO Auto-generated method stub
- return null;
+
+ CriteriaQueryGenerator generator = new CriteriaQueryGenerator(criteria);
+
+ CriteriaQueryRunner<BundleDeployDefinition> queryRunner = new CriteriaQueryRunner<BundleDeployDefinition>(
+ criteria, generator, entityManager);
+ return queryRunner.execute();
+ }
+
+ public PageList<BundleDeployment> findBundleDeploymentsByCriteria(Subject subject, BundleDeploymentCriteria criteria) {
+
+ CriteriaQueryGenerator generator = new CriteriaQueryGenerator(criteria);
+ if (!authorizationManager.isInventoryManager(subject)) {
+ if (criteria.isInventoryManagerRequired()) {
+ throw new PermissionException("Subject [" + subject.getName()
+ + "] requires InventoryManager permission for requested query criteria.");
+ }
+
+ generator.setAuthorizationResourceFragment(CriteriaQueryGenerator.AuthorizationTokenType.RESOURCE, null,
+ subject.getId());
+ }
+
+ CriteriaQueryRunner<BundleDeployment> queryRunner = new CriteriaQueryRunner<BundleDeployment>(criteria,
+ generator, entityManager);
+
+ return queryRunner.execute();
}
- public PageList<BundleDeployment> findBundleDeploymentsByCriteria(BundleDeploymentCriteria criteria) {
- // TODO Auto-generated method stub
- return null;
+ public PageList<Bundle> findBundlesByCriteria(Subject subject, BundleCriteria criteria) {
+ CriteriaQueryGenerator generator = new CriteriaQueryGenerator(criteria);
+
+ CriteriaQueryRunner<Bundle> queryRunner = new CriteriaQueryRunner<Bundle>(criteria, generator, entityManager);
+ return queryRunner.execute();
}
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
index 70601b4..ee808d0 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
@@ -27,6 +27,8 @@ import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleDeployment;
import org.rhq.core.domain.bundle.BundleType;
+import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.criteria.BundleDeployDefinitionCriteria;
import org.rhq.core.domain.criteria.BundleDeploymentCriteria;
import org.rhq.core.domain.util.PageList;
@@ -38,13 +40,12 @@ import org.rhq.core.domain.util.PageList;
*/
@Local
public interface BundleManagerLocal {
- BundleType createBundleType(BundleType bundleType);
- Bundle createBundle(Bundle b);
+ Bundle createBundle(Subject subject, Bundle b);
- PageList<BundleDeployDefinition> findBundleDeployDefinitionsByCriteria(BundleDeployDefinitionCriteria criteria);
+ BundleType createBundleType(Subject subject, BundleType bundleType);
- PageList<BundleDeployment> findBundleDeploymentsByCriteria(BundleDeploymentCriteria criteria);
+ BundleVersion createBundleVersion(Subject subject, BundleVersion bundleVersion);
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
@@ -52,5 +53,12 @@ public interface BundleManagerLocal {
//
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ PageList<BundleDeployDefinition> findBundleDeployDefinitionsByCriteria(Subject subject,
+ BundleDeployDefinitionCriteria criteria);
+
+ PageList<BundleDeployment> findBundleDeploymentsByCriteria(Subject subject, BundleDeploymentCriteria criteria);
+
+ PageList<Bundle> findBundlesByCriteria(Subject subject, BundleCriteria criteria);
+
List<BundleType> getAllBundleTypes(Subject subject);
}
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
index 5e65547..35666db 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
@@ -26,6 +26,7 @@ import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.transaction.TransactionManager;
+import org.hibernate.LazyInitializationException;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@@ -34,19 +35,24 @@ import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.Bundle;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
+import org.rhq.core.domain.criteria.BundleCriteria;
import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.test.AbstractEJB3Test;
import org.rhq.enterprise.server.util.LookupUtil;
/**
* @author John Mazzitelli
*/
+@SuppressWarnings("unchecked")
@Test
public class BundleManagerBeanTest extends AbstractEJB3Test {
private static final String TEST_PREFIX = "bundletest";
+ private static final boolean ENABLED = true;
+
private BundleManagerLocal bundleManagerBean;
@BeforeMethod
@@ -107,6 +113,7 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
}
}
+ @Test(enabled = ENABLED)
public void testGetBundleTypes() throws Exception {
BundleType bt1 = createBundleType("one");
BundleType bt2 = createBundleType("two");
@@ -122,6 +129,68 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
assert btNames.contains(bt2.getName());
}
+ @Test(enabled = ENABLED)
+ public void testfindBundlesByCriteria() throws Exception {
+ Bundle b1 = createBundle("one");
+ Bundle b2 = createBundle("two");
+ BundleVersion bv1 = createBundleVersion(b1.getName(), "1.0", b1);
+ BundleVersion bv2 = createBundleVersion(b2.getName(), "1.0", b2);
+ BundleCriteria c = new BundleCriteria();
+ PageList<Bundle> bundles = null;
+ Bundle b = null;
+ String name = null;
+
+ // return all with no optional data
+ bundles = bundleManagerBean.findBundlesByCriteria(getOverlord(), c);
+ assertNotNull(bundles);
+ assertEquals(2, bundles.size());
+ b = bundles.get(0);
+ name = "one";
+ assertNotNull(b);
+ assertTrue(b.getBundleType().getName(), b.getName().contains(name));
+ assertTrue(b.getBundleType().getName(), b.getBundleType().getName().contains(name));
+ try {
+ assertTrue(b.getBundleVersions().isEmpty());
+ fail("Should have thrown LazyInitializationException");
+ } catch (LazyInitializationException e) {
+ // expected
+ } catch (Exception e) {
+ fail("Should have thrown LazyInitializationException");
+ }
+
+ b = bundles.get(1);
+ name = "two";
+ assertNotNull(b);
+ assertTrue(b.getBundleType().getName(), b.getName().contains(name));
+ assertTrue(b.getBundleType().getName(), b.getBundleType().getName().contains(name));
+
+ // return bundle "two" using all criteria and with all optional data
+ c.addFilterId(b.getId());
+ c.addFilterName(b.getName());
+ c.fetchBundleVersions(true);
+ bundles = bundleManagerBean.findBundlesByCriteria(getOverlord(), c);
+ assertNotNull(bundles);
+ assertEquals(1, bundles.size());
+ b = bundles.get(0);
+ assertTrue(b.getBundleType().getName(), b.getName().contains(name));
+ assertTrue(b.getBundleType().getName(), b.getBundleType().getName().contains(name));
+ assertNotNull(b.getBundleVersions());
+ assertEquals(1, b.getBundleVersions().size());
+ BundleVersion bv = b.getBundleVersions().get(0);
+ assertEquals(bv2, bv);
+ assertEquals(b, bv.getBundle());
+ }
+
+ private BundleType createBundleType(String name) throws Exception {
+ final String fullName = TEST_PREFIX + "-type-" + name;
+ BundleType bt = new BundleType(fullName, createResourceType(name));
+ bt = bundleManagerBean.createBundleType(getOverlord(), bt);
+
+ assert bt.getId() > 0;
+ assert bt.getName().endsWith(fullName);
+ return bt;
+ }
+
private Bundle createBundle(String name) throws Exception {
BundleType bt = createBundleType(name);
return createBundle(name, bt);
@@ -130,19 +199,22 @@ public class BundleManagerBeanTest extends AbstractEJB3Test {
private Bundle createBundle(String name, BundleType bt) throws Exception {
final String fullName = TEST_PREFIX + "-bundle-" + name;
Bundle b = new Bundle(fullName, bt);
- b = bundleManagerBean.createBundle(b);
+ b = bundleManagerBean.createBundle(getOverlord(), b);
+
assert b.getId() > 0;
assert b.getName().endsWith(fullName);
return b;
}
- private BundleType createBundleType(String name) throws Exception {
- final String fullName = TEST_PREFIX + "-type-" + name;
- BundleType bt = new BundleType(fullName, createResourceType(name));
- bt = bundleManagerBean.createBundleType(bt);
- assert bt.getId() > 0;
- assert bt.getName().endsWith(fullName);
- return bt;
+ private BundleVersion createBundleVersion(String name, String version, Bundle bundle) throws Exception {
+ final String fullName = TEST_PREFIX + "-version-" + version + "-" + name;
+ final String recipe = TEST_PREFIX + "-recipe-" + name;
+ BundleVersion bv = new BundleVersion(fullName, version, bundle, recipe);
+ bv = bundleManagerBean.createBundleVersion(getOverlord(), bv);
+
+ assert bv.getId() > 0;
+ assert bv.getName().endsWith(fullName);
+ return bv;
}
private ResourceType createResourceType(String name) throws Exception {
commit b46293bdcd898427141b4f13f4f75af64ed87b93
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri Feb 12 16:14:51 2010 -0500
Change name of action to "recipe". We can change it back but it seems we
call this recipe all of the time, regardless of bundle type. For now,
will leave the db column as ACTION.
Added parameterized constructor to suppoert a simple create() slsb method.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java
index 38a3439..202eeac 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleVersion.java
@@ -74,7 +74,7 @@ public class BundleVersion implements Serializable {
private String version;
@Column(name = "ACTION", nullable = false)
- private String action;
+ private String recipe;
@JoinColumn(name = "BUNDLE_ID", referencedColumnName = "ID", nullable = false)
@ManyToOne(fetch = FetchType.LAZY)
@@ -92,10 +92,11 @@ public class BundleVersion implements Serializable {
// for JPA use
}
- public BundleVersion(String name, String version, Bundle bundle) {
+ public BundleVersion(String name, String version, Bundle bundle, String recipe) {
setName(name);
setVersion(version);
setBundle(bundle);
+ setRecipe(recipe);
}
public int getId() {
@@ -122,12 +123,12 @@ public class BundleVersion implements Serializable {
this.version = version;
}
- public String getAction() {
- return action;
+ public String getRecipe() {
+ return recipe;
}
- public void setAction(String action) {
- this.action = action;
+ public void setRecipe(String recipe) {
+ this.recipe = recipe;
}
public Bundle getBundle() {
commit be423884b755fb90162766c5e917346c354e5464
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri Feb 12 16:12:32 2010 -0500
Remove CascadeType.PERSIST on bundleType as the BundleType should already
be defined in the db and not persisted as part of the bundle entity.
Added bundleVersions OneToMany to allow bv access from the bundle.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
index 8faec6c..7c5cda5 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/Bundle.java
@@ -23,6 +23,8 @@
package org.rhq.core.domain.bundle;
import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
@@ -35,6 +37,7 @@ import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
+import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlAccessType;
@@ -67,9 +70,12 @@ public class Bundle implements Serializable {
private String name;
@JoinColumn(name = "BUNDLE_TYPE_ID", referencedColumnName = "ID", nullable = false)
- @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
+ @ManyToOne(fetch = FetchType.EAGER)
private BundleType bundleType;
+ @OneToMany(mappedBy = "bundle", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
+ private List<BundleVersion> bundleVersions = new ArrayList<BundleVersion>();
+
public Bundle() {
// for JPA use
}
@@ -103,6 +109,19 @@ public class Bundle implements Serializable {
this.bundleType = bundleType;
}
+ public List<BundleVersion> getBundleVersions() {
+ return bundleVersions;
+ }
+
+ public void addBundleVersion(BundleVersion bundleVersion) {
+ this.bundleVersions.add(bundleVersion);
+ bundleVersion.setBundle(this);
+ }
+
+ public void setBundleVersions(List<BundleVersion> bundleVersions) {
+ this.bundleVersions = bundleVersions;
+ }
+
@Override
public String toString() {
return "Bundle[id=" + id + ",name=" + name + ",bundleType=" + bundleType + "]";
commit 89383e0f0657bb17458442936dc92b35baa3f7ba
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri Feb 12 16:10:30 2010 -0500
fix a version problem in the sample perspective build
diff --git a/etc/samples/perspectives/sample-perspective/perspective/pom.xml b/etc/samples/perspectives/sample-perspective/perspective/pom.xml
index 8a9587a..e0ad5c4 100644
--- a/etc/samples/perspectives/sample-perspective/perspective/pom.xml
+++ b/etc/samples/perspectives/sample-perspective/perspective/pom.xml
@@ -30,7 +30,7 @@
<dependency>
<groupId>org.rhq</groupId>
<artifactId>rhq-sample-perspective-war</artifactId>
- <version>${rhq.version}</version>
+ <version>1.0.0-SNAPSHOT</version>
<scope>provided</scope>
<type>war</type>
</dependency>
commit 65b7f843d2d07bf4d36a5ea0da61aac94d0345d1
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 12 11:46:56 2010 -0500
the installer should create a keystore with the server's public endpoint in the CN
this is BZ 564409
diff --git a/modules/enterprise/gui/installer-war/pom.xml b/modules/enterprise/gui/installer-war/pom.xml
index 3481a24..6c9121b 100644
--- a/modules/enterprise/gui/installer-war/pom.xml
+++ b/modules/enterprise/gui/installer-war/pom.xml
@@ -57,6 +57,13 @@
</dependency>
<dependency>
+ <!-- need this solely for SecurityUtils -->
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-comm</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
<groupId>ant</groupId>
<artifactId>ant</artifactId>
<version>1.6.5</version>
diff --git a/modules/enterprise/gui/installer-war/src/main/java/org/rhq/enterprise/installer/ConfigurationBean.java b/modules/enterprise/gui/installer-war/src/main/java/org/rhq/enterprise/installer/ConfigurationBean.java
index 90f4072..bca6381 100644
--- a/modules/enterprise/gui/installer-war/src/main/java/org/rhq/enterprise/installer/ConfigurationBean.java
+++ b/modules/enterprise/gui/installer-war/src/main/java/org/rhq/enterprise/installer/ConfigurationBean.java
@@ -722,6 +722,9 @@ public class ConfigurationBean {
// Ensure the install server info is up to date and stored in the DB
serverInfo.storeServer(configurationAsProperties, haServer);
+ // build a keystore whose cert has a CN of this server's public endpoint address
+ serverInfo.createKeystore(haServer);
+
// now deploy RHQ Server fully
serverInfo.moveDeploymentArtifacts(true);
} catch (Exception e) {
diff --git a/modules/enterprise/gui/installer-war/src/main/java/org/rhq/enterprise/installer/ServerInformation.java b/modules/enterprise/gui/installer-war/src/main/java/org/rhq/enterprise/installer/ServerInformation.java
index f90c526..0896ace 100644
--- a/modules/enterprise/gui/installer-war/src/main/java/org/rhq/enterprise/installer/ServerInformation.java
+++ b/modules/enterprise/gui/installer-war/src/main/java/org/rhq/enterprise/installer/ServerInformation.java
@@ -61,6 +61,7 @@ import org.rhq.core.db.SQLServerDatabaseType;
import org.rhq.core.db.setup.DBSetup;
import org.rhq.core.util.PropertiesFileUpdate;
import org.rhq.core.util.jdbc.JDBCUtil;
+import org.rhq.enterprise.communications.util.SecurityUtil;
/**
* Finds out information about the RHQ Server and the JBossAS server it is running in. It can also be used to modify
@@ -97,6 +98,7 @@ public class ServerInformation {
private File binDirectory = null;
private File logDirectory = null;
private File dataDirectory = null;
+ private File confDirectory = null;
public ServerInformation() {
// This is called both within the context of the GUI and the auto-install startup servlet.
@@ -565,6 +567,18 @@ public class ServerInformation {
return dataDirectory;
}
+ private File getConfDirectory() {
+ if (confDirectory == null) {
+ MBeanServer mbs = getMBeanServer();
+ ObjectName name = ObjectNameFactory.create("jboss.system:type=ServerConfig");
+ Object mbean = MBeanServerInvocationHandler.newProxyInstance(mbs, name, ServerConfig.class, false);
+
+ confDirectory = new File(((ServerConfig) mbean).getServerHomeDir(), "conf");
+ }
+
+ return confDirectory;
+ }
+
private MBeanServer getMBeanServer() {
if (mbeanServer == null) {
mbeanServer = MBeanServerLocator.locateJBoss();
@@ -1230,4 +1244,40 @@ public class ServerInformation {
}
}
+ public void createKeystore(Server haServer) {
+ File confDir = getConfDirectory();
+ File keystore = new File(confDir, "rhq.keystore");
+ File keystoreBackup = new File(confDir, "rhq.keystore.backup");
+
+ // if there is one out-of-box, we want to remove it and create one with our proper CN
+ if (keystore.exists()) {
+ keystoreBackup.delete();
+ if (!keystore.renameTo(keystoreBackup)) {
+ LOG.warn("Cannot backup existing keystore - cannot generate a new cert with a proper domain name. ["
+ + keystore + "] will be the keystore used by this server");
+ return;
+ }
+ }
+
+ try {
+ String keystorePath = keystore.getAbsolutePath();
+ String keyAlias = "RHQ";
+ String domainName = "CN=" + haServer.endpointAddress + ", OU=RHQ, O=rhq-project.org, C=US";
+ String keystorePassword = "RHQManagement";
+ String keyPassword = keystorePassword;
+ String keyAlgorithm = "rsa";
+ int validity = 7300;
+ SecurityUtil.createKeyStore(keystorePath, keyAlias, domainName, keystorePassword, keyPassword,
+ keyAlgorithm, validity);
+ LOG.info("New keystore created [" + keystorePath + "] with cert domain name of [" + domainName + "]");
+ } catch (Exception e) {
+ LOG.warn("Could not generate a new cert with a proper domain name, will use the original keystore");
+ keystore.delete();
+ if (!keystoreBackup.renameTo(keystore)) {
+ LOG.warn("Failed to restore the original keystore from backup - please rename [" + keystoreBackup
+ + "] to [" + keystore + "]");
+ }
+ }
+ }
+
}
\ No newline at end of file
commit 619e5ea07de1ed26e790ed148911fb2bf4d3dd26
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 12 11:17:54 2010 -0500
should use rhq-project as the org name
diff --git a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/ServiceContainer.java b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/ServiceContainer.java
index 9f79ab4..6d1bf38 100644
--- a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/ServiceContainer.java
+++ b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/ServiceContainer.java
@@ -1355,7 +1355,7 @@ public class ServiceContainer {
*/
private void createKeyStore() {
SecurityUtil.createKeyStore(m_configuration.getConnectorSecurityKeystoreFile(), m_configuration
- .getConnectorSecurityKeystoreAlias(), "CN=RHQ, OU=RedHat, O=redhat.com, C=US", m_configuration
+ .getConnectorSecurityKeystoreAlias(), "CN=RHQ, OU=RHQ, O=rhq-project.org, C=US", m_configuration
.getConnectorSecurityKeystorePassword(), m_configuration.getConnectorSecurityKeystoreKeyPassword(), "DSA",
36500);
commit 63287379ccdcf153e57e7da89d56e459547acf49
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 12 10:42:27 2010 -0500
opps.. this sample plugin has been deleted, remove from eclipse classpath
diff --git a/.classpath b/.classpath
index 8c4665b..e9a098f 100644
--- a/.classpath
+++ b/.classpath
@@ -128,7 +128,6 @@
<classpathentry kind="src" path="modules/helpers/pluginAnnotations/src/main/java"/>
<classpathentry kind="src" path="modules/helpers/pluginGen/src/main/java"/>
<classpathentry kind="src" path="etc/samples/skeleton-plugin/src/main/java"/>
- <classpathentry kind="src" path="etc/samples/custom-bundle-plugin/src/main/java"/>
<classpathentry kind="src" path="etc/samples/custom-serverplugin/src/main/java"/>
<classpathentry kind="src" path="etc/samples/simplereport-serverplugin/src/main/java"/>
<classpathentry kind="src" path="etc/agentspawn/src/main/java"/>
commit f71b39d42542bbf2e2ed3c67520179a70eeabfd1
Merge: 01e9c60... d80bb12...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Thu Feb 11 09:48:47 2010 -0500
Merge branch 'bundle' into bundle-jay
Conflicts:
modules/enterprise/gui/portal-war/src/main/webapp/resource/hub/GroupHub.jsp
commit 01e9c607c759c86b68ad352544773281d9cb8639
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Thu Feb 11 09:47:03 2010 -0500
git forced LT commit
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/resource/hub/GroupHub.jsp b/modules/enterprise/gui/portal-war/src/main/webapp/resource/hub/GroupHub.jsp
index 26721d4..f61437d 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/resource/hub/GroupHub.jsp
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/resource/hub/GroupHub.jsp
@@ -1,369 +1,369 @@
-<%@ page language="java" %>
-
-<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
-<%@ taglib uri="http://jakarta.apache.org/struts/tags-html-el" prefix="html" %>
-<%@ taglib uri="http://jakarta.apache.org/struts/tags-tiles" prefix="tiles" %>
-<%@ taglib uri="/WEB-INF/tld/display.tld" prefix="display" %>
-<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
-<%@ taglib uri="/WEB-INF/tld/hq.tld" prefix="hq" %>
-
-<tiles:importAttribute name="nameSort" ignore="false" scope="page"/>
-<tiles:importAttribute name="typeSort" ignore="false"/>
-
-<script language="JavaScript" src="<html:rewrite page="/js/functions.js"/>" type="text/javascript"></script>
-<script language="JavaScript" src="<html:rewrite page="/js/listWidget.js"/>" type="text/javascript"></script>
-<c:set var="widgetInstanceName" value="listResources"/>
-<script type="text/javascript">
- var pageData = new Array();
- var FOO = "chart";
- var LIST = "list";
- var imagePath = "<html:rewrite page="/images/"/>";
-
- initializeWidgetProperties('<c:out value="${widgetInstanceName}"/>');
- widgetProperties = getWidgetProperties('<c:out value="${widgetInstanceName}"/>');
-</script>
-
-<hq:constant var="PLATFORM"
- classname="org.rhq.core.domain.resource.ResourceCategory"
- symbol="PLATFORM"/>
-<hq:constant var="SERVER"
- classname="org.rhq.core.domain.resource.ResourceCategory"
- symbol="SERVER"/>
-<hq:constant var="SERVICE"
- classname="org.rhq.core.domain.resource.ResourceCategory"
- symbol="SERVICE"/>
-
-<hq:constant var="COMPAT_GROUP"
- classname="org.rhq.core.domain.resource.group.GroupCategory"
- symbol="COMPATIBLE"/>
-<hq:constant var="MIXED_GROUP"
- classname="org.rhq.core.domain.resource.group.GroupCategory"
- symbol="MIXED"/>
-
-<c:choose>
- <c:when test="${GroupHubForm.groupCategory == COMPAT_GROUP}">
- <fmt:message var="resourceTypeTH" key="resource.hub.GroupTypeTH"/>
- </c:when>
- <%--
- Since mixed groups don't have a resourceType, do NOT set the
- resourceTypeTH, which will suppress the display of that column
- for Mixed groups.
- --%>
-</c:choose>
-
-
-<html:form method="GET" action="/GroupHub">
- <html:hidden property="groupCategory" value="${GroupHubForm.groupCategory}"/>
- <tiles:insert definition=".page.title.resource.hub">
- <tiles:put name="titleName">
- <c:out value="${navHierarchy}"/>
- </tiles:put>
- <tiles:put name="showSearch" value="true"/>
- </tiles:insert>
-</html:form>
-
-
-<html:form method="GET" action="/resource/hub/RemoveGroup.do">
-
- <c:if test="${not empty ResourceSummary}">
- <table width="100%" cellpadding="0" cellspacing="0" border="0">
- <tr>
- <td class="ResourceHubBlockTitle" width="100%">
-
- <c:url var="platformUrl" value="/ResourceHub.do">
- <c:param name="resourceCategory" value="${PLATFORM}"/>
- </c:url>
- <html:link href="${platformUrl}">
- <fmt:message key="resource.hub.filter.platform"/>
- ( <c:out value="${ResourceSummary.platformCount}"/> )
- </html:link>
- |
-
- <c:url var="serverUrl" value="/ResourceHub.do">
- <c:param name="resourceCategory" value="${SERVER}"/>
- </c:url>
- <html:link href="${serverUrl}">
- <fmt:message key="resource.hub.filter.server"/>
- ( <c:out value="${ResourceSummary.serverCount}"/> )
- </html:link>
- |
-
- <c:url var="serviceUrl" value="/ResourceHub.do">
- <c:param name="resourceCategory" value="${SERVICE}"/>
- </c:url>
- <html:link href="${serviceUrl}">
- <fmt:message key="resource.hub.filter.service"/>
- ( <c:out value="${ResourceSummary.serviceCount}"/> )
- </html:link>
- |
-
- <c:choose>
- <c:when test="${GroupHubForm.groupCategory == COMPAT_GROUP}">
- <fmt:message key="resource.hub.filter.compatibleGroups"/>
- ( <c:out value="${ResourceSummary.compatibleGroupCount}"/> )
- </c:when>
- <c:otherwise>
- <c:url var="groupUrl" value="/GroupHub.do">
- <c:param name="groupCategory" value="${COMPAT_GROUP}"/>
- </c:url>
- <html:link href="${groupUrl}">
- <fmt:message key="resource.hub.filter.compatibleGroups"/>
- ( <c:out value="${ResourceSummary.compatibleGroupCount}"/> )
- </html:link>
- </c:otherwise>
- </c:choose>
- |
- <c:choose>
- <c:when test="${GroupHubForm.groupCategory == MIXED_GROUP}">
- <fmt:message key="resource.hub.filter.mixedGroups"/>
- ( <c:out value="${ResourceSummary.mixedGroupCount}"/> )
- </c:when>
- <c:otherwise>
- <c:url var="groupUrl" value="/GroupHub.do">
- <c:param name="groupCategory" value="${MIXED_GROUP}"/>
- </c:url>
- <html:link href="${groupUrl}">
- <fmt:message key="resource.hub.filter.mixedGroups"/>
- ( <c:out value="${ResourceSummary.mixedGroupCount}"/> )
- </html:link>
- </c:otherwise>
- </c:choose>
- |
- <html:link href="/rhq/definition/group/list.xhtml">
- <fmt:message key="resource.hub.filter.groupDefinitions"/>
- ( <c:out value="${ResourceSummary.groupDefinitionCount}"/> )
- </html:link>
- </td>
- </tr>
- </table>
- </c:if>
-
- <fmt:message var="pluginTH" key="resource.hub.PluginTH"/>
-
- <tiles:insert definition=".portlet.confirm"/>
- <tiles:insert definition=".portlet.error"/>
-
- <!-- FILTER TOOLBAR CONTENTS -->
-
- <c:url var="resourceTypeAction" value="/GroupHub.do">
- <c:if test="${not empty param.keywords}">
- <c:param name="keywords" value="${param.keywords}"/>
- </c:if>
- <c:if test="${not empty param.ps}">
- <c:param name="ps" value="${param.ps}"/>
- </c:if>
- <c:if test="${not empty param.so}">
- <c:param name="so" value="${param.so}"/>
- </c:if>
- <c:if test="${not empty param.sc}">
- <c:param name="sc" value="${param.sc}"/>
- </c:if>
- <c:if test="${not empty param.plugin}">
- <c:param name="plugin" value="${param.plugin}"/>
- </c:if>
- <c:param name="groupCategory" value="${GroupHubForm.groupCategory}"/>
- </c:url>
- <c:url var="pluginAction" value="/GroupHub.do">
- <c:if test="${not empty param.keywords}">
- <c:param name="keywords" value="${param.keywords}"/>
- </c:if>
- <c:if test="${not empty param.ps}">
- <c:param name="ps" value="${param.ps}"/>
- </c:if>
- <c:if test="${not empty param.so}">
- <c:param name="so" value="${param.so}"/>
- </c:if>
- <c:if test="${not empty param.sc}">
- <c:param name="sc" value="${param.sc}"/>
- </c:if>
- <c:if test="${not empty param.resourceType}">
- <c:param name="resourceType" value="${param.resourceType}"/>
- </c:if>
- <c:param name="groupCategory" value="${GroupHubForm.groupCategory}"/>
- </c:url>
-
- <table width="100%" cellpadding="0" cellspacing="0" border="0">
- <tr>
- <td class="FilterLine" colspan="3">
- <html:img page="/images/spacer.gif" width="1" height="1" border="0"/>
- </td>
- </tr>
- <tr>
- <td class="FilterLabelText" nowrap="nowrap" align="right">
- <c:choose>
- <c:when test="${GroupHubForm.types == null}">
- <html:hidden property="resourceType" value=""/>
-
- </c:when>
- <c:otherwise>
- <fmt:message key="Filter.ViewLabel"/>
- </td>
- <td class="FilterLabelText">
- <html:select property="resourceType" styleClass="FilterFormText" size="1"
- onchange="goToSelectLocation(this, 'resourceType', '${resourceTypeAction}');">
- <html:optionsCollection property="types"/>
- </html:select>
- </c:otherwise>
- </c:choose>
- </td>
- <td class="FilterLabelText" width="100%">
- <c:choose>
- <c:when test="${GroupHubForm.plugins == null}">
- <html:hidden property="plugin" value=""/>
-
- </c:when>
- <c:otherwise>
- <html:select property="plugin" styleClass="FilterFormText" size="1"
- onchange="goToSelectLocation(this, 'plugin', '${pluginAction}');">
- <html:optionsCollection property="plugins"/>
- </html:select>
- </c:otherwise>
- </c:choose>
- </td>
-
- <c:url var="viewAction" value="/GroupHub.do">
- <c:if test="${not empty param.keywords}">
- <c:param name="keywords" value="${param.keywords}"/>
- </c:if>
- <c:if test="${not empty param.pn}">
- <c:param name="pn" value="${param.pn}"/>
- </c:if>
- <c:if test="${not empty param.so}">
- <c:param name="so" value="${param.so}"/>
- </c:if>
- <c:if test="${not empty param.sc}">
- <c:param name="sc" value="${param.sc}"/>
- </c:if>
- <c:if test="${not empty param.resourceType}">
- <c:param name="resourceType" value="${param.resourceType}"/>
- </c:if>
- <c:if test="${not empty param.plugin}">
- <c:param name="plugin" value="${param.plugin}"/>
- </c:if>
-
- <c:param name="groupCategory" value="${GroupHubForm.groupCategory}"/>
- </c:url>
-
- </tr>
- </table>
- <!-- / -->
-
- <!-- GROUP HUB CONTENTS -->
- <c:url var="sAction" value="/GroupHub.do">
- <c:if test="${not empty param.keywords}">
- <c:param name="keywords" value="${param.keywords}"/>
- </c:if>
- <c:if test="${not empty param.ps}">
- <c:param name="ps" value="${param.ps}"/>
- </c:if>
- <c:if test="${not empty param.pn}">
- <c:param name="pn" value="${param.pn}"/>
- </c:if>
- <c:if test="${not empty param.so}">
- <c:param name="so" value="${param.so}"/>
- </c:if>
- <c:if test="${not empty param.sc}">
- <c:param name="sc" value="${param.sc}"/>
- </c:if>
- <c:if test="${not empty param.resourceType}">
- <c:param name="resourceType" value="${param.resourceType}"/>
- </c:if>
- <c:if test="${not empty param.plugin}">
- <c:param name="plugin" value="${param.plugin}"/>
- </c:if>
- <c:param name="groupCategory" value="${GroupHubForm.groupCategory}"/>
- </c:url>
-
-
- <display:table items="${AllResources}" var="groupComposite" action="${sAction}"
- width="100%" cellspacing="0" cellpadding="0" styleId="resourceHub">
-
- <display:column width="1%" property="resourceGroup.id"
- title="<input type=\"checkbox\" onclick=\"ToggleAll(this, widgetProperties)\" name=\"listToggleAll\">"
- isLocalizedTitle="false" styleClass="ListCellCheckbox" headerStyleClass="ListHeaderCheckbox">
- <display:checkboxdecorator name="resources" onclick="ToggleSelection(this, widgetProperties)" styleClass="listMember"/>
- </display:column>
-
- <display:column width="5%" value="${groupComposite}" title="nbsp" nowrap="true">
- <display:group-quicknav-decorator/>
- </display:column>
-
- <c:choose>
- <c:when test="${GroupHubForm.groupCategory == 'COMPATIBLE'}">
- <display:column width="25%" property="resourceGroup.name" title="common.header.Group"
- isLocalizedTitle="true" sortAttr="groupName"
- href="/rhq/group/monitor/graphs.xhtml?category=${GroupHubForm.groupCategory}&groupId=${groupComposite.resourceGroup.id}"/>
- </c:when>
- <c:otherwise>
- <display:column width="25%" property="resourceGroup.name" title="common.header.Group"
- isLocalizedTitle="true" sortAttr="groupName"
- href="/rhq/group/inventory/view.xhtml?category=${GroupHubForm.groupCategory}&groupId=${groupComposite.resourceGroup.id}"/>
- </c:otherwise>
- </c:choose>
- <c:if test="${not empty resourceTypeTH}">
- <display:column width="15%" property="resourceGroup.resourceType.name" title="${resourceTypeTH}"
- isLocalizedTitle="false" sortAttr="resourceTypeName" />
- <display:column width="10%" property="resourceGroup.resourceType.plugin" title="${pluginTH}"
- isLocalizedTitle="false" sortAttr="res.resourceType.plugin" />
- </c:if>
-
- <display:column width="30%" property="resourceGroup.description"
- title="common.header.Description" sortAttr="groupDescription"/>
-
- <display:column width="10%" property="explicitFormatted" title="resource.common.monitor.visibility.ChildAvailabilityTH"
- headerStyleClass="ListHeaderCheckbox" valign="middle"
- sortAttr="explicitAvail"/>
-
- <display:column width="10%" property="implicitFormatted" title="resource.common.monitor.visibility.DescendentAvailabilityTH"
- headerStyleClass="ListHeaderCheckbox" valign="middle"
- sortAttr="implicitAvail"/>
-
- </display:table>
- <!-- / -->
-
- <c:url var="pageAction" value="/GroupHub.do">
- <c:if test="${not empty param.keywords}">
- <c:param name="keywords" value="${param.keywords}"/>
- </c:if>
- <c:if test="${not empty param.resourceType}">
- <c:param name="resourceType" value="${param.resourceType}"/>
- </c:if>
- <c:if test="${not empty param.plugin}">
- <c:param name="plugin" value="${param.plugin}"/>
- </c:if>
-
- <c:param name="groupCategory" value="${GroupHubForm.groupCategory}"/>
-
- <c:if test="${not empty param.so}">
- <c:param name="so" value="${param.so}"/>
- </c:if>
- <c:if test="${not empty param.sc}">
- <c:param name="sc" value="${param.sc}"/>
- </c:if>
-
- <c:if test="${not empty param.pn}">
- <c:param name="pn" value="${param.pn}"/>
- </c:if>
- <c:if test="${not empty param.ps}">
- <c:param name="ps" value="${param.ps}"/>
- </c:if>
- </c:url>
-
- <%-- I am a bit weary of this as the listNewUrl won't work in RHQ. --%>
- <tiles:insert definition=".toolbar.list">
- <tiles:put name="listNewUrl" value="/resource/platform/Inventory.do?mode=new"/>
- <tiles:put name="deleteOnly" value="true"/>
- <tiles:put name="pageList" beanName="AllResources"/>
- <tiles:put name="widgetInstanceName" beanName="widgetInstanceName"/>
- <tiles:put name="pageAction" beanName="pageAction"/>
- </tiles:insert>
-
- <html:hidden property="view"/>
- <html:hidden property="groupCategory"/>
-
- </html:form>
- <tiles:insert definition=".page.footer"/>
-
- <script type="text/javascript">
- clearIfAnyChecked();
- </script>
+<%@ page language="java" %>
+
+<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
+<%@ taglib uri="http://jakarta.apache.org/struts/tags-html-el" prefix="html" %>
+<%@ taglib uri="http://jakarta.apache.org/struts/tags-tiles" prefix="tiles" %>
+<%@ taglib uri="/WEB-INF/tld/display.tld" prefix="display" %>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
+<%@ taglib uri="/WEB-INF/tld/hq.tld" prefix="hq" %>
+
+<tiles:importAttribute name="nameSort" ignore="false" scope="page"/>
+<tiles:importAttribute name="typeSort" ignore="false"/>
+
+<script language="JavaScript" src="<html:rewrite page="/js/functions.js"/>" type="text/javascript"></script>
+<script language="JavaScript" src="<html:rewrite page="/js/listWidget.js"/>" type="text/javascript"></script>
+<c:set var="widgetInstanceName" value="listResources"/>
+<script type="text/javascript">
+ var pageData = new Array();
+ var FOO = "chart";
+ var LIST = "list";
+ var imagePath = "<html:rewrite page="/images/"/>";
+
+ initializeWidgetProperties('<c:out value="${widgetInstanceName}"/>');
+ widgetProperties = getWidgetProperties('<c:out value="${widgetInstanceName}"/>');
+</script>
+
+<hq:constant var="PLATFORM"
+ classname="org.rhq.core.domain.resource.ResourceCategory"
+ symbol="PLATFORM"/>
+<hq:constant var="SERVER"
+ classname="org.rhq.core.domain.resource.ResourceCategory"
+ symbol="SERVER"/>
+<hq:constant var="SERVICE"
+ classname="org.rhq.core.domain.resource.ResourceCategory"
+ symbol="SERVICE"/>
+
+<hq:constant var="COMPAT_GROUP"
+ classname="org.rhq.core.domain.resource.group.GroupCategory"
+ symbol="COMPATIBLE"/>
+<hq:constant var="MIXED_GROUP"
+ classname="org.rhq.core.domain.resource.group.GroupCategory"
+ symbol="MIXED"/>
+
+<c:choose>
+ <c:when test="${GroupHubForm.groupCategory == COMPAT_GROUP}">
+ <fmt:message var="resourceTypeTH" key="resource.hub.GroupTypeTH"/>
+ </c:when>
+ <%--
+ Since mixed groups don't have a resourceType, do NOT set the
+ resourceTypeTH, which will suppress the display of that column
+ for Mixed groups.
+ --%>
+</c:choose>
+
+
+<html:form method="GET" action="/GroupHub">
+ <html:hidden property="groupCategory" value="${GroupHubForm.groupCategory}"/>
+ <tiles:insert definition=".page.title.resource.hub">
+ <tiles:put name="titleName">
+ <c:out value="${navHierarchy}"/>
+ </tiles:put>
+ <tiles:put name="showSearch" value="true"/>
+ </tiles:insert>
+</html:form>
+
+
+<html:form method="GET" action="/resource/hub/RemoveGroup.do">
+
+ <c:if test="${not empty ResourceSummary}">
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="ResourceHubBlockTitle" width="100%">
+
+ <c:url var="platformUrl" value="/ResourceHub.do">
+ <c:param name="resourceCategory" value="${PLATFORM}"/>
+ </c:url>
+ <html:link href="${platformUrl}">
+ <fmt:message key="resource.hub.filter.platform"/>
+ ( <c:out value="${ResourceSummary.platformCount}"/> )
+ </html:link>
+ |
+
+ <c:url var="serverUrl" value="/ResourceHub.do">
+ <c:param name="resourceCategory" value="${SERVER}"/>
+ </c:url>
+ <html:link href="${serverUrl}">
+ <fmt:message key="resource.hub.filter.server"/>
+ ( <c:out value="${ResourceSummary.serverCount}"/> )
+ </html:link>
+ |
+
+ <c:url var="serviceUrl" value="/ResourceHub.do">
+ <c:param name="resourceCategory" value="${SERVICE}"/>
+ </c:url>
+ <html:link href="${serviceUrl}">
+ <fmt:message key="resource.hub.filter.service"/>
+ ( <c:out value="${ResourceSummary.serviceCount}"/> )
+ </html:link>
+ |
+
+ <c:choose>
+ <c:when test="${GroupHubForm.groupCategory == COMPAT_GROUP}">
+ <fmt:message key="resource.hub.filter.compatibleGroups"/>
+ ( <c:out value="${ResourceSummary.compatibleGroupCount}"/> )
+ </c:when>
+ <c:otherwise>
+ <c:url var="groupUrl" value="/GroupHub.do">
+ <c:param name="groupCategory" value="${COMPAT_GROUP}"/>
+ </c:url>
+ <html:link href="${groupUrl}">
+ <fmt:message key="resource.hub.filter.compatibleGroups"/>
+ ( <c:out value="${ResourceSummary.compatibleGroupCount}"/> )
+ </html:link>
+ </c:otherwise>
+ </c:choose>
+ |
+ <c:choose>
+ <c:when test="${GroupHubForm.groupCategory == MIXED_GROUP}">
+ <fmt:message key="resource.hub.filter.mixedGroups"/>
+ ( <c:out value="${ResourceSummary.mixedGroupCount}"/> )
+ </c:when>
+ <c:otherwise>
+ <c:url var="groupUrl" value="/GroupHub.do">
+ <c:param name="groupCategory" value="${MIXED_GROUP}"/>
+ </c:url>
+ <html:link href="${groupUrl}">
+ <fmt:message key="resource.hub.filter.mixedGroups"/>
+ ( <c:out value="${ResourceSummary.mixedGroupCount}"/> )
+ </html:link>
+ </c:otherwise>
+ </c:choose>
+ |
+ <html:link href="/rhq/definition/group/list.xhtml">
+ <fmt:message key="resource.hub.filter.groupDefinitions"/>
+ ( <c:out value="${ResourceSummary.groupDefinitionCount}"/> )
+ </html:link>
+ </td>
+ </tr>
+ </table>
+ </c:if>
+
+ <fmt:message var="pluginTH" key="resource.hub.PluginTH"/>
+
+ <tiles:insert definition=".portlet.confirm"/>
+ <tiles:insert definition=".portlet.error"/>
+
+ <!-- FILTER TOOLBAR CONTENTS -->
+
+ <c:url var="resourceTypeAction" value="/GroupHub.do">
+ <c:if test="${not empty param.keywords}">
+ <c:param name="keywords" value="${param.keywords}"/>
+ </c:if>
+ <c:if test="${not empty param.ps}">
+ <c:param name="ps" value="${param.ps}"/>
+ </c:if>
+ <c:if test="${not empty param.so}">
+ <c:param name="so" value="${param.so}"/>
+ </c:if>
+ <c:if test="${not empty param.sc}">
+ <c:param name="sc" value="${param.sc}"/>
+ </c:if>
+ <c:if test="${not empty param.plugin}">
+ <c:param name="plugin" value="${param.plugin}"/>
+ </c:if>
+ <c:param name="groupCategory" value="${GroupHubForm.groupCategory}"/>
+ </c:url>
+ <c:url var="pluginAction" value="/GroupHub.do">
+ <c:if test="${not empty param.keywords}">
+ <c:param name="keywords" value="${param.keywords}"/>
+ </c:if>
+ <c:if test="${not empty param.ps}">
+ <c:param name="ps" value="${param.ps}"/>
+ </c:if>
+ <c:if test="${not empty param.so}">
+ <c:param name="so" value="${param.so}"/>
+ </c:if>
+ <c:if test="${not empty param.sc}">
+ <c:param name="sc" value="${param.sc}"/>
+ </c:if>
+ <c:if test="${not empty param.resourceType}">
+ <c:param name="resourceType" value="${param.resourceType}"/>
+ </c:if>
+ <c:param name="groupCategory" value="${GroupHubForm.groupCategory}"/>
+ </c:url>
+
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td class="FilterLine" colspan="3">
+ <html:img page="/images/spacer.gif" width="1" height="1" border="0"/>
+ </td>
+ </tr>
+ <tr>
+ <td class="FilterLabelText" nowrap="nowrap" align="right">
+ <c:choose>
+ <c:when test="${GroupHubForm.types == null}">
+ <html:hidden property="resourceType" value=""/>
+
+ </c:when>
+ <c:otherwise>
+ <fmt:message key="Filter.ViewLabel"/>
+ </td>
+ <td class="FilterLabelText">
+ <html:select property="resourceType" styleClass="FilterFormText" size="1"
+ onchange="goToSelectLocation(this, 'resourceType', '${resourceTypeAction}');">
+ <html:optionsCollection property="types"/>
+ </html:select>
+ </c:otherwise>
+ </c:choose>
+ </td>
+ <td class="FilterLabelText" width="100%">
+ <c:choose>
+ <c:when test="${GroupHubForm.plugins == null}">
+ <html:hidden property="plugin" value=""/>
+
+ </c:when>
+ <c:otherwise>
+ <html:select property="plugin" styleClass="FilterFormText" size="1"
+ onchange="goToSelectLocation(this, 'plugin', '${pluginAction}');">
+ <html:optionsCollection property="plugins"/>
+ </html:select>
+ </c:otherwise>
+ </c:choose>
+ </td>
+
+ <c:url var="viewAction" value="/GroupHub.do">
+ <c:if test="${not empty param.keywords}">
+ <c:param name="keywords" value="${param.keywords}"/>
+ </c:if>
+ <c:if test="${not empty param.pn}">
+ <c:param name="pn" value="${param.pn}"/>
+ </c:if>
+ <c:if test="${not empty param.so}">
+ <c:param name="so" value="${param.so}"/>
+ </c:if>
+ <c:if test="${not empty param.sc}">
+ <c:param name="sc" value="${param.sc}"/>
+ </c:if>
+ <c:if test="${not empty param.resourceType}">
+ <c:param name="resourceType" value="${param.resourceType}"/>
+ </c:if>
+ <c:if test="${not empty param.plugin}">
+ <c:param name="plugin" value="${param.plugin}"/>
+ </c:if>
+
+ <c:param name="groupCategory" value="${GroupHubForm.groupCategory}"/>
+ </c:url>
+
+ </tr>
+ </table>
+ <!-- / -->
+
+ <!-- GROUP HUB CONTENTS -->
+ <c:url var="sAction" value="/GroupHub.do">
+ <c:if test="${not empty param.keywords}">
+ <c:param name="keywords" value="${param.keywords}"/>
+ </c:if>
+ <c:if test="${not empty param.ps}">
+ <c:param name="ps" value="${param.ps}"/>
+ </c:if>
+ <c:if test="${not empty param.pn}">
+ <c:param name="pn" value="${param.pn}"/>
+ </c:if>
+ <c:if test="${not empty param.so}">
+ <c:param name="so" value="${param.so}"/>
+ </c:if>
+ <c:if test="${not empty param.sc}">
+ <c:param name="sc" value="${param.sc}"/>
+ </c:if>
+ <c:if test="${not empty param.resourceType}">
+ <c:param name="resourceType" value="${param.resourceType}"/>
+ </c:if>
+ <c:if test="${not empty param.plugin}">
+ <c:param name="plugin" value="${param.plugin}"/>
+ </c:if>
+ <c:param name="groupCategory" value="${GroupHubForm.groupCategory}"/>
+ </c:url>
+
+
+ <display:table items="${AllResources}" var="groupComposite" action="${sAction}"
+ width="100%" cellspacing="0" cellpadding="0" styleId="resourceHub">
+
+ <display:column width="1%" property="resourceGroup.id"
+ title="<input type=\"checkbox\" onclick=\"ToggleAll(this, widgetProperties)\" name=\"listToggleAll\">"
+ isLocalizedTitle="false" styleClass="ListCellCheckbox" headerStyleClass="ListHeaderCheckbox">
+ <display:checkboxdecorator name="resources" onclick="ToggleSelection(this, widgetProperties)" styleClass="listMember"/>
+ </display:column>
+
+ <display:column width="5%" value="${groupComposite}" title="nbsp" nowrap="true">
+ <display:group-quicknav-decorator/>
+ </display:column>
+
+ <c:choose>
+ <c:when test="${GroupHubForm.groupCategory == 'COMPATIBLE'}">
+ <display:column width="25%" property="resourceGroup.name" title="common.header.Group"
+ isLocalizedTitle="true" sortAttr="groupName"
+ href="/rhq/group/monitor/graphs.xhtml?category=${GroupHubForm.groupCategory}&groupId=${groupComposite.resourceGroup.id}"/>
+ </c:when>
+ <c:otherwise>
+ <display:column width="25%" property="resourceGroup.name" title="common.header.Group"
+ isLocalizedTitle="true" sortAttr="groupName"
+ href="/rhq/group/inventory/view.xhtml?category=${GroupHubForm.groupCategory}&groupId=${groupComposite.resourceGroup.id}"/>
+ </c:otherwise>
+ </c:choose>
+ <c:if test="${not empty resourceTypeTH}">
+ <display:column width="15%" property="resourceGroup.resourceType.name" title="${resourceTypeTH}"
+ isLocalizedTitle="false" sortAttr="resourceTypeName" />
+ <display:column width="10%" property="resourceGroup.resourceType.plugin" title="${pluginTH}"
+ isLocalizedTitle="false" sortAttr="res.resourceType.plugin" />
+ </c:if>
+
+ <display:column width="30%" property="resourceGroup.description"
+ title="common.header.Description" sortAttr="groupDescription"/>
+
+ <display:column width="10%" property="explicitFormatted" title="resource.common.monitor.visibility.ChildAvailabilityTH"
+ headerStyleClass="ListHeaderCheckbox" valign="middle"
+ sortAttr="explicitAvail"/>
+
+ <display:column width="10%" property="implicitFormatted" title="resource.common.monitor.visibility.DescendentAvailabilityTH"
+ headerStyleClass="ListHeaderCheckbox" valign="middle"
+ sortAttr="implicitAvail"/>
+
+ </display:table>
+ <!-- / -->
+
+ <c:url var="pageAction" value="/GroupHub.do">
+ <c:if test="${not empty param.keywords}">
+ <c:param name="keywords" value="${param.keywords}"/>
+ </c:if>
+ <c:if test="${not empty param.resourceType}">
+ <c:param name="resourceType" value="${param.resourceType}"/>
+ </c:if>
+ <c:if test="${not empty param.plugin}">
+ <c:param name="plugin" value="${param.plugin}"/>
+ </c:if>
+
+ <c:param name="groupCategory" value="${GroupHubForm.groupCategory}"/>
+
+ <c:if test="${not empty param.so}">
+ <c:param name="so" value="${param.so}"/>
+ </c:if>
+ <c:if test="${not empty param.sc}">
+ <c:param name="sc" value="${param.sc}"/>
+ </c:if>
+
+ <c:if test="${not empty param.pn}">
+ <c:param name="pn" value="${param.pn}"/>
+ </c:if>
+ <c:if test="${not empty param.ps}">
+ <c:param name="ps" value="${param.ps}"/>
+ </c:if>
+ </c:url>
+
+ <%-- I am a bit weary of this as the listNewUrl won't work in RHQ. --%>
+ <tiles:insert definition=".toolbar.list">
+ <tiles:put name="listNewUrl" value="/resource/platform/Inventory.do?mode=new"/>
+ <tiles:put name="deleteOnly" value="true"/>
+ <tiles:put name="pageList" beanName="AllResources"/>
+ <tiles:put name="widgetInstanceName" beanName="widgetInstanceName"/>
+ <tiles:put name="pageAction" beanName="pageAction"/>
+ </tiles:insert>
+
+ <html:hidden property="view"/>
+ <html:hidden property="groupCategory"/>
+
+ </html:form>
+ <tiles:insert definition=".page.footer"/>
+
+ <script type="text/javascript">
+ clearIfAnyChecked();
+ </script>
14 years, 3 months