modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
| 14
modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
| 51 +
modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleDeployDefinition.java
| 16
modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleDeployment.java
| 19
modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleGroupDeployment.java
| 291 ++++++++++
modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleGroupDeploymentStatus.java
| 47 +
modules/core/domain/src/main/java/org/rhq/core/domain/resource/group/ResourceGroup.java
| 14
modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_bundleManager.js
| 47 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerBean.java
| 63 +-
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerLocal.java
| 15
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/bundle/BundleManagerRemote.java
| 20
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
| 8
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/bundle/BundleManagerBeanTest.java
| 8
13 files changed, 598 insertions(+), 15 deletions(-)
New commits:
commit a4843f881ec94bdfe97a44f6284d6b12b0bb2b01
Merge: 3b74570... aac77c4...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri Mar 26 09:27:00 2010 -0400
Merge branch 'gwt' into gwt-jay
commit aac77c4667585187cb1b24b769a36f628ec8cd1d
Merge: c319887... 7afbfa9...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri Mar 26 09:26:26 2010 -0400
Merge branch 'gwt' of
ssh://git.fedorahosted.org/git/rhq/rhq into gwt
commit 3b745709e4be143524270f8f9825ab134228e4f6
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri Mar 26 09:25:42 2010 -0400
Initial support for bundle group deployment. Needs more work around group
status tracking and possibly fault tolerance.
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
b/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
index 309c3cb..f3bdf49 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
@@ -570,6 +570,17 @@
</index>
</table>
+ <table name="RHQ_BUNDLE_GROUP_DEPLOY">
+ <column name="ID" type="INTEGER" required="true"
default="sequence-only" initial="10001"
primarykey="true"/>
+ <column name="GROUP_ID" type="INTEGER"
required="true" references="RHQ_RESOURCE_GROUP"/>
+ <column name="BUNDLE_DEPLOY_DEF_ID" type="INTEGER"
required="true" references="RHQ_BUNDLE_DEPLOY_DEF" />
+ <column name="STATUS" type="VARCHAR2"
required="true" size="16"/>
+ <column name="ERROR_MESSAGE" type="LONGVARCHAR"
required="false"/>
+ <column name="SUBJECT_NAME" type="VARCHAR2"
required="true" size="255"/>
+ <column name="CTIME" type="LONG"
required="true"/>
+ <column name="MTIME" type="LONG"
required="true"/>
+ </table>
+
<!-- Represents a bundle version that is deployed on a platform resource -->
<table name="RHQ_BUNDLE_DEPLOY">
<column name="ID" default="sequence-only"
initial="10001" primarykey="true" required="true"
type="INTEGER"/>
@@ -584,17 +595,6 @@
</index>
</table>
- <table name="RHQ_BUNDLE_GROUP_DEPLOY">
- <column name="ID" type="INTEGER" required="true"
default="sequence-only" initial="10001"
primarykey="true"/>
- <column name="GROUP_ID" type="INTEGER"
required="true" references="RHQ_RESOURCE_GROUP"/>
- <column name="BUNDLE_DEPLOY_DEF_ID" type="INTEGER"
required="true" references="RHQ_BUNDLE_DEPLOY_DEF" />
- <column name="STATUS" type="VARCHAR2"
required="true" size="16"/>
- <column name="ERROR_MESSAGE" type="LONGVARCHAR"
required="false"/>
- <column name="SUBJECT_NAME" type="VARCHAR2"
required="true" size="255"/>
- <column name="CTIME" type="LONG"
required="true"/>
- <column name="MTIME" type="LONG"
required="true"/>
- </table>
-
<table name="RHQ_BUNDLE_DEPLOY_HIST">
<column name="ID" default="sequence-only"
initial="10001" primarykey="true" required="true"
type="INTEGER"/>
<column name="BUNDLE_DEPLOY_ID" type="INTEGER"
required="true" references="RHQ_BUNDLE_DEPLOY" />
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 5c11287..8f642ea 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
@@ -103,6 +103,9 @@ public class BundleDeployDefinition implements Serializable {
@OneToMany(mappedBy = "bundleDeployDefinition", fetch = FetchType.LAZY,
cascade = CascadeType.ALL)
private List<BundleDeployment> deployments = new
ArrayList<BundleDeployment>();
+ @OneToMany(mappedBy = "bundleDeployDefinition", fetch = FetchType.LAZY,
cascade = CascadeType.ALL)
+ private List<BundleGroupDeployment> groupDeployments = new
ArrayList<BundleGroupDeployment>();
+
public BundleDeployDefinition() {
// for JPA use
}
@@ -212,6 +215,19 @@ public class BundleDeployDefinition implements Serializable {
this.deployments = deployments;
}
+ public List<BundleGroupDeployment> getGroupDeployments() {
+ return groupDeployments;
+ }
+
+ public void addGroupDeployment(BundleGroupDeployment bundleGroupDeployment) {
+ this.groupDeployments.add(bundleGroupDeployment);
+ bundleGroupDeployment.setBundleDeployDefinition(this);
+ }
+
+ public void setGroupDeployments(List<BundleGroupDeployment> groupDeployments)
{
+ this.groupDeployments = groupDeployments;
+ }
+
@Override
public String toString() {
return "BundleDeployDefinition[id=" + id + ", name=" + name +
"]";
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleGroupDeployment.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleGroupDeployment.java
index 8f27723..8a0365f 100644
---
a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleGroupDeployment.java
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleGroupDeployment.java
@@ -26,7 +26,6 @@ import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
-import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
@@ -58,11 +57,11 @@ public class BundleGroupDeployment implements Serializable {
private int id;
@JoinColumn(name = "GROUP_ID", referencedColumnName = "ID")
- @ManyToOne(cascade = { CascadeType.REMOVE })
+ @ManyToOne
private ResourceGroup group;
@JoinColumn(name = "BUNDLE_DEPLOY_DEF_ID", referencedColumnName =
"ID", nullable = false)
- @ManyToOne(cascade = { CascadeType.REMOVE }, fetch = FetchType.LAZY)
+ @ManyToOne
protected BundleDeployDefinition bundleDeployDefinition;
@Column(name = "STATUS", nullable = false)
@@ -81,7 +80,7 @@ public class BundleGroupDeployment implements Serializable {
@Column(name = "MTIME", nullable = false)
protected long modifiedTime = System.currentTimeMillis();
- @OneToMany(mappedBy = "bundleGroupDeployment", fetch = FetchType.LAZY,
cascade = { CascadeType.ALL })
+ @OneToMany(mappedBy = "bundleGroupDeployment", fetch = FetchType.LAZY)
private List<BundleDeployment> bundleDeployments = new
ArrayList<BundleDeployment>();
// For JPA
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/group/ResourceGroup.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/group/ResourceGroup.java
index 9eae8e6..3c8c5c5 100644
---
a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/group/ResourceGroup.java
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/group/ResourceGroup.java
@@ -404,10 +404,10 @@ public class ResourceGroup extends Group {
// by primary key which will also put the configuration updates in chronological
order
private List<AbstractGroupConfigurationUpdate> configurationUpdates = new
ArrayList<AbstractGroupConfigurationUpdate>();
- @OneToMany(mappedBy = "group", cascade = { CascadeType.ALL })
+ @OneToMany(mappedBy = "group", cascade = { CascadeType.REMOVE })
@OrderBy
- // by primary key which will also put the operation histories in chronological order
- private List<BundleGroupDeployment> bundleDeployments = new
ArrayList<BundleGroupDeployment>();
+ // by primary key which will also put the bundle deployments in chronological order
+ private List<BundleGroupDeployment> bundleGroupDeployments = new
ArrayList<BundleGroupDeployment>();
@JoinColumn(name = "GROUP_DEFINITION_ID", referencedColumnName =
"ID", nullable = true)
@ManyToOne
@@ -554,12 +554,12 @@ public class ResourceGroup extends Group {
this.configurationUpdates = configurationUpdates;
}
- public List<BundleGroupDeployment> getBundleDeployments() {
- return bundleDeployments;
+ public List<BundleGroupDeployment> getBundleGroupDeployments() {
+ return bundleGroupDeployments;
}
- public void setBundleDeployments(List<BundleGroupDeployment> bundleDeployments)
{
- this.bundleDeployments = bundleDeployments;
+ public void setBundleGroupDeployments(List<BundleGroupDeployment>
bundleGroupDeployments) {
+ this.bundleGroupDeployments = bundleGroupDeployments;
}
public GroupDefinition getGroupDefinition() {
diff --git
a/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_bundleManager.js
b/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_bundleManager.js
index 76e3f74..34986f1 100644
---
a/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_bundleManager.js
+++
b/modules/enterprise/remoting/scripts/src/test/script/org/rhq/enterprise/remoting/cli/test_bundleManager.js
@@ -26,7 +26,7 @@
* said platform.
*/
-var TestsEnabled = true;
+var TestsEnabled = false;
var bundleName = 'testScriptBundle';
@@ -82,6 +82,51 @@ function testDeployment() {
cleanupTestBundle();
}
+function testGroupDeployment() {
+// if ( !TestsEnabled ) {
+// return;
+// }
+
+ // delete the test bundle if it exists
+ cleanupTestBundle();
+
+ // create the test bundle
+ var testBundle = BundleManager.createBundle( bundleName, bundleName, getBundleType()
);
+
+ // define the recipe for bundleVersion 1.0
+ var recipe = "file -s testBundle.war -d
<%bundleTest.deployHome%>/group/testBundle.war"
+
+ // create bundleVersion 1.0
+ var testBundleVersion = BundleManager.createBundleVersion( testBundle.getId(),
bundleName, bundleName, null, recipe);
+
+ // add the single bundleFile, the test war file
+ var fileBytes =
scriptUtil.getFileBytes("./src/test/resources/testBundle.war");
+ var bundleFile = BundleManager.addBundleFileViaByteArray(testBundleVersion.getId(),
"testBundle.war",
+ "1.0", null, fileBytes, false);
+
+ // create the config, setting the required properties from the recipe
+ var config = new Configuration();
+ var property = new PropertySimple("bundleTest.deployHome",
"/tmp/bundle-test");
+ config.put( property );
+
+ // create a deploy def using the above config
+ var testDeployDef =
BundleManager.createBundleDeployDefinition(testBundleVersion.getId(), "Deployment
Test", "Deployment Test of testBundle WAR", config, false, -1, false);
+
+ // Find a target platform group
+ var rgc = new ResourceGroupCriteria();
+ rgc.addFilterName("platforms"); // wINdows, lINux
+ var groups = ResourceGroupManager.findResourceGroupsByCriteria(rgc);
+ Assert.assertTrue( groups.size() > 0 );
+ var groupId = groups.get(0).getId();
+
+ var bgd = BundleManager.scheduleBundleGroupDeployment(testDeployDef.getId(),
groupId);
+ Assert.assertNotNull( bgd );
+
+ // delete the test bundle if it exists (after allowing agent audit messages to
complete)
+ sleep( 5000 );
+ cleanupTestBundle();
+}
+
function getBundleType() {
var types = BundleManager.getAllBundleTypes();
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 fe4cca4..8d19ad2 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
@@ -458,7 +458,7 @@ public class BundleManagerBean implements BundleManagerLocal,
BundleManagerRemot
// The BundleDeployment record must exist in the db before the agent request
because the agent may try to
// add History to it during immediate deployments., so create and persist it
(requires a new trans).
BundleDeployment deployment = bundleManager.createBundleDeployment(subject,
deployDef.getId(), resourceId,
- bundleGroupDeployment.getId());
+ (null == bundleGroupDeployment) ? 0 : bundleGroupDeployment.getId());
// make sure the deployment contains the info required by the schedule service
BundleVersion bundleVersion = entityManager.find(BundleVersion.class,
deployDef.getBundleVersion().getId());
@@ -516,10 +516,8 @@ public class BundleManagerBean implements BundleManagerLocal,
BundleManagerRemot
}
/*
- * we need to create and persist the group deployment entity in a new transaction
before the rest of the
- * processing of this method; if we try to create and attach the deployment
children
- * to the parent before this is persisted we'll get StaleStateExceptions
- * from Hibernate because of our use of flush/clear (we're trying to update
it before it actually exists)
+ * we need to create the group deployment entity in a new transaction before the
rest of the
+ * processing of this method; the individual deployments need to reference it.
*/
BundleGroupDeployment bundleGroupDeployment = new
BundleGroupDeployment(subject.getName(), deployDef,
resourceGroup);
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 c975d38..163e9c6 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
@@ -40,6 +40,7 @@ import org.rhq.core.domain.bundle.BundleDeployDefinition;
import org.rhq.core.domain.bundle.BundleDeployment;
import org.rhq.core.domain.bundle.BundleDeploymentHistory;
import org.rhq.core.domain.bundle.BundleFile;
+import org.rhq.core.domain.bundle.BundleGroupDeployment;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.bundle.composite.BundleWithLatestVersionComposite;
@@ -152,6 +153,13 @@ public class BundleManagerBeanTest extends UpdateSubsytemTestBase {
for (Object removeMe : doomed) {
em.remove(em.getReference(BundleFile.class, ((BundleFile)
removeMe).getId()));
}
+ // remove any orphaned bgds
+ q = em.createQuery("SELECT bgd FROM BundleGroupDeployment bgd WHERE
bgd.bundleDeployDefinition.name LIKE '"
+ + TEST_PREFIX + "%'");
+ doomed = q.getResultList();
+ for (Object removeMe : doomed) {
+ em.remove(em.getReference(BundleGroupDeployment.class,
((BundleGroupDeployment) removeMe).getId()));
+ }
// remove any orphaned bds
q = em.createQuery("SELECT bd FROM BundleDeployment bd WHERE
bd.bundleDeployDefinition.name LIKE '"
+ TEST_PREFIX + "%'");
commit 7ef0eb7296676fd02a713d327b16413f8be9cb3f
Merge: b58b413... c319887...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Mar 24 16:30:37 2010 -0400
Merge branch 'gwt' into gwt-jay
commit c3198879d399d8edbb9e6a8879d84855d7c35780
Merge: d3e8405... 99ac8e8...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Mar 24 16:30:08 2010 -0400
Merge branch 'gwt' of
ssh://git.fedorahosted.org/git/rhq/rhq into gwt
commit b58b413fbaa08657c3df2127e085aa3ee0f438f2
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Mar 24 16:29:30 2010 -0400
Work on infra for bundle group deploy
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
b/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
index 178013b..309c3cb 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
@@ -576,8 +576,7 @@
<column name="BUNDLE_DEPLOY_DEF_ID" type="INTEGER"
required="true" references="RHQ_BUNDLE_DEPLOY_DEF" />
<column name="RESOURCE_ID" type="INTEGER"
required="true" references="RHQ_RESOURCE" />
<column name="CTIME" type="LONG"
required="true"/>
- <!-- for group history -->
- <column name="GROUP_ID" type="INTEGER"
required="false" references="RHQ_RESOURCE_GROUP"/>
+ <column name="BUNDLE_GROUP_DEPLOY_ID" type="INTEGER"
required="false" references="RHQ_BUNDLE_GROUP_DEPLOY"/>
<index name="RHQ_DEPLOY_DEF_RESOURCE_IDX"
unique="true">
<field ref="BUNDLE_DEPLOY_DEF_ID"/>
@@ -585,6 +584,17 @@
</index>
</table>
+ <table name="RHQ_BUNDLE_GROUP_DEPLOY">
+ <column name="ID" type="INTEGER" required="true"
default="sequence-only" initial="10001"
primarykey="true"/>
+ <column name="GROUP_ID" type="INTEGER"
required="true" references="RHQ_RESOURCE_GROUP"/>
+ <column name="BUNDLE_DEPLOY_DEF_ID" type="INTEGER"
required="true" references="RHQ_BUNDLE_DEPLOY_DEF" />
+ <column name="STATUS" type="VARCHAR2"
required="true" size="16"/>
+ <column name="ERROR_MESSAGE" type="LONGVARCHAR"
required="false"/>
+ <column name="SUBJECT_NAME" type="VARCHAR2"
required="true" size="255"/>
+ <column name="CTIME" type="LONG"
required="true"/>
+ <column name="MTIME" type="LONG"
required="true"/>
+ </table>
+
<table name="RHQ_BUNDLE_DEPLOY_HIST">
<column name="ID" default="sequence-only"
initial="10001" primarykey="true" required="true"
type="INTEGER"/>
<column name="BUNDLE_DEPLOY_ID" type="INTEGER"
required="true" references="RHQ_BUNDLE_DEPLOY" />
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 da47976..18db292 100644
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@ -2819,7 +2819,7 @@
<!-- RHQ_BUNDLE_DEPLOY_HIST -->
<schema-directSQL>
<statement desc="Creating table
RHQ_BUNDLE_DEPLOY_HIST">
- CREATE TABLE RHQ_BUNDLE_DEPLOY_HIST ( ID INTEGER )
+ CREATE TABLE RHQ_BUNDLE_DEPLOY_HIST ( ID INTEGER PRIMARY KEY )
</statement>
</schema-directSQL>
<schema-alterColumn table="RHQ_BUNDLE_DEPLOY_HIST"
column="ID" nullable="FALSE" />
@@ -2899,7 +2899,50 @@
</schemaSpec>
<schemaSpec version="2.78.5">
- <schema-addColumn table="RHQ_BUNDLE_DEPLOY"
column="RESOURCE_GROUP_ID" columnType="INTEGER" />
+ <!-- RHQ_BUNDLE_GROUP_DEPLOY -->
+ <schema-directSQL>
+ <statement desc="Creating table
RHQ_BUNDLE_GROUP_DEPLOY">
+ CREATE TABLE RHQ_BUNDLE_GROUP_DEPLOY ( ID INTEGER PRIMARY KEY )
+ </statement>
+ </schema-directSQL>
+ <schema-alterColumn table="RHQ_BUNDLE_GROUP_DEPLOY"
column="ID" nullable="FALSE" />
+ <schema-addColumn table="RHQ_BUNDLE_GROUP_DEPLOY"
column="GROUP_ID" columnType="INTEGER" />
+ <schema-alterColumn table="RHQ_BUNDLE_GROUP_DEPLOY"
column="GROUP_ID" nullable="FALSE" />
+ <schema-addColumn table="RHQ_BUNDLE_GROUP_DEPLOY"
column="BUNDLE_DEPLOY_DEF_ID" columnType="INTEGER" />
+ <schema-alterColumn table="RHQ_BUNDLE_GROUP_DEPLOY"
column="BUNDLE_DEPLOY_DEF_ID" nullable="FALSE" />
+ <schema-addColumn table="RHQ_BUNDLE_GROUP_DEPLOY"
column="STATUS" columnType="VARCHAR2" precision="16" />
+ <schema-alterColumn table="RHQ_BUNDLE_GROUP_DEPLOY"
column="STATUS" nullable="FALSE" />
+ <schema-addColumn table="RHQ_BUNDLE_GROUP_DEPLOY"
column="ERROR_MESSAGE" columnType="LONGVARCHAR" />
+ <schema-addColumn table="RHQ_BUNDLE_GROUP_DEPLOY"
column="SUBJECT_NAME" columnType="VARCHAR2" precision="255"
/>
+ <schema-alterColumn table="RHQ_BUNDLE_GROUP_DEPLOY"
column="SUBJECT_NAME" nullable="FALSE" />
+ <schema-addColumn table="RHQ_BUNDLE_GROUP_DEPLOY"
column="CTIME" columnType="LONG" />
+ <schema-alterColumn table="RHQ_BUNDLE_GROUP_DEPLOY"
column="CTIME" nullable="FALSE" />
+ <schema-addColumn table="RHQ_BUNDLE_GROUP_DEPLOY"
column="MTIME" columnType="LONG" />
+ <schema-alterColumn table="RHQ_BUNDLE_GROUP_DEPLOY"
column="MTIME" nullable="FALSE" />
+ <schema-directSQL>
+ <statement desc="Creating RHQ_BUNDLE_GROUP_DEPLOY foreign key
relation to RHQ_RESOURCE_GROUP">
+ ALTER TABLE RHQ_BUNDLE_GROUP_DEPLOY
+ ADD CONSTRAINT RHQ_RESOURCE_GROUP_FK
+ FOREIGN KEY (GROUP_ID)
+ REFERENCES RHQ_RESOURCE_GROUP (ID)
+ </statement>
+ <statement desc="Creating RHQ_BUNDLE_GROUP_DEPLOY foreign key
relation to RHQ_BUNDLE_DEPLOY_DEF">
+ ALTER TABLE RHQ_BUNDLE_GROUP_DEPLOY
+ ADD CONSTRAINT RHQ_BUNDLE_DEPLOY_DEF_FK
+ FOREIGN KEY (BUNDLE_DEPLOY_DEF_ID)
+ REFERENCES RHQ_BUNDLE_DEPLOY_DEF (ID)
+ </statement>
+ </schema-directSQL>
+
+ <schema-addColumn table="RHQ_BUNDLE_DEPLOY"
column="BUNDLE_GROUP_DEPLOY_ID" columnType="INTEGER" />
+ <schema-directSQL>
+ <statement desc="Creating RHQ_BUNDLE_DEPLOY foreign key
relation to RHQ_BUNDLE_GROUP_DEPLOY">
+ ALTER TABLE RHQ_BUNDLE_DEPLOY
+ ADD CONSTRAINT RHQ_BUNDLE_GROUP_DEPLOY_FK
+ FOREIGN KEY (BUNDLE_GROUP_DEPLOY_ID)
+ REFERENCES RHQ_BUNDLE_GROUP_DEPLOY (ID)
+ </statement>
+ </schema-directSQL>
</schemaSpec>
<schemaSpec version="2.79">
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 45389af..4bb964d 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
@@ -80,6 +80,10 @@ public class BundleDeployment implements Serializable {
@ManyToOne(fetch = FetchType.LAZY)
private Resource resource;
+ @JoinColumn(name = "BUNDLE_GROUP_DEPLOY_ID", referencedColumnName =
"ID", nullable = true)
+ @ManyToOne
+ private BundleGroupDeployment bundleGroupDeployment;
+
@Column(name = "CTIME")
private Long ctime = -1L;
@@ -94,6 +98,13 @@ public class BundleDeployment implements Serializable {
this.resource = resource;
}
+ public BundleDeployment(BundleDeployDefinition bundleDeploymentDef, Resource
resource,
+ BundleGroupDeployment bundleGroupDeployment) {
+ this.bundleDeployDefinition = bundleDeploymentDef;
+ this.resource = resource;
+ this.bundleGroupDeployment = bundleGroupDeployment;
+ }
+
public BundleDeployDefinition getBundleDeployDefinition() {
return bundleDeployDefinition;
}
@@ -140,6 +151,14 @@ public class BundleDeployment implements Serializable {
this.histories.add(history);
}
+ public BundleGroupDeployment getBundleGroupDeployment() {
+ return bundleGroupDeployment;
+ }
+
+ public void setBundleGroupDeployment(BundleGroupDeployment bundleGroupDeployment) {
+ this.bundleGroupDeployment = bundleGroupDeployment;
+ }
+
@Override
public String toString() {
StringBuilder str = new StringBuilder("BundleDeployment: ");
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleGroupDeployment.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleGroupDeployment.java
new file mode 100644
index 0000000..8f27723
--- /dev/null
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleGroupDeployment.java
@@ -0,0 +1,292 @@
+/*
+ * 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.domain.bundle;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.PrePersist;
+import javax.persistence.PreUpdate;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+
+import org.rhq.core.domain.configuration.ConfigurationUpdateStatus;
+import org.rhq.core.domain.resource.group.ResourceGroup;
+
+@Entity
+@SequenceGenerator(name = "SEQ", sequenceName =
"RHQ_BUNDLE_GROUP_DEPLOY_ID_SEQ")
+@Table(name = "RHQ_BUNDLE_GROUP_DEPLOY")
+public class BundleGroupDeployment implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @GeneratedValue(generator = "SEQ", strategy = GenerationType.AUTO)
+ @Id
+ private int id;
+
+ @JoinColumn(name = "GROUP_ID", referencedColumnName = "ID")
+ @ManyToOne(cascade = { CascadeType.REMOVE })
+ private ResourceGroup group;
+
+ @JoinColumn(name = "BUNDLE_DEPLOY_DEF_ID", referencedColumnName =
"ID", nullable = false)
+ @ManyToOne(cascade = { CascadeType.REMOVE }, fetch = FetchType.LAZY)
+ protected BundleDeployDefinition bundleDeployDefinition;
+
+ @Column(name = "STATUS", nullable = false)
+ @Enumerated(EnumType.STRING)
+ protected BundleGroupDeploymentStatus status;
+
+ @Column(name = "ERROR_MESSAGE")
+ protected String errorMessage;
+
+ @Column(name = "SUBJECT_NAME")
+ protected String subjectName;
+
+ @Column(name = "CTIME", nullable = false)
+ protected long createdTime = System.currentTimeMillis();
+
+ @Column(name = "MTIME", nullable = false)
+ protected long modifiedTime = System.currentTimeMillis();
+
+ @OneToMany(mappedBy = "bundleGroupDeployment", fetch = FetchType.LAZY,
cascade = { CascadeType.ALL })
+ private List<BundleDeployment> bundleDeployments = new
ArrayList<BundleDeployment>();
+
+ // For JPA
+ public BundleGroupDeployment() {
+ }
+
+ public BundleGroupDeployment(String subjectName, BundleDeployDefinition
bundleDeployDefinition, ResourceGroup group) {
+ this.subjectName = subjectName;
+ this.bundleDeployDefinition = bundleDeployDefinition;
+ this.group = group;
+ this.status = BundleGroupDeploymentStatus.INPROGRESS;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ /**
+ * The status of the request which indicates that the request is either still in
progress, or it has completed and
+ * either succeeded or failed.
+ *
+ * @return the request status
+ */
+ public BundleGroupDeploymentStatus getStatus() {
+ return status;
+ }
+
+ public void setStatus(BundleGroupDeploymentStatus status) {
+ this.status = status;
+ }
+
+ public ResourceGroup getGroup() {
+ return group;
+ }
+
+ public void setGroup(ResourceGroup group) {
+ this.group = group;
+ }
+
+ public BundleDeployDefinition getBundleDeployDefinition() {
+ return bundleDeployDefinition;
+ }
+
+ public void setBundleDeployDefinition(BundleDeployDefinition bundleDeployDefinition)
{
+ this.bundleDeployDefinition = bundleDeployDefinition;
+ }
+
+ /**
+ * If not <code>null</code>, this is an error message (possibly a full
stack trace) to indicate the overall error
+ * that occurred when the configuration update failed. This will normally be
<code>null</code> unless the
+ * {@link #getStatus() status} indicates a {@link
BundleGroupDeploymentStatus#FAILURE}.
+ *
+ * @return overall error that occurred
+ */
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ /**
+ * Calling this method with a non-<code>null</code> error message implies
that the request's status is
+ * {@link ConfigurationUpdateStatus#FAILURE}. The inverse is <i>not</i>
true - that is, if you set the error message
+ * to <code>null</code>, the status is left as-is; it will not assume
that a <code>null</code> error message means
+ * the status is successful.
+ *
+ * @param errorMessage
+ */
+ public void setErrorMessage(String errorMessage) {
+ this.errorMessage = errorMessage;
+
+ if (this.errorMessage != null) {
+ setStatus(BundleGroupDeploymentStatus.FAILURE);
+ }
+ }
+
+ /**
+ * For auditing purposes, this method tells you the username of the person that
created the request. This is not a
+ * relationship to an actual Subject because we want to maintain the audit trail,
even if a Subject has been deleted
+ * from the database.
+ *
+ * @return the actual name string of the submitter of the request
+ */
+ public String getSubjectName() {
+ return subjectName;
+ }
+
+ /**
+ * The time this entity was originally created; in other words, when the request was
originally made.
+ *
+ * @return creation time
+ */
+ public long getCreatedTime() {
+ return this.createdTime;
+ }
+
+ /**
+ * The time this entity was last modified. This is the last time the status was
updated. If the status has never
+ * been updated, this will be the {@link #getCreatedTime() created time}.
+ *
+ * @return last modified time
+ */
+ public long getModifiedTime() {
+ return this.modifiedTime;
+ }
+
+ public List<BundleDeployment> getBundleDeployments() {
+ return bundleDeployments;
+ }
+
+ public void setBundleDeployments(List<BundleDeployment> bundleDeployments) {
+ this.bundleDeployments = bundleDeployments;
+ }
+
+ public void addBundleDeployment(BundleDeployment bundleDeployment) {
+ bundleDeployment.setBundleGroupDeployment(this);
+ this.bundleDeployments.add(bundleDeployment);
+ }
+
+ /**
+ * The duration of the configuration update request which simply is the difference
between the
+ * {@link #getCreatedTime()} and the {@link #getModifiedTime()}. If the request
hasn't completed yet, this will be
+ * the difference between the current time and the created time.
+ *
+ * @return the duration of time that the request took or is taking to complete
+ */
+ public long getDuration() {
+ long start = this.createdTime;
+ long end;
+ if ((status == null) || (status == BundleGroupDeploymentStatus.INPROGRESS)) {
+ end = System.currentTimeMillis();
+ } else {
+ end = this.modifiedTime;
+ }
+
+ return end - start;
+ }
+
+ @Override
+ public int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ result = (PRIME * result) + (int) (createdTime ^ (createdTime >>> 32));
+ result = (PRIME * result) + ((subjectName == null) ? 0 :
subjectName.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if ((obj == null) || !(obj instanceof BundleGroupDeployment)) {
+ return false;
+ }
+
+ final BundleGroupDeployment other = (BundleGroupDeployment) obj;
+
+ if (this.createdTime != other.createdTime) {
+ return false;
+ }
+
+ if (this.subjectName == null) {
+ if (other.subjectName != null) {
+ return false;
+ }
+ } else if (!this.subjectName.equals(other.subjectName)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @PrePersist
+ void onPersist() {
+ // don't set createdTime - we use it in equals/hashCode - it is already set
at instantiation time
+ this.modifiedTime = System.currentTimeMillis();
+ }
+
+ @PreUpdate
+ void onUpdate() {
+ this.modifiedTime = System.currentTimeMillis();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder str = new StringBuilder("BundleGroupDeployment [");
+ str.append("id=").append(this.id);
+ str.append(", status=").append(this.status);
+ str.append(", resourceGroup=").append(this.group);
+ str.append(", deployDef=").append(this.getBundleDeployDefinition());
+ str.append(", subjectName=").append(this.subjectName);
+ str.append(", createdTime=").append(this.createdTime);
+ str.append(", modifiedTime=").append(this.modifiedTime);
+
+ String err = this.errorMessage;
+ if ((err != null) && (err.indexOf('\n') > -1)) {
+ err = err.substring(0, err.indexOf('\n')) + "...";
+ }
+ str.append(", errorMessage=").append(err);
+ str.append(']');
+
+ return str.toString();
+ }
+}
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleGroupDeploymentStatus.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleGroupDeploymentStatus.java
new file mode 100644
index 0000000..94f9113
--- /dev/null
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/BundleGroupDeploymentStatus.java
@@ -0,0 +1,47 @@
+/*
+ * 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.domain.bundle;
+
+/**
+ * Simple statuses for Bundle Group Deploy requests. When a request is first initiated,
it will be considered in the
+ * {@link #INPROGRESS} state. When the request has completed, it will have been either a
{@link #SUCCESS} or
+ * {@link #FAILURE}.
+ *
+ * @author Jay Shaughnessy
+ */
+public enum BundleGroupDeploymentStatus {
+ INPROGRESS("In Progress"), //
+ SUCCESS("Success"), //
+ FAILURE("Failure"), //
+ NOCHANGE("No Change");
+
+ private String displayName;
+
+ BundleGroupDeploymentStatus(String displayName) {
+ this.displayName = displayName;
+ }
+
+ public String toString() {
+ return displayName;
+ }
+}
\ No newline at end of file
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/GroupBundleDeployment.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/GroupBundleDeployment.java
deleted file mode 100644
index 67ad13f..0000000
---
a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/GroupBundleDeployment.java
+++ /dev/null
@@ -1,73 +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.domain.bundle;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.persistence.CascadeType;
-import javax.persistence.DiscriminatorValue;
-import javax.persistence.Entity;
-import javax.persistence.JoinColumn;
-import javax.persistence.ManyToOne;
-import javax.persistence.OneToMany;
-
-import org.rhq.core.domain.resource.group.ResourceGroup;
-
-@DiscriminatorValue("group")
-@Entity
-public class GroupBundleDeployment extends BundleDeployment {
-
- private static final long serialVersionUID = 1L;
-
- @JoinColumn(name = "GROUP_ID", referencedColumnName = "ID")
- @ManyToOne
- private ResourceGroup group;
-
- @OneToMany(mappedBy = "groupBundleHistory", cascade = {
CascadeType.PERSIST, CascadeType.REMOVE })
- private List<BundleDeployment> bundleDeployments = new
ArrayList<BundleDeployment>();
-
- protected GroupBundleDeployment() {
- }
-
- public ResourceGroup getGroup() {
- return group;
- }
-
- public void setGroup(ResourceGroup group) {
- this.group = group;
- }
-
- public List<BundleDeployment> getBundleDeployments() {
- return bundleDeployments;
- }
-
- public void setBundleDeployments(List<BundleDeployment> bundleDeployments) {
- this.bundleDeployments = bundleDeployments;
- }
-
- public void addBundleDeployments(BundleDeployment bundleDeployment) {
- this.bundleDeployments.add(bundleDeployment);
- }
-
-}
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/group/ResourceGroup.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/group/ResourceGroup.java
index 7a10422..9eae8e6 100644
---
a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/group/ResourceGroup.java
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/group/ResourceGroup.java
@@ -55,7 +55,7 @@ import org.jetbrains.annotations.NotNull;
import org.rhq.core.domain.alert.AlertDefinition;
import org.rhq.core.domain.authz.Role;
-import org.rhq.core.domain.bundle.GroupBundleDeployment;
+import org.rhq.core.domain.bundle.BundleGroupDeployment;
import org.rhq.core.domain.configuration.group.AbstractGroupConfigurationUpdate;
import org.rhq.core.domain.operation.GroupOperationHistory;
import org.rhq.core.domain.resource.Resource;
@@ -407,7 +407,7 @@ public class ResourceGroup extends Group {
@OneToMany(mappedBy = "group", cascade = { CascadeType.ALL })
@OrderBy
// by primary key which will also put the operation histories in chronological order
- private List<GroupBundleDeployment> bundleDeployments = new
ArrayList<GroupBundleDeployment>();
+ private List<BundleGroupDeployment> bundleDeployments = new
ArrayList<BundleGroupDeployment>();
@JoinColumn(name = "GROUP_DEFINITION_ID", referencedColumnName =
"ID", nullable = true)
@ManyToOne
@@ -554,11 +554,11 @@ public class ResourceGroup extends Group {
this.configurationUpdates = configurationUpdates;
}
- public List<GroupBundleDeployment> getBundleDeployments() {
+ public List<BundleGroupDeployment> getBundleDeployments() {
return bundleDeployments;
}
- public void setBundleDeployments(List<GroupBundleDeployment> bundleDeployments)
{
+ public void setBundleDeployments(List<BundleGroupDeployment> bundleDeployments)
{
this.bundleDeployments = bundleDeployments;
}
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 bab247a..8e6e479 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
@@ -50,6 +50,7 @@ import org.rhq.core.domain.bundle.BundleDeployment;
import org.rhq.core.domain.bundle.BundleDeploymentAction;
import org.rhq.core.domain.bundle.BundleDeploymentHistory;
import org.rhq.core.domain.bundle.BundleFile;
+import org.rhq.core.domain.bundle.BundleGroupDeployment;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.bundle.composite.BundleWithLatestVersionComposite;
@@ -67,6 +68,7 @@ import org.rhq.core.domain.criteria.BundleFileCriteria;
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.resource.group.ResourceGroup;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.util.NumberUtil;
import org.rhq.enterprise.server.RHQConstants;
@@ -431,25 +433,32 @@ public class BundleManagerBean implements BundleManagerLocal,
BundleManagerRemot
return (PackageType) packageTypeQuery.getSingleResult();
}
- @RequiredPermission(Permission.MANAGE_INVENTORY)
public BundleDeployment scheduleBundleDeployment(Subject subject, int
bundleDeployDefinitionId, int resourceId)
throws Exception {
-
BundleDeployDefinition deployDef =
entityManager.find(BundleDeployDefinition.class, bundleDeployDefinitionId);
if (null == deployDef) {
throw new IllegalArgumentException("Invalid bundleDeployDefinitionId:
" + bundleDeployDefinitionId);
}
+
Resource resource = (Resource) entityManager.find(Resource.class, resourceId);
if (null == resource) {
throw new IllegalArgumentException("Invalid resourceId (Resource does
not exist): " + resourceId);
}
+ return scheduleBundleDeployment(subject, deployDef, resource, null);
+ }
+
+ private BundleDeployment scheduleBundleDeployment(Subject subject,
BundleDeployDefinition deployDef,
+ Resource resource, BundleGroupDeployment bundleGroupDeployment) throws Exception
{
+
+ int resourceId = resource.getId();
AgentClient agentClient = agentManager.getAgentClient(resourceId);
BundleAgentService bundleAgentService = agentClient.getBundleAgentService();
// The BundleDeployment record must exist in the db before the agent request
because the agent may try to
// add History to it during immediate deployments., so create and persist it
(requires a new trans).
- BundleDeployment deployment = bundleManager.createBundleDeployment(subject,
deployDef.getId(), resourceId);
+ BundleDeployment deployment = bundleManager.createBundleDeployment(subject,
deployDef.getId(), resourceId,
+ bundleGroupDeployment.getId());
// make sure the deployment contains the info required by the schedule service
BundleVersion bundleVersion = entityManager.find(BundleVersion.class,
deployDef.getBundleVersion().getId());
@@ -492,10 +501,44 @@ public class BundleManagerBean implements BundleManagerLocal,
BundleManagerRemot
return deployment;
}
+ @RequiredPermission(Permission.MANAGE_INVENTORY)
+ public BundleGroupDeployment scheduleBundleGroupDeployment(Subject subject, int
bundleDeployDefinitionId,
+ int resourceGroupId) throws Exception {
+
+ BundleDeployDefinition deployDef =
entityManager.find(BundleDeployDefinition.class, bundleDeployDefinitionId);
+ if (null == deployDef) {
+ throw new IllegalArgumentException("Invalid bundleDeployDefinitionId:
" + bundleDeployDefinitionId);
+ }
+ ResourceGroup resourceGroup = (ResourceGroup)
entityManager.find(ResourceGroup.class, resourceGroupId);
+ if (null == resourceGroup) {
+ throw new IllegalArgumentException("Invalid resourceGroupId
(ResourceGroup does not exist): "
+ + resourceGroupId);
+ }
+
+ /*
+ * we need to create and persist the group deployment entity in a new transaction
before the rest of the
+ * processing of this method; if we try to create and attach the deployment
children
+ * to the parent before this is persisted we'll get StaleStateExceptions
+ * from Hibernate because of our use of flush/clear (we're trying to update
it before it actually exists)
+ */
+ BundleGroupDeployment bundleGroupDeployment = new
BundleGroupDeployment(subject.getName(), deployDef,
+ resourceGroup);
+ bundleGroupDeployment =
bundleManager.createBundleGroupDeployment(bundleGroupDeployment);
+
+ // Create and persist updates for each of the group members.
+ for (Resource resource : resourceGroup.getExplicitResources()) {
+ BundleDeployment bundleDeployment = scheduleBundleDeployment(subject,
deployDef, resource,
+ bundleGroupDeployment);
+ bundleGroupDeployment.addBundleDeployment(bundleDeployment);
+ }
+
+ return bundleGroupDeployment;
+ }
+
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
@RequiredPermission(Permission.MANAGE_INVENTORY)
- public BundleDeployment createBundleDeployment(Subject subject, int
bundleDeployDefinitionId, int resourceId)
- throws Exception {
+ public BundleDeployment createBundleDeployment(Subject subject, int
bundleDeployDefinitionId, int resourceId,
+ int bundleGroupDeploymentId) throws Exception {
BundleDeployDefinition deployDef =
entityManager.find(BundleDeployDefinition.class, bundleDeployDefinitionId);
if (null == deployDef) {
@@ -506,12 +549,22 @@ public class BundleManagerBean implements BundleManagerLocal,
BundleManagerRemot
throw new IllegalArgumentException("Invalid resourceId (Resource does
not exist): " + resourceId);
}
- BundleDeployment deployment = new BundleDeployment(deployDef, resource);
+ BundleGroupDeployment bundleGroupDeployment = (BundleGroupDeployment)
entityManager.find(
+ BundleGroupDeployment.class, bundleGroupDeploymentId);
+
+ BundleDeployment deployment = new BundleDeployment(deployDef, resource,
bundleGroupDeployment);
entityManager.persist(deployment);
return deployment;
}
+ @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
+ public BundleGroupDeployment createBundleGroupDeployment(BundleGroupDeployment
bundleGroupDeployment)
+ throws Exception {
+ entityManager.persist(bundleGroupDeployment);
+ return bundleGroupDeployment;
+ }
+
@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 fc4d224..b265f0e 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
@@ -25,6 +25,7 @@ import javax.ejb.Local;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.bundle.BundleDeployment;
import org.rhq.core.domain.bundle.BundleDeploymentHistory;
+import org.rhq.core.domain.bundle.BundleGroupDeployment;
import org.rhq.core.domain.bundle.BundleType;
/**
@@ -65,11 +66,17 @@ public interface BundleManagerLocal extends BundleManagerRemote {
BundleType createBundleType(Subject subject, String name, int resourceTypeId) throws
Exception;
/**
- * This is typically not called directly, typically deployBundle() is called
externally. This executes
- * in a New Transaction and supports deployBundle.
+ * This is typically not called directly, typically scheduleBundleDeployment() is
called externally. This executes
+ * in a New Transaction and supports scheduleBundleDeployment.
*/
- BundleDeployment createBundleDeployment(Subject subject, int
bundleDeployDefinitionId, int resourceId)
- throws Exception;
+ BundleDeployment createBundleDeployment(Subject subject, int
bundleDeployDefinitionId, int resourceId,
+ int bundleGroupDeploymentId) throws Exception;
+
+ /**
+ * This is typically not called directly, typically scheduleBundleGroupDeployment()
is called externally.
+ * This executes in a New Transaction and supports scheduleBundleGroupDeployment.
+ */
+ BundleGroupDeployment createBundleGroupDeployment(BundleGroupDeployment
bundleGroupDeployment) throws Exception;
// added here because the same method in @Remote was commented out to bypass a
WSProvide issue
Map<String, Boolean> getAllBundleVersionFilenames(Subject subject, int
bundleVersionId) throws Exception;
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 b3a84ff..6184a6c 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
@@ -33,6 +33,7 @@ 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.BundleGroupDeployment;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.bundle.composite.BundleWithLatestVersionComposite;
@@ -296,4 +297,23 @@ public interface BundleManagerRemote {
@WebParam(name = "bundleDeployDefinitionId") int
bundleDeployDefinitionId, //
@WebParam(name = "resourceId") int resourceId) throws Exception;
+ /**
+ * Deploy the bundle as described in the provided deploy definition to all of the
resources in the
+ * specified resource group.
+ * Deployment is asynchronous so return of this method does not indicate deployments
are complete. The
+ * returned BundleGroupDeployment can be used to track the history of the
deployments.
+ *
+ * TODO: Add the scheduling capability, currently it's Immediate.
+ *
+ * @param subject must be InventoryManager
+ * @param bundleDeployDefinitionId the BundleDeployDefinition being used to guide the
deployments
+ * @param resourceGroupId the target resourceGroup (must exist), typically platforms,
for the deployments
+ * @return the BundleGroupDeployment created to track the deployments.
+ * @throws Exception
+ */
+ @WebMethod
+ BundleGroupDeployment scheduleBundleGroupDeployment( //
+ @WebParam(name = "subject") Subject subject, //
+ @WebParam(name = "bundleDeployDefinitionId") int
bundleDeployDefinitionId, //
+ @WebParam(name = "resourceGroupId") int resourceGroupId) throws
Exception;
}
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
index 6521e5b..06b59c6 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/webservices/WebservicesManagerBean.java
@@ -42,6 +42,7 @@ 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.BundleGroupDeployment;
import org.rhq.core.domain.bundle.BundleType;
import org.rhq.core.domain.bundle.BundleVersion;
import org.rhq.core.domain.bundle.composite.BundleWithLatestVersionComposite;
@@ -425,7 +426,12 @@ public class WebservicesManagerBean implements WebservicesRemote {
return bundleManager.scheduleBundleDeployment(subject, bundleDeployDefinitionId,
resourceId);
}
- //BUNDLEMANAGER: END ----------------------------------
+ public BundleGroupDeployment scheduleBundleGroupDeployment(Subject subject, int
bundleDeployDefinitionId,
+ int resourceGroupId) throws Exception {
+ return bundleManager.scheduleBundleGroupDeployment(subject,
bundleDeployDefinitionId, resourceGroupId);
+ }
+
+ //BUNDLEMANAGER: END ----------------------------------
//CALLTIMEDATAMANAGER: BEGIN ----------------------------------
public PageList<CallTimeDataComposite> findCallTimeDataForResource(Subject
subject, int scheduleId, long beginTime,
commit d3e840578d34c8de89352e6502aa7227cfa58165
Merge: 0212483... 89d3004...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Tue Mar 23 17:03:54 2010 -0400
Merge branch 'gwt' of
ssh://git.fedorahosted.org/git/rhq/rhq into gwt
commit 02124836fdb9776037c4c184262493553694200b
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Tue Mar 23 17:02:07 2010 -0400
Some stuff for group bundle deploy
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
b/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
index 75675ef..178013b 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml
@@ -575,7 +575,9 @@
<column name="ID" default="sequence-only"
initial="10001" primarykey="true" required="true"
type="INTEGER"/>
<column name="BUNDLE_DEPLOY_DEF_ID" type="INTEGER"
required="true" references="RHQ_BUNDLE_DEPLOY_DEF" />
<column name="RESOURCE_ID" type="INTEGER"
required="true" references="RHQ_RESOURCE" />
- <column name="CTIME" type="LONG"
required="true"/>
+ <column name="CTIME" type="LONG"
required="true"/>
+ <!-- for group history -->
+ <column name="GROUP_ID" type="INTEGER"
required="false" references="RHQ_RESOURCE_GROUP"/>
<index name="RHQ_DEPLOY_DEF_RESOURCE_IDX"
unique="true">
<field ref="BUNDLE_DEPLOY_DEF_ID"/>
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 2b8848f..da47976 100644
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@ -2898,7 +2898,11 @@
<schema-alterColumn table="RHQ_BUNDLE_VERSION"
column="VERSION_ORDER" nullable="FALSE" />
</schemaSpec>
- <schemaSpec version="2.79">
+ <schemaSpec version="2.78.5">
+ <schema-addColumn table="RHQ_BUNDLE_DEPLOY"
column="RESOURCE_GROUP_ID" columnType="INTEGER" />
+ </schemaSpec>
+
+ <schemaSpec version="2.79">
<schema-directSQL>
<statement desc="Normalizing resource group
descriptions">
UPDATE RHQ_RESOURCE_GROUP SET DESCRIPTION = NULL WHERE
DESCRIPTION = ''
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/GroupBundleDeployment.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/GroupBundleDeployment.java
new file mode 100644
index 0000000..67ad13f
--- /dev/null
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/bundle/GroupBundleDeployment.java
@@ -0,0 +1,73 @@
+/*
+ * 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.domain.bundle;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.CascadeType;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+
+import org.rhq.core.domain.resource.group.ResourceGroup;
+
+@DiscriminatorValue("group")
+@Entity
+public class GroupBundleDeployment extends BundleDeployment {
+
+ private static final long serialVersionUID = 1L;
+
+ @JoinColumn(name = "GROUP_ID", referencedColumnName = "ID")
+ @ManyToOne
+ private ResourceGroup group;
+
+ @OneToMany(mappedBy = "groupBundleHistory", cascade = {
CascadeType.PERSIST, CascadeType.REMOVE })
+ private List<BundleDeployment> bundleDeployments = new
ArrayList<BundleDeployment>();
+
+ protected GroupBundleDeployment() {
+ }
+
+ public ResourceGroup getGroup() {
+ return group;
+ }
+
+ public void setGroup(ResourceGroup group) {
+ this.group = group;
+ }
+
+ public List<BundleDeployment> getBundleDeployments() {
+ return bundleDeployments;
+ }
+
+ public void setBundleDeployments(List<BundleDeployment> bundleDeployments) {
+ this.bundleDeployments = bundleDeployments;
+ }
+
+ public void addBundleDeployments(BundleDeployment bundleDeployment) {
+ this.bundleDeployments.add(bundleDeployment);
+ }
+
+}
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/group/ResourceGroup.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/group/ResourceGroup.java
index 63f229c..7a10422 100644
---
a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/group/ResourceGroup.java
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/group/ResourceGroup.java
@@ -55,6 +55,7 @@ import org.jetbrains.annotations.NotNull;
import org.rhq.core.domain.alert.AlertDefinition;
import org.rhq.core.domain.authz.Role;
+import org.rhq.core.domain.bundle.GroupBundleDeployment;
import org.rhq.core.domain.configuration.group.AbstractGroupConfigurationUpdate;
import org.rhq.core.domain.operation.GroupOperationHistory;
import org.rhq.core.domain.resource.Resource;
@@ -403,6 +404,11 @@ public class ResourceGroup extends Group {
// by primary key which will also put the configuration updates in chronological
order
private List<AbstractGroupConfigurationUpdate> configurationUpdates = new
ArrayList<AbstractGroupConfigurationUpdate>();
+ @OneToMany(mappedBy = "group", cascade = { CascadeType.ALL })
+ @OrderBy
+ // by primary key which will also put the operation histories in chronological order
+ private List<GroupBundleDeployment> bundleDeployments = new
ArrayList<GroupBundleDeployment>();
+
@JoinColumn(name = "GROUP_DEFINITION_ID", referencedColumnName =
"ID", nullable = true)
@ManyToOne
private GroupDefinition groupDefinition;
@@ -548,6 +554,14 @@ public class ResourceGroup extends Group {
this.configurationUpdates = configurationUpdates;
}
+ public List<GroupBundleDeployment> getBundleDeployments() {
+ return bundleDeployments;
+ }
+
+ public void setBundleDeployments(List<GroupBundleDeployment> bundleDeployments)
{
+ this.bundleDeployments = bundleDeployments;
+ }
+
public GroupDefinition getGroupDefinition() {
return groupDefinition;
}