modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java | 14
modules/core/domain/src/main/java/org/rhq/core/domain/content/transfer/ResourcePackageDetails.java | 46 +-
modules/core/plugin-container/src/main/java/org/rhq/core/pc/content/ContentManager.java | 90 ++++
modules/core/plugin-container/src/main/java/org/rhq/core/pc/content/RetrieveContentBitsRunner.java | 76 ++--
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateNewPackageUIBean.java | 86 +++-
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/ListPackageHistoryUIBean.java | 28 -
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/inventory/resource/CreateNewPackageChildResourceUIBean.java | 99 +++++
modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/repo.xhtml | 2
modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/create.xhtml | 3
modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/inventory/create-package-1.xhtml | 31 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java | 190 +++++++++-
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerHelper.java | 1
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java | 11
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerBean.java | 39 +-
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerLocal.java | 6
modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/deploy/AbstractDeployer.java | 49 ++
modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/JBossASServerComponent.java | 47 +-
modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/util/FileContentDelegate.java | 166 ++++----
18 files changed, 759 insertions(+), 225 deletions(-)
New commits:
commit 06136ac6f6ea806c3887cf2635ab0feb6b91378a
Author: Simeon Pinder <spinder(a)redhat.com>
Date: Wed May 26 04:22:31 2010 -0400
content synch up issue.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java
index 4e16f53..468dfc2 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java
@@ -69,6 +69,11 @@ import org.rhq.core.domain.resource.ProductVersion;
+ " AND pv.generalPackage.packageType.name = :packageTypeName "
+ " AND pv.generalPackage.packageType.resourceType.id = :resourceTypeId "
+ " AND pv.architecture.name = :architectureName " + " AND pv.version = :version "),
+ @NamedQuery(name = PackageVersion.QUERY_FIND_BY_PACKAGE_DETAILS_SHA, query = "SELECT pv FROM PackageVersion AS pv "
+ + " WHERE pv.generalPackage.name = :packageName "
+ + " AND pv.generalPackage.packageType.name = :packageTypeName " + " AND pv.sha256 = :sha "
+ + " AND pv.generalPackage.packageType.resourceType.id = :resourceTypeId "
+ + " AND pv.architecture.name = :architectureName " + " AND pv.version = :version "),
@NamedQuery(name = PackageVersion.QUERY_FIND_ID_BY_PACKAGE_DETAILS_KEY_AND_RES_ID, query = "SELECT pv.id "
+ " FROM PackageVersion AS pv " + " JOIN pv.generalPackage.packageType.resourceType.resources r "
+ " WHERE pv.generalPackage.name = :packageName "
@@ -249,6 +254,7 @@ public class PackageVersion implements Serializable {
public static final String QUERY_FIND_BY_PACKAGE_SHA = "PackageVersion.findByPackageSha";
public static final String QUERY_FIND_BY_PACKAGE_SHA_RES_TYPE = "PackageVersion.findByPackageShaResType";
public static final String QUERY_FIND_BY_PACKAGE_DETAILS_KEY = "PackageVersion.findByPackageDetailsKey";
+ public static final String QUERY_FIND_BY_PACKAGE_DETAILS_SHA = "PackageVersion.findByPackageDetailsSha";
public static final String QUERY_FIND_ID_BY_PACKAGE_DETAILS_KEY_AND_RES_ID = "PackageVersion.findIdByPackageDetailsKeyAndResId";
public static final String QUERY_FIND_BY_REPO_ID = "PackageVersion.findByRepoId";
public static final String QUERY_FIND_BY_REPO_ID_FILTERED = "PackageVersion.findByRepoIdFiltered";
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
index a36770f..5513fc1 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
@@ -243,13 +243,14 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
// See if package version already exists for the resource package
Query packageVersionQuery = entityManager
- .createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_DETAILS_KEY);
+ .createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_DETAILS_SHA);
packageVersionQuery.setFlushMode(FlushModeType.COMMIT);
packageVersionQuery.setParameter("packageName", resourcePackage.getName());
packageVersionQuery.setParameter("packageTypeName", resourcePackage.getPackageTypeName());
packageVersionQuery.setParameter("resourceTypeId", resource.getResourceType().getId());
packageVersionQuery.setParameter("architectureName", resourcePackage.getArchitectureName());
packageVersionQuery.setParameter("version", resourcePackage.getVersion());
+ packageVersionQuery.setParameter("sha", resourcePackage.getSHA256());
List<PackageVersion> existingPackageVersionList = packageVersionQuery.getResultList();
commit 278fae722d5ca8ab81a5c2d77d8d7efda781dc74
Merge: bd8ee1e... fa3fb9c...
Author: Simeon Pinder <spinder(a)redhat.com>
Date: Wed May 26 04:21:35 2010 -0400
Merge branch 'master' of ssh://spinder@git.fedorahosted.org/git/rhq/rhq
commit bd8ee1ee291e656dfec223110ed51d0cb24d2219
Author: Simeon Pinder <spinder(a)redhat.com>
Date: Wed May 26 02:51:17 2010 -0400
content: reapply ce0d8ab, sp changes, noResultException handling.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateNewPackageUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateNewPackageUIBean.java
index e488010..fbe9977 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateNewPackageUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateNewPackageUIBean.java
@@ -27,6 +27,7 @@ import java.util.Map;
import javax.faces.application.FacesMessage;
import javax.faces.model.SelectItem;
+import javax.persistence.NoResultException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@@ -80,6 +81,12 @@ public class CreateNewPackageUIBean {
*/
private static final String REPO_OPTION_NEW = "new";
+ /**
+ * Option value for no repo. This is a standalone war that may not be related to any repo.
+ *
+ */
+ private static final String REPO_OPTION_NONE = "none";
+
private String packageName;
private String version;
private int selectedArchitectureId;
@@ -153,6 +160,7 @@ public class CreateNewPackageUIBean {
String repoOption = request.getParameter("repoOption");
UploadItem fileItem = uploadUIBean.getFileItem();
+ boolean usingARepo = true;
// Validate
if (packageName == null || packageName.trim().equals("")) {
@@ -182,15 +190,21 @@ public class CreateNewPackageUIBean {
return null;
}
+ if (repoOption.equalsIgnoreCase(REPO_OPTION_NONE)) {
+ usingARepo = false;
+ }
+
// Determine which repo the package will go into
String repoId = null;
- try {
- repoId = determineRepo(repoOption, subject, resource.getId());
- } catch (ContentException ce) {
- String errorMessages = ThrowableUtil.getAllMessages(ce);
- FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "Failed to determine repository. Cause: "
- + errorMessages);
- return "failure";
+ if (usingARepo) {
+ try {
+ repoId = determineRepo(repoOption, subject, resource.getId());
+ } catch (ContentException ce) {
+ String errorMessages = ThrowableUtil.getAllMessages(ce);
+ FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "Failed to determine repository. Cause: "
+ + errorMessages);
+ return "failure";
+ }
}
try {
@@ -215,11 +229,9 @@ public class CreateNewPackageUIBean {
workflow and we'll deal with the refactoring later.
jdobies, Feb 27, 2008
*/
- PackageVersion packageVersion;
+ PackageVersion packageVersion = null;
try {
ContentManagerLocal contentManager = LookupUtil.getContentManager();
- packageVersion = contentManager.createPackageVersion(packageName, packageTypeId, version,
- architectureId, packageStream);
//store information about uploaded file for packageDetails as most of it is already available
Map<String, String> packageUploadDetails = new HashMap<String, String>();
@@ -244,26 +256,30 @@ public class CreateNewPackageUIBean {
packageVersion = contentManager.getUploadedPackageVersion(packageName, packageTypeId, version,
architectureId, packageStream, packageUploadDetails, newResourceTypeId);
+ } catch (NoResultException nre) {
+ //eat the exception. Some of the queries return no results if no package yet exists which is fine.
} catch (Exception e) {
String errorMessages = ThrowableUtil.getAllMessages(e);
FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "Failed to create package [" + packageName
- + "] in repo. Cause: " + errorMessages);
+ + "] in repository. Cause: " + errorMessages);
return "failure";
}
int[] packageVersionList = new int[] { packageVersion.getId() };
// Add the package to the repo
- try {
- int iRepoId = Integer.parseInt(repoId);
-
- RepoManagerLocal repoManager = LookupUtil.getRepoManagerLocal();
- repoManager.addPackageVersionsToRepo(subject, iRepoId, packageVersionList);
- } catch (Exception e) {
- String errorMessages = ThrowableUtil.getAllMessages(e);
- FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "Failed to associate package ["
- + packageName + "] with repository ID [" + repoId + "]. Cause: " + errorMessages);
- return "failure";
+ if (usingARepo) {
+ try {
+ int iRepoId = Integer.parseInt(repoId);
+
+ RepoManagerLocal repoManager = LookupUtil.getRepoManagerLocal();
+ repoManager.addPackageVersionsToRepo(subject, iRepoId, packageVersionList);
+ } catch (Exception e) {
+ String errorMessages = ThrowableUtil.getAllMessages(e);
+ FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "Failed to associate package ["
+ + packageName + "] with repository ID [" + repoId + "]. Cause: " + errorMessages);
+ return "failure";
+ }
}
// Put the package ID in the session so it can fit into the deploy existing package workflow
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/inventory/resource/CreateNewPackageChildResourceUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/inventory/resource/CreateNewPackageChildResourceUIBean.java
index a55927d..786d579 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/inventory/resource/CreateNewPackageChildResourceUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/inventory/resource/CreateNewPackageChildResourceUIBean.java
@@ -29,6 +29,7 @@ import java.util.Map;
import javax.faces.application.FacesMessage;
import javax.faces.model.SelectItem;
+import javax.persistence.NoResultException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -212,6 +213,8 @@ public class CreateNewPackageChildResourceUIBean {
}
+ } catch (NoResultException nre) {
+ //eat the exception. Some of the queries return no results if no package yet exists which is fine.
} catch (Exception e) {
String errorMessages = ThrowableUtil.getAllMessages(e);
FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR,
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/repo.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/repo.xhtml
index 55fdd56..28edad0 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/repo.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/content/repo.xhtml
@@ -333,7 +333,6 @@
<rich:column colspan="#{param.debug ? 8 : 7}"
width="100%">
- <ui:remove>
<!-- The ability to associate/disassociate repos with content sources is not needed for JON. -->
<h:commandButton
action="#{RepoContentSourcesUIBean.associateWithContentProviders}"
@@ -344,7 +343,6 @@
value="DISASSOCIATE SELECTED"
target="selectedRepoContentProviders"
styleClass="on-pager-button buttonsmall" />
- </ui:remove>
<ui:param name="paginationDataTableName"
value="repoContentProvidersDataTable" />
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
index 2136261..a36770f 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
@@ -191,27 +191,27 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
packageDiscoveredQuery.setParameter("resourceTypeId", resource.getResourceType().getId());
List<PackageVersion> discoveredPackages = packageDiscoveredQuery.getResultList();
if (discoveredPackages.size() > 0) {
- //iterate over packages to determine first one with same file name
- PackageVersion[] discovered = new PackageVersion[discoveredPackages.size()];
- discoveredPackages.toArray(discovered);
- boolean located = false;
- for (int i = 0; (!located && i < discovered.length); i++) {
- packageVersion = discovered[i];
- //check that the returned file name is same as expected otherwise
- //bail(bank1.war != crook1.war for auditing purposes) even though hash is equal.
- if (packageVersion.getFileName().trim().equals(resourcePackage.getFileName().trim())) {
- located = true;
- //now assign PackageVersion details correctly
- PackageDetailsKey discoveredKey = new PackageDetailsKey(packageVersion.getFileName(),
- packageVersion.getVersion(), packageVersion.getGeneralPackage().getPackageType()
- .getName(), resourcePackage.getArchitectureName());
- ResourcePackageDetails retrievedResourcePackage = new ResourcePackageDetails(
- discoveredKey);
- retrievedResourcePackage.setInstallationTimestamp(resourcePackage.getFileCreatedDate());
- //now reassign the resourcePackage to use this newly retrieved id.
- resourcePackage = retrievedResourcePackage;
- }
- }
+ // //iterate over packages to determine first one with same file name
+ // PackageVersion[] discovered = new PackageVersion[discoveredPackages.size()];
+ // discoveredPackages.toArray(discovered);
+ // boolean located = false;
+ // for (int i = 0; (!located && i < discovered.length); i++) {
+ // packageVersion = discovered[i];
+ // //check that the returned file name is same as expected otherwise
+ // //bail(bank1.war != crook1.war for auditing purposes) even though hash is equal.
+ // if (packageVersion.getFileName().trim().equals(resourcePackage.getFileName().trim())) {
+ // located = true;
+ // //now assign PackageVersion details correctly
+ // PackageDetailsKey discoveredKey = new PackageDetailsKey(packageVersion.getFileName(),
+ // packageVersion.getVersion(), packageVersion.getGeneralPackage().getPackageType()
+ // .getName(), resourcePackage.getArchitectureName());
+ // ResourcePackageDetails retrievedResourcePackage = new ResourcePackageDetails(
+ // discoveredKey);
+ // retrievedResourcePackage.setInstallationTimestamp(resourcePackage.getFileCreatedDate());
+ // //now reassign the resourcePackage to use this newly retrieved id.
+ // resourcePackage = retrievedResourcePackage;
+ // }
+ // }
packageVersion = discoveredPackages.get(0);
//check that the returned file name is same as expected otherwise
//bail(bank1.war != crook1.war for auditing purposes) even though hash is equal.
@@ -1608,6 +1608,7 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
packageVersion.setSHA256(packageUploadDetails.get(ContentManagerBean.UPLOAD_SHA256));
}
entityManager.merge(packageVersion);
+ entityManager.flush();
return packageVersion;
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerBean.java
index 8b0e4d6..3ecd40f 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerBean.java
@@ -30,6 +30,7 @@ import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
+import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@@ -319,7 +320,7 @@ public class ResourceFactoryManagerBean implements ResourceFactoryManagerLocal,
CreateResourceHistory history = new CreateResourceHistory(parentResource, resourceType, user.getName(),
(InstalledPackage) null);
history.setCreatedResourceName(createResourceName);
- history.setConfiguration(deploymentTimeConfiguration);
+ // history.setConfiguration(deploymentTimeConfiguration);
history.setStatus(CreateResourceStatus.IN_PROGRESS);
entityManager.persist(history);
@@ -529,6 +530,19 @@ public class ResourceFactoryManagerBean implements ResourceFactoryManagerLocal,
packageVersionNumber, architectureId, packageBitStream, packageUploadDetails, newResourceTypeId);
}
+ //check that Configuration is persisted correctly.
+ if (deploymentTimeConfiguration.getId() > 0) {
+ entityManager.merge(deploymentTimeConfiguration);
+ } else {
+ entityManager.persist(deploymentTimeConfiguration);
+ }
+ //check that Configuration is persisted correctly.
+ if (pluginConfiguration.getId() > 0) {
+ entityManager.merge(pluginConfiguration);
+ } else {
+ entityManager.persist(pluginConfiguration);
+ }
+
// Persist in separate transaction so it is committed immediately, before the request is sent to the agent
CreateResourceHistory persistedHistory = resourceFactoryManager.persistCreateHistory(user, parentResourceId,
newResourceTypeId, newResourceName, packageVersion, deploymentTimeConfiguration);
@@ -544,6 +558,8 @@ public class ResourceFactoryManagerBean implements ResourceFactoryManagerLocal,
AgentClient agentClient = agentManager.getAgentClient(agent);
ResourceFactoryAgentService resourceFactoryAgentService = agentClient.getResourceFactoryAgentService();
resourceFactoryAgentService.createResource(request);
+ } catch (NoResultException nre) {
+ //eat the exception. Some of the queries return no results if no package yet exists which is fine.
} catch (Exception e) {
log.error("Error while sending create resource request to agent service", e);
commit 5db6f43e511700a4de58dace6461a81b308ecc70
Author: Simeon Pinder <spinder(a)redhat.com>
Date: Tue May 25 15:00:24 2010 -0400
BZ:589173: modified agent side and server side to update pkg version using Sha.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java
index 4bfc1db..4e16f53 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java
@@ -60,6 +60,10 @@ import org.rhq.core.domain.resource.ProductVersion;
+ " AND pv.architecture.id = :architectureId " + " AND pv.version = :version "),
@NamedQuery(name = PackageVersion.QUERY_FIND_BY_PACKAGE_SHA, query = "SELECT pv FROM PackageVersion AS pv "
+ " WHERE pv.sha256 = :sha "),
+ @NamedQuery(name = PackageVersion.QUERY_FIND_BY_PACKAGE_SHA_RES_TYPE, query = "SELECT pv FROM PackageVersion AS pv "
+ + " WHERE pv.sha256 = :sha "
+ + " AND pv.displayName = :displayName "
+ + " AND pv.generalPackage.packageType.resourceType.id = :resourceTypeId "),
@NamedQuery(name = PackageVersion.QUERY_FIND_BY_PACKAGE_DETAILS_KEY, query = "SELECT pv FROM PackageVersion AS pv "
+ " WHERE pv.generalPackage.name = :packageName "
+ " AND pv.generalPackage.packageType.name = :packageTypeName "
@@ -243,6 +247,7 @@ public class PackageVersion implements Serializable {
public static final String QUERY_FIND_BY_PACKAGE_VER_ARCH = "PackageVersion.findByPackageVerArch";
public static final String QUERY_FIND_BY_PACKAGE_SHA = "PackageVersion.findByPackageSha";
+ public static final String QUERY_FIND_BY_PACKAGE_SHA_RES_TYPE = "PackageVersion.findByPackageShaResType";
public static final String QUERY_FIND_BY_PACKAGE_DETAILS_KEY = "PackageVersion.findByPackageDetailsKey";
public static final String QUERY_FIND_ID_BY_PACKAGE_DETAILS_KEY_AND_RES_ID = "PackageVersion.findIdByPackageDetailsKeyAndResId";
public static final String QUERY_FIND_BY_REPO_ID = "PackageVersion.findByRepoId";
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 9f6ff44..e46f403 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
@@ -23,6 +23,7 @@
package org.rhq.core.pc.content;
import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -39,6 +40,8 @@ import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -80,6 +83,7 @@ import org.rhq.core.util.MessageDigestGenerator;
public class ContentManager extends AgentService implements ContainerService, ContentAgentService, ContentServices {
private static final int FACET_METHOD_TIMEOUT = 60 * 60 * 1000; // 60 minutes
+ public static final String RHQ_SHA256 = "RHQ-Sha256";
private final Log log = LogFactory.getLog(ContentManager.class);
/**
@@ -661,24 +665,42 @@ public class ContentManager extends AgentService implements ContainerService, Co
for (ResourcePackageDetails detail : recentlyDiscoveredArray) {
try {
- //if the filesize of discovered package is null then it's an exploded and deployed war/ear.
- if ((detail.getFileSize() == null) || (detail.getFileSize() == 0)) {
- //when deployed exploded then don't calculate digest but update string with message to that effect.
- //TODO: is this ok? Once exploded and run at all ... contents could be different.
- detail.setSHA256("(deployed exploded. no message digest possible)");
+ //only operate on .ear/.war
+ String currentFile = detail.getFileName();
+ if (currentFile != null) {
+ currentFile = currentFile.toLowerCase();
}
- //and for each detail where size != null or non empty ... then an un-exploded war/ear
- if ((detail.getFileSize() != null) || (detail.getFileSize() > 0)) {
- File localCopy = null;
- if ((detail.getLocation() != null) && (!detail.getLocation().isEmpty())) {
- localCopy = new File(detail.getLocation());
- //calculate md5
- String sha256 = new MessageDigestGenerator(MessageDigestGenerator.SHA_256)
- .calcDigestString(localCopy);
- //and attach it to the report returned to be picked up on server side in merge
- detail.setSHA256(sha256);
- //attach fileCreatedDate as well
- detail.setInstallationTimestamp(Long.valueOf(System.currentTimeMillis()));
+ if (currentFile != null && (currentFile.endsWith(".ear") || currentFile.endsWith(".war"))) {
+ //if the filesize of discovered package is null then it's an exploded and deployed war/ear.
+ if ((detail.getFileSize() == null) || (detail.getFileSize() == 0)) {
+ //when deployed exploded then don't calculate digest but check for META-INF entry
+ File explodedDirectory = new File(detail.getLocation());
+ File manifestFile = new File(explodedDirectory, "META-INF/MANIFEST.MF");
+ Manifest manifest;
+ if (manifestFile.exists()) {
+ FileInputStream inputStream = new FileInputStream(manifestFile);
+ manifest = new Manifest(inputStream);
+ inputStream.close();
+ Attributes attribs = manifest.getMainAttributes();
+ String retrievedShaValue = attribs.getValue(RHQ_SHA256);
+ if ((retrievedShaValue != null) && (!retrievedShaValue.trim().isEmpty())) {
+ detail.setSHA256(retrievedShaValue);
+ }
+ }
+ }
+ //and for each detail where size != null or non empty ... then an un-exploded war/ear
+ else if ((detail.getFileSize() != null) || (detail.getFileSize() > 0)) {
+ File localCopy = null;
+ if ((detail.getLocation() != null) && (!detail.getLocation().isEmpty())) {
+ localCopy = new File(detail.getLocation());
+ //calculate md5
+ String sha256 = new MessageDigestGenerator(MessageDigestGenerator.SHA_256)
+ .calcDigestString(localCopy);
+ //and attach it to the report returned to be picked up on server side in merge
+ detail.setSHA256(sha256);
+ //attach fileCreatedDate as well
+ detail.setInstallationTimestamp(Long.valueOf(System.currentTimeMillis()));
+ }
}
}
} catch (IOException iex) {
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateNewPackageUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateNewPackageUIBean.java
index 3db7ce6..e488010 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateNewPackageUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/CreateNewPackageUIBean.java
@@ -21,7 +21,9 @@ package org.rhq.enterprise.gui.content;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import javax.faces.application.FacesMessage;
import javax.faces.model.SelectItem;
@@ -44,9 +46,11 @@ import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceCreationDataType;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.gui.util.FacesContextUtility;
+import org.rhq.core.util.MessageDigestGenerator;
import org.rhq.core.util.exception.ThrowableUtil;
import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility;
import org.rhq.enterprise.server.content.ContentException;
+import org.rhq.enterprise.server.content.ContentManagerBean;
import org.rhq.enterprise.server.content.ContentManagerLocal;
import org.rhq.enterprise.server.content.ContentUIManagerLocal;
import org.rhq.enterprise.server.content.RepoManagerLocal;
@@ -216,6 +220,30 @@ public class CreateNewPackageUIBean {
ContentManagerLocal contentManager = LookupUtil.getContentManager();
packageVersion = contentManager.createPackageVersion(packageName, packageTypeId, version,
architectureId, packageStream);
+
+ //store information about uploaded file for packageDetails as most of it is already available
+ Map<String, String> packageUploadDetails = new HashMap<String, String>();
+ packageUploadDetails.put(ContentManagerBean.UPLOAD_FILE_SIZE, String.valueOf(fileItem.getFileSize()));
+ packageUploadDetails.put(ContentManagerBean.UPLOAD_FILE_INSTALL_DATE, String.valueOf(System
+ .currentTimeMillis()));
+ packageUploadDetails.put(ContentManagerBean.UPLOAD_OWNER, subject.getName());
+ packageUploadDetails.put(ContentManagerBean.UPLOAD_FILE_NAME, fileItem.getFileName());
+
+ try {//Easier to implement here than in server side bean. Shouldn't affect performance too much.
+ packageUploadDetails.put(ContentManagerBean.UPLOAD_MD5, new MessageDigestGenerator(
+ MessageDigestGenerator.MD5).calcDigestString(fileItem.getFile()));
+ packageUploadDetails.put(ContentManagerBean.UPLOAD_SHA256, new MessageDigestGenerator(
+ MessageDigestGenerator.SHA_256).calcDigestString(fileItem.getFile()));
+ } catch (IOException e1) {
+ log.warn("Error calculating file digest(s) : " + e1.getMessage());
+ e1.printStackTrace();
+ }
+
+ //TODO: need to get parent id instead right? ref to app server inst itself?
+ int newResourceTypeId = resource.getResourceType().getId();
+ packageVersion = contentManager.getUploadedPackageVersion(packageName, packageTypeId, version,
+ architectureId, packageStream, packageUploadDetails, newResourceTypeId);
+
} catch (Exception e) {
String errorMessages = ThrowableUtil.getAllMessages(e);
FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "Failed to create package [" + packageName
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/create.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/create.xhtml
index 53f8f4d..ec32881 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/create.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/content/create.xhtml
@@ -43,7 +43,8 @@
<h:form id="uploadForm">
<input type="hidden" name="id" value="${param.id}"/>
- <rich:panel rendered="#{CreateNewPackageUIBean.needRequestPackageDetails}">
+ <!-- <rich:panel rendered="#{CreateNewPackageUIBean.needRequestPackageDetails}">-->
+ <rich:panel >
<f:facet name="header">New Package Details</f:facet>
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
index 507c432..2136261 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
@@ -149,8 +149,8 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
// For performance tracking
long start = System.currentTimeMillis();
- log.debug("Merging [" + report.getDeployedPackages().size() + "] packages for Resource with id ["
- + resourceId + "]...");
+ log.debug("Merging [" + report.getDeployedPackages().size() + "] packages for Resource with id [" + resourceId
+ + "]...");
// Load the resource and its installed packages
Resource resource = entityManager.find(Resource.class, resourceId);
@@ -185,8 +185,10 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
if ((md5Value == null) || (md5Value.isEmpty())) {
//query for installed packages with SHA256
Query packageDiscoveredQuery = entityManager
- .createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_SHA);
+ .createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_SHA_RES_TYPE);
packageDiscoveredQuery.setParameter("sha", shaValue);
+ packageDiscoveredQuery.setParameter("displayName", resourcePackage.getFileName());
+ packageDiscoveredQuery.setParameter("resourceTypeId", resource.getResourceType().getId());
List<PackageVersion> discoveredPackages = packageDiscoveredQuery.getResultList();
if (discoveredPackages.size() > 0) {
//iterate over packages to determine first one with same file name
@@ -210,6 +212,17 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
resourcePackage = retrievedResourcePackage;
}
}
+ packageVersion = discoveredPackages.get(0);
+ //check that the returned file name is same as expected otherwise
+ //bail(bank1.war != crook1.war for auditing purposes) even though hash is equal.
+ //now assign PackageVersion details correctly
+ PackageDetailsKey discoveredKey = new PackageDetailsKey(packageVersion.getDisplayName(),
+ packageVersion.getVersion(), packageVersion.getGeneralPackage().getPackageType().getName(),
+ resourcePackage.getArchitectureName());
+ ResourcePackageDetails retrievedResourcePackage = new ResourcePackageDetails(discoveredKey);
+ retrievedResourcePackage.setInstallationTimestamp(resourcePackage.getFileCreatedDate());
+ //now reassign the resourcePackage to use this newly retrieved id.
+ resourcePackage = retrievedResourcePackage;
}
}
}
diff --git a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/deploy/AbstractDeployer.java b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/deploy/AbstractDeployer.java
index 65f9598..8f98d9c 100644
--- a/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/deploy/AbstractDeployer.java
+++ b/modules/plugins/jboss-as-5/src/main/java/org/rhq/plugins/jbossas5/deploy/AbstractDeployer.java
@@ -23,11 +23,17 @@
package org.rhq.plugins.jbossas5.deploy;
import java.io.File;
-import java.util.Set;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.net.URI;
import java.util.Collection;
+import java.util.Set;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+
import org.jboss.deployers.spi.management.KnownDeploymentTypes;
import org.jboss.deployers.spi.management.ManagementView;
import org.jboss.deployers.spi.management.deploy.DeploymentManager;
@@ -40,6 +46,7 @@ import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
import org.rhq.core.domain.resource.CreateResourceStatus;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.pluginapi.inventory.CreateResourceReport;
+import org.rhq.core.util.MessageDigestGenerator;
import org.rhq.plugins.jbossas5.connection.ProfileServiceConnection;
import org.rhq.plugins.jbossas5.util.ConversionUtils;
import org.rhq.plugins.jbossas5.util.DeploymentUtils;
@@ -53,6 +60,7 @@ import org.rhq.plugins.jbossas5.util.DeploymentUtils;
public abstract class AbstractDeployer implements Deployer {
private static final ProfileKey FARM_PROFILE_KEY = new ProfileKey("farm");
private static final ProfileKey APPLICATIONS_PROFILE_KEY = new ProfileKey("applications");
+ public static final String DEPLOYMENT_NAME_PROPERTY = "deploymentName";
private final Log log = LogFactory.getLog(this.getClass());
@@ -97,25 +105,54 @@ public abstract class AbstractDeployer implements Deployer {
}
if (!farmSupported) {
throw new IllegalStateException("This application server instance is not a node in a cluster, "
- + "so it does not support farmed deployments. Supported deployment profiles are "
- + profileKeys + ".");
+ + "so it does not support farmed deployments. Supported deployment profiles are " + profileKeys
+ + ".");
}
if (deployExploded) {
- throw new IllegalArgumentException("Deploying farmed applications in exploded form is not supported by the Profile Service.");
+ throw new IllegalArgumentException(
+ "Deploying farmed applications in exploded form is not supported by the Profile Service.");
}
deploymentManager.loadProfile(FARM_PROFILE_KEY);
}
try {
DeploymentUtils.deployArchive(deploymentManager, archiveFile, deployExploded);
- }
- finally {
+ } finally {
// Make sure to switch back to the 'applications' profile if we switched to the 'farm' profile above.
if (deployFarmed) {
deploymentManager.loadProfile(APPLICATIONS_PROFILE_KEY);
}
}
+ //if deployed exploded, we need to store the sha of source package for correct versioning
+ if (deployExploded) {
+ String shaString = new MessageDigestGenerator(MessageDigestGenerator.SHA_256)
+ .getDigestString(archiveFile);
+ String deploymentName = deployTimeConfig.getSimple(DEPLOYMENT_NAME_PROPERTY).getStringValue();
+ URI deployePackageURI = URI.create(deploymentName);
+ // e.g.: foo.war
+ String path = deployePackageURI.getPath();
+ File location = new File(path);
+ //We've located the deployed
+ if ((location != null) && (location.isDirectory())) {
+ File manifestFile = new File(location, "META-INF/MANIFEST.MF");
+ Manifest manifest;
+ if (manifestFile.exists()) {
+ FileInputStream inputStream = new FileInputStream(manifestFile);
+ manifest = new Manifest(inputStream);
+ inputStream.close();
+ } else {
+ manifest = new Manifest();
+ }
+ Attributes attribs = manifest.getMainAttributes();
+ // attribs.put("RHQ-Sha256", shaString);
+ attribs.putValue("RHQ-Sha256", shaString);
+ FileOutputStream outputStream = new FileOutputStream(manifestFile);
+ manifest.write(outputStream);
+ outputStream.close();
+ }
+ }
+
// Deployment was successful!
createResourceReport.setResourceName(archiveName);
createResourceReport.setResourceKey(archiveName);
diff --git a/modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/JBossASServerComponent.java b/modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/JBossASServerComponent.java
index 7effdd5..4dc7a41 100644
--- a/modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/JBossASServerComponent.java
+++ b/modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/JBossASServerComponent.java
@@ -43,10 +43,11 @@ import java.util.jar.JarFile;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
+import com.jboss.jbossnetwork.product.jbpm.handlers.ControlActionFacade;
+import com.jboss.jbossnetwork.product.jbpm.handlers.InPluginControlActionFacade;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.jboss.on.common.jbossas.JBPMWorkflowManager;
-import org.jboss.on.common.jbossas.JBossASPaths;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
@@ -62,13 +63,16 @@ import org.mc4j.ems.connection.support.ConnectionProvider;
import org.mc4j.ems.connection.support.metadata.ConnectionTypeDescriptor;
import org.mc4j.ems.connection.support.metadata.InternalVMTypeDescriptor;
-import org.rhq.core.domain.content.transfer.DeployPackagesResponse;
-import org.rhq.core.domain.content.transfer.RemovePackagesResponse;
+import org.jboss.on.common.jbossas.JBPMWorkflowManager;
+import org.jboss.on.common.jbossas.JBossASPaths;
+
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.content.PackageDetailsKey;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.transfer.DeployPackageStep;
+import org.rhq.core.domain.content.transfer.DeployPackagesResponse;
+import org.rhq.core.domain.content.transfer.RemovePackagesResponse;
import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.domain.measurement.MeasurementDataNumeric;
@@ -94,6 +98,7 @@ import org.rhq.core.pluginapi.support.SnapshotReportRequest;
import org.rhq.core.pluginapi.support.SnapshotReportResults;
import org.rhq.core.pluginapi.support.SupportFacet;
import org.rhq.core.pluginapi.util.FileUtils;
+import org.rhq.core.util.MessageDigestGenerator;
import org.rhq.plugins.jbossas.helper.JavaSystemProperties;
import org.rhq.plugins.jbossas.helper.MainDeployer;
import org.rhq.plugins.jbossas.util.ConnectionFactoryConfigurationEditor;
@@ -109,9 +114,6 @@ import org.rhq.plugins.jmx.JMXComponent;
import org.rhq.plugins.jmx.JMXDiscoveryComponent;
import org.rhq.plugins.jmx.ObjectNameQueryUtility;
-import com.jboss.jbossnetwork.product.jbpm.handlers.ControlActionFacade;
-import com.jboss.jbossnetwork.product.jbpm.handlers.InPluginControlActionFacade;
-
/**
* Supports JBoss 3.2.3 through 4.2.x
*
@@ -261,7 +263,7 @@ public class JBossASServerComponent implements MeasurementFacet, OperationFacet,
this.logFileEventDelegate = new LogFileEventResourceComponentHelper(this.resourceContext);
this.logFileEventDelegate.startLogFileEventPollers();
-
+
// prepare to perform async avail checking
String availCheckPeriodProp = pluginConfig.getSimpleValue(AVAIL_CHECK_PERIOD_CONFIG_PROP, null);
if (availCheckPeriodProp != null) {
@@ -279,7 +281,7 @@ public class JBossASServerComponent implements MeasurementFacet, OperationFacet,
}
}
- return;
+ return;
}
public void stop() {
@@ -319,12 +321,12 @@ public class JBossASServerComponent implements MeasurementFacet, OperationFacet,
// A different server must have been started on our JNP URL - this is definitely something about which
// the user should be informed.
if (!this.loggedHijackedJnpUrlError) {
- String namingURL = this.resourceContext.getPluginConfiguration().
- getSimpleValue(NAMING_URL_CONFIG_PROP, null);
+ String namingURL = this.resourceContext.getPluginConfiguration().getSimpleValue(
+ NAMING_URL_CONFIG_PROP, null);
String message = "Availability check for JBoss AS Resource with configPath [" + this.configPath
- + "] has connected to a different running JBoss AS instance which is installed at ["
- + serverHomeViaJnp + "] using namingURL [" + namingURL
- + "] - returning AvailabilityType.DOWN...";
+ + "] has connected to a different running JBoss AS instance which is installed at ["
+ + serverHomeViaJnp + "] using namingURL [" + namingURL
+ + "] - returning AvailabilityType.DOWN...";
log.error(message);
this.loggedHijackedJnpUrlError = true;
// Throw an exception, so the PC can send the message to the Server for display in the GUI.
@@ -343,7 +345,7 @@ public class JBossASServerComponent implements MeasurementFacet, OperationFacet,
File serverHomeViaJnp;
EmsAttribute serverHomeDirAttrib = bean.getAttribute("ServerHomeDir");
if (serverHomeDirAttrib != null) {
- serverHomeViaJnp = (File)serverHomeDirAttrib.refresh();
+ serverHomeViaJnp = (File) serverHomeDirAttrib.refresh();
} else {
// We have a non-null MBean but a null ServerHomeDir attribute. This most likely means we're
// connected to a JBoss 5.x or 6.x instance, because in those versions the ServerConfig MBean no
@@ -356,12 +358,12 @@ public class JBossASServerComponent implements MeasurementFacet, OperationFacet,
return serverHomeViaJnp;
}
- private static File toFile(URL url) {
+ private static File toFile(URL url) {
File file;
try {
- file = new File(url.toURI());
- } catch(URISyntaxException e) {
- file = new File(url.getPath());
+ file = new File(url.toURI());
+ } catch (URISyntaxException e) {
+ file = new File(url.getPath());
}
return file;
}
@@ -456,8 +458,8 @@ public class JBossASServerComponent implements MeasurementFacet, OperationFacet,
public SnapshotReportResults getSnapshotReport(SnapshotReportRequest request) throws Exception {
Configuration pluginConfig = resourceContext.getPluginConfiguration();
String tmpDir = resourceContext.getTemporaryDirectory().getAbsolutePath();
- JBossASSnapshotReport report = new JBossASSnapshotReport(request.getName(), request.getDescription(), pluginConfig, this.configPath
- .getCanonicalPath(), tmpDir);
+ JBossASSnapshotReport report = new JBossASSnapshotReport(request.getName(), request.getDescription(),
+ pluginConfig, this.configPath.getCanonicalPath(), tmpDir);
File reportFile = report.generate();
InputStream inputStream = new BufferedInputStream(new FileInputStream(reportFile));
SnapshotReportResults results = new SnapshotReportResults(inputStream);
@@ -895,7 +897,8 @@ public class JBossASServerComponent implements MeasurementFacet, OperationFacet,
}
InputStream isForTempDir = new BufferedInputStream(new FileInputStream(tempFile));
- deployer.createContent(details, isForTempDir, !zip, createBackup);
+ String shaString = new MessageDigestGenerator(MessageDigestGenerator.SHA_256).getDigestString(tempFile);
+ deployer.createContent(details, isForTempDir, !zip, createBackup, shaString);
String vhost = null;
if (resourceTypeName.equals(RESOURCE_TYPE_WAR)) {
diff --git a/modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/util/FileContentDelegate.java b/modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/util/FileContentDelegate.java
index 331dc56..4f112b3 100644
--- a/modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/util/FileContentDelegate.java
+++ b/modules/plugins/jboss-as/src/main/java/org/rhq/plugins/jbossas/util/FileContentDelegate.java
@@ -1,55 +1,58 @@
- /*
- * Jopr 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.plugins.jbossas.util;
-
- import java.io.BufferedInputStream;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.io.InputStream;
- import java.util.Set;
-
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
-
- import org.rhq.core.domain.content.PackageDetails;
- import org.rhq.core.domain.content.PackageDetailsKey;
- import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
- import org.rhq.core.pluginapi.util.FileUtils;
- import org.rhq.core.util.ZipUtil;
- import org.rhq.core.util.file.FileUtil;
-
- /**
- * Delegate class used for manipulating artifacts in a JON plugin.
+/*
+ * Jopr 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.
*
- * @author Greg Hinkle
- * @author Jason Dobies
+ * 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.jbossas.util;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Set;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.domain.content.PackageDetails;
+import org.rhq.core.domain.content.PackageDetailsKey;
+import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
+import org.rhq.core.pluginapi.util.FileUtils;
+import org.rhq.core.util.ZipUtil;
+import org.rhq.core.util.file.FileUtil;
+
+/**
+* Delegate class used for manipulating artifacts in a JON plugin.
+*
+* @author Greg Hinkle
+* @author Jason Dobies
+*/
public class FileContentDelegate {
// Attributes --------------------------------------------
- private Log log = LogFactory.getLog(FileContentDelegate.class);
+ private Log log = LogFactory.getLog(FileContentDelegate.class);
protected File directory;
@@ -85,17 +88,34 @@ public class FileContentDelegate {
* @param details describes the package being created
* @param content content to be written for the package. NOTE this Stream will be closed by this method.
* @param unzip if <code>true</code>, the content stream will be treated like a ZIP file and be unzipped as
-* it is written, using the package name as the base directory; if <code>false</code> the
+ * it is written, using the package name as the base directory; if <code>false</code> the
* @param createBackup If <code>true</code>, the original file will be backed up to file.bak
+ * @param shaString the SHA-256 of the specified input stream
*/
- public void createContent(PackageDetails details, InputStream content, boolean unzip, boolean createBackup) {
+ public void createContent(PackageDetails details, InputStream content, boolean unzip, boolean createBackup,
+ String shaString) {
File contentFile = getPath(details);
try {
if (createBackup) {
- moveToBackup(contentFile,".bak");
+ moveToBackup(contentFile, ".bak");
}
if (unzip) {
ZipUtil.unzipFile(content, contentFile);
+ File manifestFile = new File(contentFile, "META-INF/MANIFEST.MF");
+ Manifest manifest;
+ if (manifestFile.exists()) {
+ FileInputStream inputStream = new FileInputStream(manifestFile);
+ manifest = new Manifest(inputStream);
+ inputStream.close();
+ } else {
+ manifest = new Manifest();
+ }
+ Attributes attribs = manifest.getMainAttributes();
+ // attribs.put("RHQ-Sha256", shaString);
+ attribs.putValue("RHQ-Sha256", shaString);
+ FileOutputStream outputStream = new FileOutputStream(manifestFile);
+ manifest.write(outputStream);
+ outputStream.close();
} else {
FileUtil.writeFile(content, contentFile);
}
@@ -105,25 +125,25 @@ public class FileContentDelegate {
}
}
- /**
- * Try to move the passed contentFile to a backup named contentFile + suffix
- * @param contentFile File object pointing to the original file
- * @param suffix the suffix to tack on
- */
- private void moveToBackup(File contentFile, String suffix) {
-
- File backupFile = new File(contentFile.getAbsolutePath() + suffix);
- if (backupFile.exists()) {
- // remove
- if (!backupFile.delete())
- log.warn("Removing of old backup file " + backupFile + " failed ");
- }
- if (!contentFile.renameTo(backupFile)) {
- log.warn("Moving " + contentFile + " to backup " + backupFile + " failed");
- }
- }
-
- public File getPath(PackageDetails details) {
+ /**
+ * Try to move the passed contentFile to a backup named contentFile + suffix
+ * @param contentFile File object pointing to the original file
+ * @param suffix the suffix to tack on
+ */
+ private void moveToBackup(File contentFile, String suffix) {
+
+ File backupFile = new File(contentFile.getAbsolutePath() + suffix);
+ if (backupFile.exists()) {
+ // remove
+ if (!backupFile.delete())
+ log.warn("Removing of old backup file " + backupFile + " failed ");
+ }
+ if (!contentFile.renameTo(backupFile)) {
+ log.warn("Moving " + contentFile + " to backup " + backupFile + " failed");
+ }
+ }
+
+ public File getPath(PackageDetails details) {
/* JBNADM-2022 - It still needs to be determined if it is the responsibility of the plugin container or the
* plugin to be concerned with path information in the package name. For now, it's the plugin's
* responsibility. We strip out the path information to keep control of where the JARs are
@@ -174,10 +194,8 @@ public class FileContentDelegate {
try {
FileUtils.purge(contentFile, true);
- }
- catch (IOException e) {
- throw new RuntimeException("Failed to delete underlying file [" + contentFile + "] for " + details
- + ".", e);
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to delete underlying file [" + contentFile + "] for " + details + ".", e);
}
}
@@ -188,4 +206,4 @@ public class FileContentDelegate {
*/
return null;
}
- }
\ No newline at end of file
+}
\ No newline at end of file
commit 123f9e9cd6a5da9f966c8e0d3f0814478459a34e
Author: Simeon Pinder <spinder(a)redhat.com>
Date: Fri May 21 16:49:58 2010 -0400
BZ-583104: populate install date details for content.
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 e993082..9f6ff44 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
@@ -677,6 +677,8 @@ public class ContentManager extends AgentService implements ContainerService, Co
.calcDigestString(localCopy);
//and attach it to the report returned to be picked up on server side in merge
detail.setSHA256(sha256);
+ //attach fileCreatedDate as well
+ detail.setInstallationTimestamp(Long.valueOf(System.currentTimeMillis()));
}
}
} catch (IOException iex) {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
index bd6d933..507c432 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
@@ -183,20 +183,33 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
//discovered with created
String md5Value = resourcePackage.getMD5();
if ((md5Value == null) || (md5Value.isEmpty())) {
- //query for installed packages with SHA256, we'll grab first one. All identical.
+ //query for installed packages with SHA256
Query packageDiscoveredQuery = entityManager
.createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_SHA);
packageDiscoveredQuery.setParameter("sha", shaValue);
List<PackageVersion> discoveredPackages = packageDiscoveredQuery.getResultList();
if (discoveredPackages.size() > 0) {
- packageVersion = discoveredPackages.get(0);
- //now assign PackageVersion details correctly
- PackageDetailsKey discoveredKey = new PackageDetailsKey(packageVersion.getFileName(),
- packageVersion.getVersion(), packageVersion.getGeneralPackage().getPackageType().getName(),
- resourcePackage.getArchitectureName());
- ResourcePackageDetails retrievedResourcePackage = new ResourcePackageDetails(discoveredKey);
- //now reassign the resourcePackage to use this newly retrieved id.
- resourcePackage = retrievedResourcePackage;
+ //iterate over packages to determine first one with same file name
+ PackageVersion[] discovered = new PackageVersion[discoveredPackages.size()];
+ discoveredPackages.toArray(discovered);
+ boolean located = false;
+ for (int i = 0; (!located && i < discovered.length); i++) {
+ packageVersion = discovered[i];
+ //check that the returned file name is same as expected otherwise
+ //bail(bank1.war != crook1.war for auditing purposes) even though hash is equal.
+ if (packageVersion.getFileName().trim().equals(resourcePackage.getFileName().trim())) {
+ located = true;
+ //now assign PackageVersion details correctly
+ PackageDetailsKey discoveredKey = new PackageDetailsKey(packageVersion.getFileName(),
+ packageVersion.getVersion(), packageVersion.getGeneralPackage().getPackageType()
+ .getName(), resourcePackage.getArchitectureName());
+ ResourcePackageDetails retrievedResourcePackage = new ResourcePackageDetails(
+ discoveredKey);
+ retrievedResourcePackage.setInstallationTimestamp(resourcePackage.getFileCreatedDate());
+ //now reassign the resourcePackage to use this newly retrieved id.
+ resourcePackage = retrievedResourcePackage;
+ }
+ }
}
}
}
commit c7a3cd80a75f9f5141a5a95553906eb4e361d134
Author: Simeon Pinder <spinder(a)redhat.com>
Date: Thu May 20 16:10:29 2010 -0400
BZ-589193: numerous changes for details of content uploaded. UI + mergeDiscovery + agent side.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java
index 42e7605..4bfc1db 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/content/PackageVersion.java
@@ -58,6 +58,8 @@ import org.rhq.core.domain.resource.ProductVersion;
@NamedQuery(name = PackageVersion.QUERY_FIND_BY_PACKAGE_VER_ARCH, query = "SELECT pv FROM PackageVersion AS pv "
+ " WHERE pv.generalPackage.name = :name " + " AND pv.generalPackage.packageType.id = :packageTypeId "
+ " AND pv.architecture.id = :architectureId " + " AND pv.version = :version "),
+ @NamedQuery(name = PackageVersion.QUERY_FIND_BY_PACKAGE_SHA, query = "SELECT pv FROM PackageVersion AS pv "
+ + " WHERE pv.sha256 = :sha "),
@NamedQuery(name = PackageVersion.QUERY_FIND_BY_PACKAGE_DETAILS_KEY, query = "SELECT pv FROM PackageVersion AS pv "
+ " WHERE pv.generalPackage.name = :packageName "
+ " AND pv.generalPackage.packageType.name = :packageTypeName "
@@ -240,6 +242,7 @@ public class PackageVersion implements Serializable {
private static final long serialVersionUID = 1L;
public static final String QUERY_FIND_BY_PACKAGE_VER_ARCH = "PackageVersion.findByPackageVerArch";
+ public static final String QUERY_FIND_BY_PACKAGE_SHA = "PackageVersion.findByPackageSha";
public static final String QUERY_FIND_BY_PACKAGE_DETAILS_KEY = "PackageVersion.findByPackageDetailsKey";
public static final String QUERY_FIND_ID_BY_PACKAGE_DETAILS_KEY_AND_RES_ID = "PackageVersion.findIdByPackageDetailsKeyAndResId";
public static final String QUERY_FIND_BY_REPO_ID = "PackageVersion.findByRepoId";
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/content/transfer/ResourcePackageDetails.java b/modules/core/domain/src/main/java/org/rhq/core/domain/content/transfer/ResourcePackageDetails.java
index 01e313d..c1440cc 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/content/transfer/ResourcePackageDetails.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/content/transfer/ResourcePackageDetails.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.domain.content.transfer;
import org.rhq.core.domain.configuration.Configuration;
@@ -67,5 +67,3 @@ public class ResourcePackageDetails extends PackageDetails {
this.installationTimestamp = installationTimestamp;
}
}
-
-
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 1e2f6c8..e993082 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
@@ -22,8 +22,11 @@
*/
package org.rhq.core.pc.content;
+import java.io.File;
+import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -45,15 +48,15 @@ import org.rhq.core.clientapi.agent.content.ContentAgentService;
import org.rhq.core.clientapi.server.content.ContentDiscoveryReport;
import org.rhq.core.clientapi.server.content.ContentServerService;
import org.rhq.core.clientapi.server.content.DeletePackagesRequest;
-import org.rhq.core.domain.content.transfer.DeployPackagesResponse;
-import org.rhq.core.domain.content.transfer.RemovePackagesResponse;
+import org.rhq.core.clientapi.server.content.DeployPackagesRequest;
+import org.rhq.core.clientapi.server.content.RetrievePackageBitsRequest;
import org.rhq.core.domain.content.PackageDetailsKey;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.composite.PackageVersionMetadataComposite;
import org.rhq.core.domain.content.transfer.DeployPackageStep;
-import org.rhq.core.clientapi.server.content.DeployPackagesRequest;
+import org.rhq.core.domain.content.transfer.DeployPackagesResponse;
+import org.rhq.core.domain.content.transfer.RemovePackagesResponse;
import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
-import org.rhq.core.clientapi.server.content.RetrievePackageBitsRequest;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.util.PageControl;
@@ -72,6 +75,7 @@ import org.rhq.core.pc.util.LoggingThreadFactory;
import org.rhq.core.pluginapi.content.ContentContext;
import org.rhq.core.pluginapi.content.ContentFacet;
import org.rhq.core.pluginapi.content.ContentServices;
+import org.rhq.core.util.MessageDigestGenerator;
public class ContentManager extends AgentService implements ContainerService, ContentAgentService, ContentServices {
@@ -264,11 +268,11 @@ public class ContentManager extends AgentService implements ContainerService, Co
OutputStream outputStream, boolean resourceExists) {
ContentContextImpl contextImpl = (ContentContextImpl) context; // this has to be of this type, we gave it to the plugin
ContentServerService serverService = getContentServerService();
-
+
//we need to load the content to server before we will start download the content
// it is because of timeout on remoteStreams
serverService.preLoadRemoteContent(contextImpl.getResourceId(), packageDetailsKey);
-
+
outputStream = remoteOutputStream(outputStream);
long count = 0;
if (resourceExists) {
@@ -612,6 +616,8 @@ public class ContentManager extends AgentService implements ContainerService, Co
if (log.isDebugEnabled()) {
log.debug("Found [" + updatedPackageSet.size() + "] new packages for resource id [" + resourceId + "]");
}
+ //from set of new packages discovered, iterate through pkg details to get information for pkg version mapping.
+ updatedPackageSet = updateResourcePackageDetails(updatedPackageSet);
}
// Add new content (yes, existingInstalledPackagesSet is same as details, but use the container's reference)
@@ -641,6 +647,52 @@ public class ContentManager extends AgentService implements ContainerService, Co
return report;
}
+ /** Goes through newly discovered packages and calculates SHA256 for the packages discovered, updating
+ * ResourcePackageDetails in the process.
+ *
+ * @param discoveredPackageSet
+ * @return updated discoveredPackageSet
+ */
+ private Set<ResourcePackageDetails> updateResourcePackageDetails(Set<ResourcePackageDetails> discoveredPackageSet) {
+ if (discoveredPackageSet != null && discoveredPackageSet.size() > 0) {
+ //iterate through pkg details list
+ ResourcePackageDetails list[] = new ResourcePackageDetails[discoveredPackageSet.size()];
+ ResourcePackageDetails[] recentlyDiscoveredArray = discoveredPackageSet.toArray(list);
+
+ for (ResourcePackageDetails detail : recentlyDiscoveredArray) {
+ try {
+ //if the filesize of discovered package is null then it's an exploded and deployed war/ear.
+ if ((detail.getFileSize() == null) || (detail.getFileSize() == 0)) {
+ //when deployed exploded then don't calculate digest but update string with message to that effect.
+ //TODO: is this ok? Once exploded and run at all ... contents could be different.
+ detail.setSHA256("(deployed exploded. no message digest possible)");
+ }
+ //and for each detail where size != null or non empty ... then an un-exploded war/ear
+ if ((detail.getFileSize() != null) || (detail.getFileSize() > 0)) {
+ File localCopy = null;
+ if ((detail.getLocation() != null) && (!detail.getLocation().isEmpty())) {
+ localCopy = new File(detail.getLocation());
+ //calculate md5
+ String sha256 = new MessageDigestGenerator(MessageDigestGenerator.SHA_256)
+ .calcDigestString(localCopy);
+ //and attach it to the report returned to be picked up on server side in merge
+ detail.setSHA256(sha256);
+ }
+ }
+ } catch (IOException iex) {
+ //log exception but move on, discovery happens often. No reason to hold up anything.
+ if (log.isDebugEnabled()) {
+ log.debug("Problem calculating digest of package [" + detail.getName() + "]."
+ + iex.getMessage());
+ }
+ }
+ }
+ discoveredPackageSet.clear();
+ discoveredPackageSet.addAll(Arrays.asList(recentlyDiscoveredArray));
+ }
+ return discoveredPackageSet;
+ }
+
/**
* Returns the <code>ContentFacet</code> for the component associated with the specified resource ID.
*
@@ -704,4 +756,4 @@ public class ContentManager extends AgentService implements ContainerService, Co
}
}
}
-}
+}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/content/RetrieveContentBitsRunner.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/content/RetrieveContentBitsRunner.java
index f260137..e9a82de 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/content/RetrieveContentBitsRunner.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/content/RetrieveContentBitsRunner.java
@@ -1,38 +1,41 @@
- /*
- * 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.content;
import java.io.InputStream;
+
import org.rhq.core.clientapi.server.content.ContentServerService;
import org.rhq.core.clientapi.server.content.ContentServiceResponse;
import org.rhq.core.clientapi.server.content.RetrievePackageBitsRequest;
import org.rhq.core.domain.content.ContentRequestStatus;
+import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
+import org.rhq.core.util.MessageDigestGenerator;
- /**
- * Runnable implementation to allow threaded requests to get a package content.
- *
- * @author Jason Dobies
- */
+/**
+* Runnable implementation to allow threaded requests to get a package content.
+*
+* @author Jason Dobies
+*/
public class RetrieveContentBitsRunner implements Runnable {
// Attributes --------------------------------------------
@@ -78,5 +81,24 @@ public class RetrieveContentBitsRunner implements Runnable {
if (serverService != null) {
serverService.completeRetrievePackageBitsRequest(response, inputStream);
}
+ ResourcePackageDetails pkgDetails = request.getPackageDetails();
+ if ((pkgDetails != null) && ((pkgDetails.getSHA256() == null) || (pkgDetails.getSHA256().trim().isEmpty()))) {
+ InputStream is;
+ try {
+ is = contentManager.performGetPackageBits(request.getResourceId(), request.getPackageDetails());
+ pkgDetails.setSHA256(new MessageDigestGenerator(MessageDigestGenerator.SHA_256).calcDigestString(is));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ if ((pkgDetails != null) && ((pkgDetails.getMD5() == null) || (pkgDetails.getMD5().trim().isEmpty()))) {
+ InputStream is;
+ try {
+ is = contentManager.performGetPackageBits(request.getResourceId(), request.getPackageDetails());
+ pkgDetails.setMD5((new MessageDigestGenerator(MessageDigestGenerator.MD5).calcDigestString(is)));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
}
}
\ No newline at end of file
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/ListPackageHistoryUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/ListPackageHistoryUIBean.java
index 354c60c..845c60d 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/ListPackageHistoryUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/content/ListPackageHistoryUIBean.java
@@ -27,6 +27,9 @@ import javax.faces.model.DataModel;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.rhq.core.clientapi.util.units.UnitNumber;
+import org.rhq.core.clientapi.util.units.UnitsConstants;
+import org.rhq.core.clientapi.util.units.UnitsFormat;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.content.InstalledPackage;
@@ -36,9 +39,6 @@ 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.util.FacesContextUtility;
-import org.rhq.core.clientapi.util.units.UnitsFormat;
-import org.rhq.core.clientapi.util.units.UnitNumber;
-import org.rhq.core.clientapi.util.units.UnitsConstants;
import org.rhq.enterprise.gui.common.framework.PagedDataTableUIBean;
import org.rhq.enterprise.gui.common.paging.PageControlView;
import org.rhq.enterprise.gui.common.paging.PagedListDataModel;
@@ -103,6 +103,7 @@ public class ListPackageHistoryUIBean extends PagedDataTableUIBean {
private List<PackageTableDataValue> toCombinedValues(InstalledPackage current, InstalledPackage old) {
List<PackageTableDataValue> results = new ArrayList<PackageTableDataValue>();
+ // current.getPackageVersion();
results.add(new PackageTableDataValue("Name", current.getPackageVersion().getGeneralPackage().getName(), null));
results.add(new PackageTableDataValue("Version", current.getPackageVersion().getDisplayVersion(),
((old != null) ? old.getPackageVersion().getDisplayVersion() : null)));
@@ -113,18 +114,21 @@ public class ListPackageHistoryUIBean extends PagedDataTableUIBean {
(old != null) ? ((old.getPackageVersion().getFileSize() != null) ? old.getPackageVersion().getFileName()
: null) : null));
- long fileSizeBytes = (current.getPackageVersion().getFileSize() != null) ? current.getPackageVersion().getFileSize() : 0;
- long oldFileSizeBytes = (old != null) ? ((old.getPackageVersion().getFileSize() != null) ? old.getPackageVersion().getFileSize() : 0) : 0;
- results.add(new PackageTableDataValue("File Size",
- UnitsFormat.format(new UnitNumber(fileSizeBytes, UnitsConstants.UNIT_BYTES)).toString(),
- UnitsFormat.format(new UnitNumber(oldFileSizeBytes, UnitsConstants.UNIT_BYTES)).toString()));
+ long fileSizeBytes = (current.getPackageVersion().getFileSize() != null) ? current.getPackageVersion()
+ .getFileSize() : 0;
+ long oldFileSizeBytes = (old != null) ? ((old.getPackageVersion().getFileSize() != null) ? old
+ .getPackageVersion().getFileSize() : 0) : 0;
+ results.add(new PackageTableDataValue("File Size", UnitsFormat.format(
+ new UnitNumber(fileSizeBytes, UnitsConstants.UNIT_BYTES)).toString(), UnitsFormat.format(
+ new UnitNumber(oldFileSizeBytes, UnitsConstants.UNIT_BYTES)).toString()));
results.add(new PackageTableDataValue("SHA256", current.getPackageVersion().getSHA256(), ((old != null) ? old
.getPackageVersion().getSHA256() : null)));
- results.add(new PackageTableDataValue("Installation Date", dateToString(current.getInstallationDate()),
- dateToString((old != null) ? old.getInstallationDate() : null)));
- results.add(new PackageTableDataValue("Owner", (current.getUser() != null) ? current.getUser().toString()
- : null, (old != null) ? ((old.getUser() != null) ? old.getUser().toString() : null) : null));
+ results.add(new PackageTableDataValue("Installation Date", dateToString(current.getPackageVersion()
+ .getFileCreatedDate()), dateToString((old != null) ? old.getPackageVersion().getFileCreatedDate() : null)));
+ //Comment for now. This field is not even in the list of InstalledPackage fields
+ //results.add(new PackageTableDataValue("Owner", (current.getUser() != null) ? current.getUser().toString()
+ // : null, (old != null) ? ((old.getUser() != null) ? old.getUser().toString() : null) : null));
// TODO: figure out how to know if the content is available
/*
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/inventory/resource/CreateNewPackageChildResourceUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/inventory/resource/CreateNewPackageChildResourceUIBean.java
index 16b8896..a55927d 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/inventory/resource/CreateNewPackageChildResourceUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/inventory/resource/CreateNewPackageChildResourceUIBean.java
@@ -23,7 +23,9 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import javax.faces.application.FacesMessage;
import javax.faces.model.SelectItem;
@@ -46,11 +48,14 @@ import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.gui.configuration.ConfigurationMaskingUtility;
import org.rhq.core.gui.util.FacesContextUtility;
+import org.rhq.core.util.MessageDigestGenerator;
import org.rhq.core.util.exception.ThrowableUtil;
import org.rhq.enterprise.gui.legacy.ParamConstants;
import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility;
import org.rhq.enterprise.server.configuration.ConfigurationManagerLocal;
+import org.rhq.enterprise.server.content.ContentManagerBean;
import org.rhq.enterprise.server.content.ContentManagerLocal;
+import org.rhq.enterprise.server.content.ContentUIManagerLocal;
import org.rhq.enterprise.server.resource.ResourceFactoryManagerLocal;
import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal;
import org.rhq.enterprise.server.resource.ResourceTypeNotFoundException;
@@ -78,6 +83,10 @@ public class CreateNewPackageChildResourceUIBean {
private ResourceType resourceType;
private PackageType packageType;
+ private String packageName;
+ private String version = "1.0";//default it to 1.0
+ private int selectedPackageTypeId;
+
private int selectedArchitectureId;
private CreateResourceHistory retryCreateItem;
@@ -105,11 +114,37 @@ public class CreateNewPackageChildResourceUIBean {
uploadUIBean = FacesContextUtility.getManagedBean(UploadNewChildPackageUIBean.class);
UploadItem fileItem = uploadUIBean.getFileItem();
+ //store information about uploaded file for packageDetails as most of it is already available
+ Map<String, String> packageUploadDetails = new HashMap<String, String>();
+ packageUploadDetails.put(ContentManagerBean.UPLOAD_FILE_SIZE, String.valueOf(fileItem.getFileSize()));
+ packageUploadDetails.put(ContentManagerBean.UPLOAD_FILE_INSTALL_DATE, String
+ .valueOf(System.currentTimeMillis()));
+ packageUploadDetails.put(ContentManagerBean.UPLOAD_OWNER, user.getName());
+ packageUploadDetails.put(ContentManagerBean.UPLOAD_FILE_NAME, fileItem.getFileName());
+
+ try {//Easier to implement here than in server side bean. Shouldn't affect performance too much.
+ packageUploadDetails.put(ContentManagerBean.UPLOAD_MD5, new MessageDigestGenerator(
+ MessageDigestGenerator.MD5).calcDigestString(fileItem.getFile()));
+ packageUploadDetails.put(ContentManagerBean.UPLOAD_SHA256, new MessageDigestGenerator(
+ MessageDigestGenerator.SHA_256).calcDigestString(fileItem.getFile()));
+ } catch (IOException e1) {
+ log.warn("Error calculating file digest(s) : " + e1.getMessage());
+ e1.printStackTrace();
+ }
+
// Validate
if ((fileItem == null) || fileItem.getFile() == null) {
FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "A package file must be uploaded");
return null;
}
+ if ((getVersion() == null) || (getVersion().trim().length() == 0)) {//version
+ FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "A package version must be specified.");
+ return null;
+ }
+ if ((getSelectedPackageTypeId() < 0) || (getVersion().trim().length() == 0)) {//type
+ FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "A package type must be specified.");
+ return null;
+ }
ConfigurationManagerLocal configurationManager = LookupUtil.getConfigurationManager();
ConfigurationDefinition pluginConfigurationDefinition = configurationManager
@@ -132,6 +167,9 @@ public class CreateNewPackageChildResourceUIBean {
return OUTCOME_SUCCESS_OR_FAILURE;
}
+ //pull in archictecture selection
+ selectedArchitectureId = getSelectedArchitectureId();
+
// If the type does not support architectures, load the no architecture entity and use that
if (!packageType.isSupportsArchitecture()) {
ContentManagerLocal contentManager = LookupUtil.getContentManager();
@@ -160,9 +198,20 @@ public class CreateNewPackageChildResourceUIBean {
// RHQ-666 - Changed to not request the resource name from the user; simply pass null
// JON 2.0 RC3 - use timestamp versioning; pass null for version
- resourceFactoryManager.createResource(user, parentResource.getId(), getResourceTypeId(), null,
- pluginConfiguration, packageName, null, selectedArchitectureId, deployTimeConfiguration,
- packageContentStream);
+ // resourceFactoryManager.createResource(user, parentResource.getId(), getResourceTypeId(), null,
+ // pluginConfiguration, packageName, null, selectedArchitectureId, deployTimeConfiguration,
+ // packageContentStream);
+ if (packageUploadDetails != null) {
+ resourceFactoryManager.createResource(user, parentResource.getId(), getResourceTypeId(), null,
+ pluginConfiguration, packageName, getVersion(), selectedArchitectureId,
+ deployTimeConfiguration, packageContentStream, packageUploadDetails);
+ } else {
+ resourceFactoryManager.createResource(user, parentResource.getId(), getResourceTypeId(), null,
+ pluginConfiguration, packageName, null, selectedArchitectureId, deployTimeConfiguration,
+ packageContentStream);
+
+ }
+
} catch (Exception e) {
String errorMessages = ThrowableUtil.getAllMessages(e);
FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR,
@@ -355,4 +404,45 @@ public class CreateNewPackageChildResourceUIBean {
ParamConstants.RESOURCE_TYPE_ID_PARAM);
}
}
+
+ public String getPackageName() {
+ return packageName;
+ }
+
+ public void setPackageName(String packageName) {
+ this.packageName = packageName;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public int getSelectedPackageTypeId() {
+ return selectedPackageTypeId;
+ }
+
+ public void setSelectedPackageTypeId(int selectedPackageTypeId) {
+ this.selectedPackageTypeId = selectedPackageTypeId;
+ }
+
+ public SelectItem[] getPackageTypes() {
+ Resource resource = EnterpriseFacesContextUtility.getResource();
+
+ ContentUIManagerLocal contentUIManager = LookupUtil.getContentUIManager();
+ List<PackageType> packageTypes = contentUIManager.getPackageTypes(resource.getResourceType().getId());
+
+ SelectItem[] items = new SelectItem[packageTypes.size()];
+ int itemCounter = 0;
+ for (PackageType packageType : packageTypes) {
+ SelectItem item = new SelectItem(packageType.getId(), packageType.getDisplayName());
+ items[itemCounter++] = item;
+ }
+
+ return items;
+ }
+
}
\ No newline at end of file
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/inventory/create-package-1.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/inventory/create-package-1.xhtml
index 67eebb2..6363600 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/inventory/create-package-1.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/inventory/create-package-1.xhtml
@@ -63,6 +63,37 @@
<h:outputText rendered="#{!ResourceUIBean.permissions.content}"
value="You do not have permissions to upload content"/>
+ <rich:panel >
+
+ <f:facet name="header">Package Version Details</f:facet>
+
+ <input type="hidden" name="packageVersion" value="true"/>
+
+ <table>
+ <tr>
+ <td align="right"><b>Version *</b></td>
+ <td align="left"><h:inputText value="#{CreateNewPackageChildResourceUIBean.version}"/></td>
+ </tr>
+ <tr>
+ <td align="right"><b>Architecture </b></td>
+ <td align="left">
+ <h:selectOneMenu value="#{CreateNewPackageChildResourceUIBean.selectedArchitectureId}">
+ <f:selectItems value="#{CreateNewPackageChildResourceUIBean.architectures}" />
+ </h:selectOneMenu>
+ </td>
+ </tr>
+ <tr>
+ <td align="right"><b>Type *</b></td>
+ <td align="left">
+ <h:selectOneMenu value="#{CreateNewPackageChildResourceUIBean.selectedPackageTypeId}">
+ <f:selectItems value="#{CreateNewPackageChildResourceUIBean.packageTypes}" />
+ </h:selectOneMenu>
+ </td>
+ </tr>
+ </table>
+ </rich:panel>
+
+
<onc:config configurationDefinition="#{CreateNewPackageChildResourceUIBean.configurationDefinition}"
configuration="#{CreateNewPackageChildResourceUIBean.configuration}"
nullConfigurationDefinitionMessage="#{CreateNewPackageChildResourceUIBean.nullConfigurationDefinitionMessage}"
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
index c2c3ccd..bd6d933 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
@@ -111,6 +111,13 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
*/
private static final int REQUEST_TIMEOUT = 1000 * 60 * 60;
+ public static final String UPLOAD_FILE_SIZE = "fileSize";
+ public static final String UPLOAD_FILE_INSTALL_DATE = "fileInstallDate";
+ public static final String UPLOAD_OWNER = "owner";
+ public static final String UPLOAD_FILE_NAME = "fileName";
+ public static final String UPLOAD_MD5 = "md5";
+ public static final String UPLOAD_SHA256 = "sha256";
+
// Attributes --------------------------------------------
private final Log log = LogFactory.getLog(this.getClass());
@@ -165,7 +172,35 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
// The report contains an entire snapshot of packages, so each of these has to be represented
// as an InstalledPackage
+ PackageVersion packageVersion = null;
for (ResourcePackageDetails resourcePackage : report.getDeployedPackages()) {
+
+ //check for pkgs detected on agent side but not mapped correctly
+ String shaValue = resourcePackage.getSHA256();
+ if ((shaValue != null) && (!shaValue.isEmpty())
+ && (shaValue.indexOf("(deployed exploded. no message digest possible)") == -1)) {
+ //if SHA set, but no MD5 then agent updated these packagedetails so we can link
+ //discovered with created
+ String md5Value = resourcePackage.getMD5();
+ if ((md5Value == null) || (md5Value.isEmpty())) {
+ //query for installed packages with SHA256, we'll grab first one. All identical.
+ Query packageDiscoveredQuery = entityManager
+ .createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_SHA);
+ packageDiscoveredQuery.setParameter("sha", shaValue);
+ List<PackageVersion> discoveredPackages = packageDiscoveredQuery.getResultList();
+ if (discoveredPackages.size() > 0) {
+ packageVersion = discoveredPackages.get(0);
+ //now assign PackageVersion details correctly
+ PackageDetailsKey discoveredKey = new PackageDetailsKey(packageVersion.getFileName(),
+ packageVersion.getVersion(), packageVersion.getGeneralPackage().getPackageType().getName(),
+ resourcePackage.getArchitectureName());
+ ResourcePackageDetails retrievedResourcePackage = new ResourcePackageDetails(discoveredKey);
+ //now reassign the resourcePackage to use this newly retrieved id.
+ resourcePackage = retrievedResourcePackage;
+ }
+ }
+ }
+
// Load the overall package (used in a few places later in this loop)
Query packageQuery = entityManager.createNamedQuery(Package.QUERY_FIND_BY_NAME_PKG_TYPE_RESOURCE_TYPE);
packageQuery.setFlushMode(FlushModeType.COMMIT);
@@ -192,7 +227,7 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
List<PackageVersion> existingPackageVersionList = packageVersionQuery.getResultList();
- PackageVersion packageVersion = null;
+ // PackageVersion packageVersion = null;
if (existingPackageVersionList.size() > 0) {
packageVersion = existingPackageVersionList.get(0);
}
@@ -1216,22 +1251,8 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
PackageVersion newPackageVersion = new PackageVersion(existingPackage, version, architecture);
newPackageVersion.setDisplayName(existingPackage.getName());
- // TODO: THIS IS VERY BAD - MUST FIX - DO NOT SLURP THE ENTIRE FILE IN MEMORY - USE JDBC STREAMING
- // Write the content into the newly created package version. This may eventually move, but for now we'll just
- // use the byte array in the package version to store the bits.
- byte[] packageBits;
- try {
- packageBits = StreamUtil.slurp(packageBitStream);
- } catch (RuntimeException re) {
- throw new RuntimeException("Error reading in the package file", re);
- }
+ PackageBits bits = loadPackageBits(packageBitStream);
- PackageBits bits = new PackageBits();
- try {
- bits.setBits(packageBits);
- } catch (Exception e) {
- log.error("Error savinf the package.", e);
- }
newPackageVersion.setPackageBits(bits);
newPackageVersion = persistOrMergePackageVersionSafely(newPackageVersion);
@@ -1489,4 +1510,107 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
return result;
}
+
+ /** Does much of same functionality as createPackageVersion, but uses same named query
+ * as the agent side discovery mechanism, and passes in additional parameters available
+ * when file has been uploaded via the UI.
+ */
+ @Override
+ public PackageVersion getUploadedPackageVersion(String packageName, int packageTypeId, String version,
+ int architectureId, InputStream packageBitStream, Map<String, String> packageUploadDetails,
+ int newResourceTypeId) {
+
+ PackageVersion packageVersion = null;
+
+ //default version to 1.0 if is null, not provided for any reason.
+ if ((version == null) || (version.trim().isEmpty())) {
+ version = "1.0";
+ }
+
+ // See if package version already exists for the resource package
+ Query packageVersionQuery = entityManager.createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_DETAILS_KEY);
+ packageVersionQuery.setFlushMode(FlushModeType.COMMIT);
+ packageVersionQuery.setParameter("packageName", packageName);
+ PackageType packageType = contentManager.getResourceCreationPackageType(newResourceTypeId);
+ packageVersionQuery.setParameter("packageTypeName", packageType.getName());
+ packageVersionQuery.setParameter("resourceTypeId", newResourceTypeId);
+
+ Architecture architecture = entityManager.find(Architecture.class, architectureId);
+ packageVersionQuery.setParameter("architectureName", architecture.getName());
+ packageVersionQuery.setParameter("version", version);
+
+ // Result of the query should be either 0 or 1
+ List<PackageVersion> existingPackageVersionList = packageVersionQuery.getResultList();
+
+ if (existingPackageVersionList.size() > 0) {
+ packageVersion = existingPackageVersionList.get(0);
+ }
+
+ Package existingPackage = null;
+
+ Query packageQuery = entityManager.createNamedQuery(Package.QUERY_FIND_BY_NAME_PKG_TYPE_ID);
+ packageQuery.setParameter("name", packageName);
+ packageQuery.setParameter("packageTypeId", packageTypeId);
+ List<Package> existingPackageList = packageQuery.getResultList();
+
+ if (existingPackageList.size() == 0) {
+ // If the package doesn't exist, create that here
+ existingPackage = new Package(packageName, packageType);
+ existingPackage = persistOrMergePackageSafely(existingPackage);
+ } else {
+ existingPackage = existingPackageList.get(0);
+ }
+
+ //initialize package version if not already
+ if (packageVersion == null) {
+ packageVersion = new PackageVersion(existingPackage, version, architecture);
+ packageVersion.setDisplayName(existingPackage.getName());
+ entityManager.persist(packageVersion);
+ }
+
+ //get the data and persist/merge packageVersion
+ PackageBits bits = loadPackageBits(packageBitStream);
+ packageVersion.setPackageBits(bits);
+
+ //populate extra details, persist
+ if (packageUploadDetails != null) {
+ packageVersion.setFileCreatedDate(Long.valueOf(packageUploadDetails
+ .get(ContentManagerBean.UPLOAD_FILE_INSTALL_DATE)));
+ packageVersion.setFileName(packageUploadDetails.get(ContentManagerBean.UPLOAD_FILE_NAME));
+ packageVersion.setFileSize(Long.valueOf(packageUploadDetails.get(ContentManagerBean.UPLOAD_FILE_SIZE)));
+ packageVersion.setMD5(packageUploadDetails.get(ContentManagerBean.UPLOAD_MD5));
+ packageVersion.setSHA256(packageUploadDetails.get(ContentManagerBean.UPLOAD_SHA256));
+ }
+ entityManager.merge(packageVersion);
+
+ return packageVersion;
+
+ }
+
+ /** Pulls in package bits from the stream. Currently inefficient.
+ *
+ * @param packageBitStream
+ * @return PackageBits ref populated.
+ */
+ private PackageBits loadPackageBits(InputStream packageBitStream) {
+ PackageBits bits = null;
+ // TODO: THIS IS VERY BAD - MUST FIX - DO NOT SLURP THE ENTIRE FILE IN MEMORY - USE JDBC STREAMING
+ // Write the content into the newly created package version. This may eventually move, but for now we'll just
+ // use the byte array in the package version to store the bits.
+ byte[] packageBits;
+ try {
+ packageBits = StreamUtil.slurp(packageBitStream);
+ } catch (RuntimeException re) {
+ throw new RuntimeException("Error reading in the package file", re);
+ }
+
+ bits = new PackageBits();
+ try {
+ bits.setBits(packageBits);
+ entityManager.persist(bits);
+ } catch (Exception e) {
+ log.error("Error saving the package.", e);
+ }
+ return bits;
+ }
}
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerHelper.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerHelper.java
index 7656d93..9d4a4bc 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerHelper.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerHelper.java
@@ -95,6 +95,7 @@ public class ContentManagerHelper {
details.setMetadata(packageVersion.getMetadata());
details.setSHA256(packageVersion.getSHA256());
details.setShortDescription(packageVersion.getShortDescription());
+ details.setInstallationTimestamp(packageVersion.getFileCreatedDate());
return details;
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java
index 22f69aa..fc128a4 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerLocal.java
@@ -20,13 +20,13 @@ package org.rhq.enterprise.server.content;
import java.io.InputStream;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import javax.ejb.Local;
+import org.rhq.core.clientapi.server.content.ContentDiscoveryReport;
import org.rhq.core.clientapi.server.content.ContentServiceResponse;
-import org.rhq.core.domain.content.transfer.DeployPackagesResponse;
-import org.rhq.core.domain.content.transfer.RemovePackagesResponse;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.content.Architecture;
import org.rhq.core.domain.content.ContentServiceRequest;
@@ -35,8 +35,9 @@ import org.rhq.core.domain.content.Package;
import org.rhq.core.domain.content.PackageDetailsKey;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.PackageVersion;
-import org.rhq.core.clientapi.server.content.ContentDiscoveryReport;
import org.rhq.core.domain.content.transfer.DeployPackageStep;
+import org.rhq.core.domain.content.transfer.DeployPackagesResponse;
+import org.rhq.core.domain.content.transfer.RemovePackagesResponse;
import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
import org.rhq.core.domain.criteria.InstalledPackageCriteria;
import org.rhq.core.domain.criteria.PackageVersionCriteria;
@@ -210,6 +211,10 @@ public interface ContentManagerLocal {
PackageVersion createPackageVersion(String packageName, int packageTypeId, String version, int architectureId,
InputStream packageBitStream);
+ PackageVersion getUploadedPackageVersion(String packageName, int packageTypeId, String version,
+ int architectureId, InputStream packageBitStream, Map<String, String> packageUploadDetails,
+ int newResourceTypeId);
+
/**
* Very simple method that persists the given package version within its own transaction.
*
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerBean.java
index 65ccce7..8b0e4d6 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerBean.java
@@ -22,6 +22,7 @@ import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Calendar;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import javax.ejb.EJB;
@@ -483,6 +484,14 @@ public class ResourceFactoryManagerBean implements ResourceFactoryManagerLocal,
public void createResource(Subject user, int parentResourceId, int newResourceTypeId, String newResourceName,
Configuration pluginConfiguration, String packageName, String packageVersionNumber, Integer architectureId,
Configuration deploymentTimeConfiguration, InputStream packageBitStream) {
+ createResource(user, parentResourceId, newResourceTypeId, newResourceName, pluginConfiguration, packageName,
+ packageVersionNumber, architectureId, deploymentTimeConfiguration, packageBitStream, null);
+ }
+
+ public void createResource(Subject user, int parentResourceId, int newResourceTypeId, String newResourceName,
+ Configuration pluginConfiguration, String packageName, String packageVersionNumber, Integer architectureId,
+ Configuration deploymentTimeConfiguration, InputStream packageBitStream,
+ Map<String, String> packageUploadDetails) {
log.info("Received call to create package backed resource under parent [" + parentResourceId + "]");
Resource resource = entityManager.find(Resource.class, parentResourceId);
@@ -510,9 +519,15 @@ public class ResourceFactoryManagerBean implements ResourceFactoryManagerLocal,
// default to no required architecture
architectureId = (null != architectureId) ? architectureId : contentManager.getNoArchitecture().getId();
- // Create package and package version
- PackageVersion packageVersion = contentManager.createPackageVersion(packageName, newPackageType.getId(),
- packageVersionNumber, architectureId, packageBitStream);
+ // Create/locate package and package version
+ PackageVersion packageVersion = null;
+ if (packageUploadDetails == null) {
+ packageVersion = contentManager.createPackageVersion(packageName, newPackageType.getId(),
+ packageVersionNumber, architectureId, packageBitStream);
+ } else {
+ packageVersion = contentManager.getUploadedPackageVersion(packageName, newPackageType.getId(),
+ packageVersionNumber, architectureId, packageBitStream, packageUploadDetails, newResourceTypeId);
+ }
// Persist in separate transaction so it is committed immediately, before the request is sent to the agent
CreateResourceHistory persistedHistory = resourceFactoryManager.persistCreateHistory(user, parentResourceId,
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerLocal.java
index f5d267e..ea3784d 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerLocal.java
@@ -19,6 +19,7 @@
package org.rhq.enterprise.server.resource;
import java.io.InputStream;
+import java.util.Map;
import javax.ejb.Local;
@@ -83,6 +84,11 @@ public interface ResourceFactoryManagerLocal {
Configuration pluginConfiguration, String packageName, String packageVersion, Integer architectureId,
Configuration deploymentTimeConfiguration, InputStream packageBitStream);
+ void createResource(Subject user, int parentResourceId, int newResourceTypeId, String newResourceName,
+ Configuration pluginConfiguration, String packageName, String packageVersion, Integer architectureId,
+ Configuration deploymentTimeConfiguration, InputStream packageBitStream,
+ Map<String, String> packageUploadDetails);
+
// Internal Utilities --------------------------------------------
/**