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@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@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@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@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@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@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 --------------------------------------------
/**
rhq-commits@lists.fedorahosted.org