use of org.jboss.fuse.patch.management.Artifact in project fuse-karaf by jboss-fuse.
the class KarafFeaturesPropertiesFileResolver method uris.
/**
* Returns a map of groupId/artifactId -> artifact
* @param uriStringsFromPatch
* @return
*/
private Map<String, Artifact> uris(List<String> uriStringsFromPatch) {
Map<String, Artifact> result = new LinkedHashMap<>();
for (String uri : uriStringsFromPatch) {
Artifact a = Utils.mvnurlToArtifact(uri, true);
if (a == null) {
continue;
}
String ga = String.format("%s/%s", a.getGroupId(), a.getArtifactId());
result.put(ga, a);
}
return result;
}
use of org.jboss.fuse.patch.management.Artifact in project fuse-karaf by jboss-fuse.
the class GitPatchManagementServiceImpl method updateOverrides.
/**
* <p>Updates existing <code>etc/org.apache.karaf.features.xml</code> after installing single {@link PatchKind#NON_ROLLUP}
* patch. Both bundle and feature replacements are taken into account.</p>
* @param workTree
* @param patches
*/
private void updateOverrides(File workTree, List<PatchData> patches) throws IOException {
File overrides = new File(workTree, "etc/" + featureProcessing);
File versions = new File(workTree, "etc/" + featureProcessingVersions);
// we need two different versions to detect whether the version is externalized in etc/versions.properties
FeaturesProcessing fp1;
FeaturesProcessing fp2;
if (overrides.isFile()) {
fp1 = InternalUtils.loadFeatureProcessing(overrides, versions);
fp2 = InternalUtils.loadFeatureProcessing(overrides, null);
} else {
fp1 = fp2 = new FeaturesProcessing();
}
List<BundleReplacements.OverrideBundle> br1 = fp1.getBundleReplacements().getOverrideBundles();
List<BundleReplacements.OverrideBundle> br2 = fp2.getBundleReplacements().getOverrideBundles();
org.apache.felix.utils.properties.Properties props = null;
boolean propertyChanged = false;
if (versions.isFile()) {
props = new org.apache.felix.utils.properties.Properties(versions);
}
for (PatchData patchData : patches) {
for (String bundle : patchData.getBundles()) {
Artifact artifact = mvnurlToArtifact(bundle, true);
if (artifact == null) {
continue;
}
// Compute patch bundle version and range
Version oVer = Utils.getOsgiVersion(artifact.getVersion());
String vr = patchData.getVersionRange(bundle);
if (vr != null && !vr.isEmpty()) {
artifact.setVersion(vr);
} else {
Version v1 = new Version(oVer.getMajor(), oVer.getMinor(), 0);
Version v2 = new Version(oVer.getMajor(), oVer.getMinor() + 1, 0);
artifact.setVersion(new VersionRange(VersionRange.LEFT_CLOSED, v1, v2, VersionRange.RIGHT_OPEN).toString());
}
// features processing file may contain e.g.,:
// <bundle originalUri="mvn:org.jboss.fuse/fuse-zen/[1,2)/war"
// replacement="mvn:org.jboss.fuse/fuse-zen/${version.test2}/war" mode="maven" />
// patch descriptor contains e.g.,:
// bundle.0 = mvn:org.jboss.fuse/fuse-zen/1.2.0/war
// bundle.0.range = [1.1,1.2)
//
// we will always match by replacement attribute, ignoring originalUri - the patch descriptor must be
// prepared correctly
int idx = 0;
BundleReplacements.OverrideBundle existing = null;
// we'll examine model with resolved property placeholders, but modify the other one
for (BundleReplacements.OverrideBundle override : br1) {
LocationPattern lp = new LocationPattern(artifact.getCanonicalUri());
if (lp.matches(override.getReplacement())) {
// we've found existing override in current etc/org.apache.karaf.features.xml
existing = br2.get(idx);
break;
}
idx++;
}
if (existing == null) {
existing = new BundleReplacements.OverrideBundle();
br2.add(existing);
}
// either update existing override or configure a new one
existing.setMode(BundleReplacements.BundleOverrideMode.MAVEN);
existing.setOriginalUri(artifact.getCanonicalUri());
String replacement = existing.getReplacement();
if (replacement != null && replacement.contains("${")) {
// assume that we have existing replacement="mvn:org.jboss.fuse/fuse-zen/${version.test2}/war"
// so we can't change the replacement and instead we have to update properties
String property = null;
String value = null;
if (replacement.startsWith("mvn:")) {
LocationPattern existingReplacement = new LocationPattern(replacement);
property = existingReplacement.getVersionString().substring(existingReplacement.getVersionString().indexOf("${") + 2);
if (property.contains("}")) {
// it should...
property = property.substring(0, property.indexOf("}"));
}
LocationPattern newReplacement = new LocationPattern(bundle);
value = newReplacement.getVersionString();
} else {
// non-mvn? then we can't determine the version from non-mvn: URI...
}
// we are not changing replacement - we'll have to update properties
if (props != null && property != null) {
props.setProperty(property, value);
propertyChanged = true;
}
} else {
existing.setReplacement(bundle);
}
}
// feature overrides
File featureOverridesLocation = new File(patchData.getPatchDirectory(), "org.apache.karaf.features.xml");
if (featureOverridesLocation.isFile()) {
FeaturesProcessing featureOverrides = InternalUtils.loadFeatureProcessing(featureOverridesLocation, null);
Map<String, FeatureReplacements.OverrideFeature> patchedFeatures = new LinkedHashMap<>();
List<FeatureReplacements.OverrideFeature> mergedOverrides = new LinkedList<>();
featureOverrides.getFeatureReplacements().getReplacements().forEach(of -> patchedFeatures.put(of.getFeature().getId(), of));
fp2.getFeatureReplacements().getReplacements().forEach(of -> {
FeatureReplacements.OverrideFeature override = patchedFeatures.remove(of.getFeature().getId());
mergedOverrides.add(override == null ? of : override);
});
// add remaining
mergedOverrides.addAll(patchedFeatures.values());
fp2.getFeatureReplacements().getReplacements().clear();
fp2.getFeatureReplacements().getReplacements().addAll(mergedOverrides);
}
}
if (propertyChanged) {
props.save();
}
InternalUtils.saveFeatureProcessing(fp2, overrides, versions);
}
use of org.jboss.fuse.patch.management.Artifact in project fuse-karaf by jboss-fuse.
the class GitPatchManagementServiceImpl method trackPatch.
/**
* <p>This method turns static information about a patch into managed patch - i.e., patch added to git
* repository.</p>
*
* <p>Such patch has its own branch ready to be merged (when patch is installed). Before installation we can verify
* the patch,
* examine the content, check the differences, conflicts and perform simulation (merge to temporary branch created
* from main patch branch)</p>
*
* <p>The strategy is as follows:<ul>
* <li><em>main patch branch</em> in git repository tracks all changes (from baselines, patch-management
* system, patches and user changes)</li>
* <li>Initially there are 3 commits: baseline, patch-management bundle installation in etc/startup.properties,
* initial user changes</li>
* <li>We always <strong>tag the baseline commit</strong></li>
* <li>User changes may be applied each time Framework is restarted</li>
* <li>When we add a patch, we create <em>named branch</em> from the <strong>latest baseline</strong></li>
* <li>When we install a patch, we <strong>merge</strong> the patch branch with the <em>main patch branch</em>
* (that may contain additional user changes)</li>
* <li>When patch ZIP contains new baseline distribution, after merging patch branch, we tag the merge commit
* in <em>main patch branch</em> branch as new baseline</li>
* <li>Branches for new patches will then be created from new baseline commit</li>
* </ul></p>
* @param patchData
* @return
*/
@Override
public Patch trackPatch(PatchData patchData) throws PatchException {
try {
awaitInitialization();
} catch (InterruptedException e) {
throw new PatchException("Patch management system is not ready yet");
}
Git fork = null;
try {
Git mainRepository = gitPatchRepository.findOrCreateMainGitRepository();
// prepare single fork for all the below operations
fork = gitPatchRepository.cloneRepository(mainRepository, true);
// 1. find current baseline
RevTag latestBaseline = gitPatchRepository.findCurrentBaseline(fork);
if (latestBaseline == null) {
throw new PatchException("Can't find baseline distribution tracked in patch management. Is patch management initialized?");
}
// the commit from the patch should be available from main patch branch
RevCommit commit = new RevWalk(fork.getRepository()).parseCommit(latestBaseline.getObject());
// create dedicated branch for this patch. We'll immediately add patch content there so we can examine the
// changes from the latest baseline
gitPatchRepository.checkout(fork).setCreateBranch(true).setName("patch-" + patchData.getId()).setStartPoint(commit).call();
// copy patch resources (but not maven artifacts from system/ or repository/) to working copy
if (patchData.getPatchDirectory() != null) {
boolean removeTargetDir = patchData.isRollupPatch();
copyManagedDirectories(patchData.getPatchDirectory(), fork.getRepository().getWorkTree(), removeTargetDir, false, false);
}
// add the changes
fork.add().addFilepattern(".").call();
// remove the deletes
for (String missing : fork.status().call().getMissing()) {
fork.rm().addFilepattern(missing).call();
}
// record information about other "patches" included in added patch (e.g., Fuse patch
// may contain patches to instance:create based containers in standalone mode)
StringWriter sw = new StringWriter();
sw.append("# tags for patches included in \"").append(patchData.getId()).append("\"\n");
for (String bundle : patchData.getBundles()) {
// containers that want to patch:install patches added in root containers
if (bundle.contains("mvn:org.apache.karaf.instance/org.apache.karaf.instance.core/")) {
Artifact a = Utils.mvnurlToArtifact(bundle, true);
if (a != null) {
sw.append(String.format(EnvType.STANDALONE_CHILD.getBaselineTagFormat(), a.getVersion())).append("\n");
}
break;
}
}
FileUtils.write(new File(fork.getRepository().getWorkTree(), "patch-info.txt"), sw.toString(), "UTF-8");
fork.add().addFilepattern(".").call();
// commit the changes (patch vs. baseline) to patch branch
gitPatchRepository.prepareCommit(fork, String.format("[PATCH] Tracking patch %s", patchData.getId())).call();
// push the patch branch
gitPatchRepository.push(fork, "patch-" + patchData.getId());
// for instance:create child containers
trackBaselinesForChildContainers(fork);
return new Patch(patchData, gitPatchRepository.getManagedPatch(patchData.getId()));
} catch (IOException | GitAPIException e) {
throw new PatchException(e.getMessage(), e);
} finally {
if (fork != null) {
gitPatchRepository.closeRepository(fork, true);
}
}
}
use of org.jboss.fuse.patch.management.Artifact in project fuse-karaf by jboss-fuse.
the class GitPatchManagementServiceImpl method gatherOverrides.
/**
* Returns list of bundle updates (maven coordinates) from HF/P patch that should be preserved during
* installation of R patch
* @param hfPatchId ID of patch that was detected to be HF patch installed previously (before R patch just being installed)
* @param patch R patch which is currently being installed
* @return an artificial {@link PatchData} with a list of maven URIs for bundles that are newer in previous P-patches than the ones in currently installed R-patch
*/
private PatchData gatherOverrides(String hfPatchId, Patch patch) {
Patch hf = loadPatch(new PatchDetailsRequest(hfPatchId));
List<String> bundles = new LinkedList<>();
Map<String, String> ranges = new LinkedHashMap<>();
if (hf != null && hf.getPatchData() != null) {
for (String bundle : hf.getPatchData().getBundles()) {
bundles.add(bundle);
String versionRange = hf.getPatchData().getVersionRange(bundle);
if (versionRange != null && !versionRange.trim().equals("")) {
ranges.put(bundle, versionRange);
}
}
// leave only these artifacts that are in newer version than in R patch being installed
if (patch != null && patch.getPatchData() != null) {
Map<String, Artifact> cache = new HashMap<>();
for (String bu : patch.getPatchData().getBundles()) {
Artifact rPatchArtifact = Utils.mvnurlToArtifact(bu, true);
if (rPatchArtifact != null) {
cache.put(String.format("%s:%s", rPatchArtifact.getGroupId(), rPatchArtifact.getArtifactId()), rPatchArtifact);
}
}
for (String bu : hf.getPatchData().getBundles()) {
Artifact hfPatchArtifact = Utils.mvnurlToArtifact(bu, true);
if (hfPatchArtifact != null) {
String key = String.format("%s:%s", hfPatchArtifact.getGroupId(), hfPatchArtifact.getArtifactId());
if (cache.containsKey(key)) {
Version hfVersion = Utils.getOsgiVersion(hfPatchArtifact.getVersion());
Version rVersion = Utils.getOsgiVersion(cache.get(key).getVersion());
if (rVersion.compareTo(hfVersion) >= 0) {
bundles.remove(bu);
ranges.remove(bu);
}
}
}
}
}
}
return new PatchData(null, null, bundles, null, ranges, null, null);
}
use of org.jboss.fuse.patch.management.Artifact in project fuse-karaf by jboss-fuse.
the class GitPatchManagementServiceImpl method determineVersion.
/**
* Return version of product used, but probably based on different karafHome
* @param home
* @return
*/
private String determineVersion(File home) {
if (env == EnvType.STANDALONE) {
File versions = new File(home, "etc/version.properties");
if (versions.exists() && versions.isFile()) {
Properties props = new Properties();
FileInputStream fis = null;
try {
fis = new FileInputStream(versions);
props.load(fis);
return props.getProperty("version");
} catch (IOException e) {
Activator.log(LogService.LOG_ERROR, null, e.getMessage(), e, true);
return null;
} finally {
Utils.closeQuietly(fis);
}
} else {
Activator.log2(LogService.LOG_ERROR, "Can't find etc/version.properties");
}
} else {
// for child container we have to be more careful and not examine root container's etc/version.properties!
File startup = new File(home, "etc/startup.properties");
if (startup.exists() && startup.isFile()) {
Properties props = new Properties();
FileInputStream fis = null;
try {
fis = new FileInputStream(startup);
props.load(fis);
for (String key : props.stringPropertyNames()) {
if (key.contains("org.apache.karaf.features/org.apache.karaf.features.core/")) {
Artifact artifact = Utils.mvnurlToArtifact(key, true);
if (artifact != null) {
return artifact.getVersion();
}
}
}
} catch (IOException e) {
Activator.log(LogService.LOG_ERROR, null, e.getMessage(), e, true);
return null;
} finally {
Utils.closeQuietly(fis);
}
} else {
Activator.log2(LogService.LOG_ERROR, "Can't find etc/startup.properties file in child container");
}
}
return null;
}
Aggregations