@Override
public void handleDiscoveredPackage(Resource resource, ResourcePackageDetails discoveredPackage,
Set<InstalledPackage> doomedPackages, long timestamp) {
Package generalPackage = null;
PackageVersion packageVersion = null;
// 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);
// these form a query for a unique package
packageQuery.setParameter("name", discoveredPackage.getName());
packageQuery.setParameter("packageTypeName", discoveredPackage.getPackageTypeName());
packageQuery.setParameter("resourceTypeId", resource.getResourceType().getId());
List<Package> resultPackages = packageQuery.getResultList();
if (resultPackages.size() > 0) {
generalPackage = resultPackages.get(0); // returns at most 1 Package
}
// If the package exists see if package version already exists
if (null != generalPackage) {
Query packageVersionQuery = entityManager.createNamedQuery(PackageVersion.QUERY_FIND_BY_PACKAGE_VERSION);
packageVersionQuery.setFlushMode(FlushModeType.COMMIT);
packageVersionQuery.setParameter("packageId", generalPackage.getId());
packageVersionQuery.setParameter("version", discoveredPackage.getVersion());
List<PackageVersion> resultPackageVersions = packageVersionQuery.getResultList();
// Although the PV unique index is (package,version,arch) in reality the architecture portion is
// superfluous. The version is now basically unique (it's basically an enhanced SHA) so it means that
// two different architectures would basically have two different versions anyway. So, despite the
// DB model, this query will return at most 1 PV.
if (resultPackageVersions.size() > 0) {
packageVersion = resultPackageVersions.get(0); // returns at most 1 PackageVersion
}
}
// If we didn't find a package version for this deployed package, we will need to create it
if (null == packageVersion) {
if (null == generalPackage) {
Query packageTypeQuery = entityManager
.createNamedQuery(PackageType.QUERY_FIND_BY_RESOURCE_TYPE_ID_AND_NAME);
packageTypeQuery.setFlushMode(FlushModeType.COMMIT);
packageTypeQuery.setParameter("typeId", resource.getResourceType().getId());
packageTypeQuery.setParameter("name", discoveredPackage.getPackageTypeName());
PackageType packageType = (PackageType) packageTypeQuery.getSingleResult();
generalPackage = new Package(discoveredPackage.getName(), packageType);
generalPackage = persistOrMergePackageSafely(generalPackage);
}
// Create a new package version and attach to the general package
Architecture packageArchitecture;
Query architectureQuery = entityManager.createNamedQuery(Architecture.QUERY_FIND_BY_NAME);
architectureQuery.setFlushMode(FlushModeType.COMMIT);
architectureQuery.setParameter("name", discoveredPackage.getArchitectureName());
// We don't have an architecture enum, so it's very possible the plugin will pass in a crap string here.
// If the architecture is unknown just use "noarch" and log a warning. We don't want to blow up
// just because a plugin didn't set this correctly, as architecture is nearly useless at this point.
try {
packageArchitecture = (Architecture) architectureQuery.getSingleResult();
} catch (Exception e) {
LOG.warn("Discovered Architecture [" + discoveredPackage.getArchitectureName()
+ "] not found for package [" + discoveredPackage.getName()
+ "]. Setting to [noarch] and continuing...");
packageArchitecture = getNoArchitecture();
}
packageVersion = new PackageVersion(generalPackage, discoveredPackage.getVersion(), packageArchitecture);
packageVersion.setDisplayName(discoveredPackage.getDisplayName());
packageVersion.setDisplayVersion(discoveredPackage.getDisplayVersion());
packageVersion.setFileCreatedDate(discoveredPackage.getFileCreatedDate());
packageVersion.setFileName(discoveredPackage.getFileName());
packageVersion.setFileSize(discoveredPackage.getFileSize());
packageVersion.setLicenseName(discoveredPackage.getLicenseName());
packageVersion.setLicenseVersion(discoveredPackage.getLicenseVersion());
packageVersion.setLongDescription(discoveredPackage.getLongDescription());
packageVersion.setMD5(discoveredPackage.getMD5());
packageVersion.setMetadata(discoveredPackage.getMetadata());
packageVersion.setSHA256(discoveredPackage.getSHA256());
packageVersion.setShortDescription(discoveredPackage.getShortDescription());
packageVersion.setExtraProperties(discoveredPackage.getExtraProperties());
packageVersion = persistOrMergePackageVersionSafely(packageVersion);
} else {
// At this point we know a PackageVersion existed previously in the DB already. If it is already
// installed to the resource then we are done, and we can remove it from the doomed package list.
for (Iterator<InstalledPackage> i = doomedPackages.iterator(); i.hasNext();) {
InstalledPackage ip = i.next();
PackageVersion pv = ip.getPackageVersion();
if (pv.getId() == packageVersion.getId()) {
i.remove();
return;
}
}
}