use of org.jboss.fuse.patch.management.PatchData in project fuse-karaf by jboss-fuse.
the class GitConflictResolutionIT method cherryPickConflict.
@Test
public void cherryPickConflict() throws Exception {
prepareChanges2();
RevWalk rw = new RevWalk(git.getRepository());
git.checkout().setName("custom").setCreateBranch(false).call();
ObjectId commit = git.getRepository().resolve("patched");
CherryPickResult result = git.cherryPick().include(commit).call();
RevCommit cMaster = rw.parseCommit(git.getRepository().resolve("master"));
RevCommit cCustom = rw.parseCommit(git.getRepository().resolve("custom"));
RevCommit cPatched = rw.parseCommit(git.getRepository().resolve("patched"));
assertThat(result.getStatus(), equalTo(CherryPickResult.CherryPickStatus.CONFLICTING));
Map<String, IndexDiff.StageState> conflicts = git.status().call().getConflictingStageState();
assertThat(conflicts.size(), equalTo(2));
assertThat(conflicts.get("etc/org.ops4j.pax.logging.cfg"), equalTo(IndexDiff.StageState.BOTH_MODIFIED));
assertThat(conflicts.get("etc/file.properties"), equalTo(IndexDiff.StageState.BOTH_MODIFIED));
new GitPatchManagementServiceImpl().handleCherryPickConflict(null, git, result, git.getRepository().parseCommit(commit), true, PatchKind.NON_ROLLUP, "x", false, false);
RevCommit cMerged = git.commit().setMessage("resolved").call();
// we have 4 commits (7349224 is a custom change that's conflicting with "patched" branch):
/*
* 92a9ad8 - (HEAD -> custom) resolved
* 7349224 - custom etc/org.ops4j.pax.logging.cfg
| * 5777547 - (patched) patched etc/org.ops4j.pax.logging.cfg
|/
* 306f328 - (master) original etc/org.ops4j.pax.logging.cfg
*/
FileWriter writer = new FileWriter("target/report.html");
PatchData pd = new PatchData("my-patch-id2");
PatchResult patchResult = PatchResult.load(pd, getClass().getResourceAsStream("/conflicts/example1/fuse-karaf-7.0.0.fuse-000160.patch.result"));
DiffUtils.generateDiffReport(new Patch(pd, null), patchResult, git, new HashSet<>(), cMaster, cCustom, cPatched, cMerged, writer);
writer.close();
}
use of org.jboss.fuse.patch.management.PatchData in project fuse-karaf by jboss-fuse.
the class PatchServiceImplTest method testLoadWithPrereqs.
@Test
public void testLoadWithPrereqs() throws IOException {
PatchServiceImpl service = createMockServiceImpl();
PatchData pd = PatchData.load(getClass().getClassLoader().getResourceAsStream("test-with-prereq.patch"));
assertEquals(2, pd.getBundles().size());
assertEquals(1, pd.getRequirements().size());
assertTrue(pd.getRequirements().contains("prereq1"));
assertNull(pd.getVersionRange("mvn:io.fabric8.test/test2/1.0.0"));
}
use of org.jboss.fuse.patch.management.PatchData 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.PatchData in project fuse-karaf by jboss-fuse.
the class GitPatchManagementServiceImpl method loadPatch.
/**
* Retrieves patch information from existing file
* @param patchDescriptor existing file with patch descriptor (<code>*.patch</code> file)
* @param details whether the returned {@link Patch} should contain {@link ManagedPatch} information
* @return
* @throws IOException
*/
private Patch loadPatch(File patchDescriptor, boolean details) throws IOException {
Patch p = new Patch();
if (!patchDescriptor.exists() || !patchDescriptor.isFile()) {
return null;
}
PatchData data = PatchData.load(new FileInputStream(patchDescriptor));
p.setPatchData(data);
File patchDirectory = new File(patchesDir, FilenameUtils.getBaseName(patchDescriptor.getName()));
if (patchDirectory.exists() && patchDirectory.isDirectory()) {
// not every descriptor downloaded may be a ZIP file, not every patch has content
data.setPatchDirectory(patchDirectory);
File featureOverridesLocation = new File(patchDirectory, "org.apache.karaf.features.xml");
if (featureOverridesLocation.isFile()) {
// them available during all patch operations
try {
FeaturesProcessing featureOverrides = InternalUtils.loadFeatureProcessing(featureOverridesLocation, null);
List<String> overrides = new LinkedList<>();
if (featureOverrides.getFeatureReplacements().getReplacements() != null) {
featureOverrides.getFeatureReplacements().getReplacements().forEach(of -> overrides.add(of.getFeature().getId()));
}
data.setFeatureOverrides(overrides);
} catch (Exception e) {
Activator.log(LogService.LOG_WARNING, "Problem loading org.apache.karaf.features.xml from patch " + data.getId() + ": " + e.getMessage());
}
}
}
data.setPatchLocation(patchesDir);
File resultFile = new File(patchesDir, FilenameUtils.getBaseName(patchDescriptor.getName()) + ".patch.result");
if (resultFile.exists() && resultFile.isFile()) {
PatchResult result = PatchResult.load(data, new FileInputStream(resultFile));
p.setResult(result);
}
if (details) {
ManagedPatch mp = gitPatchRepository.getManagedPatch(data.getId());
p.setManagedPatch(mp);
}
return p;
}
use of org.jboss.fuse.patch.management.PatchData in project fuse-karaf by jboss-fuse.
the class GitPatchManagementServiceImpl method checkPendingPatches.
@Override
public void checkPendingPatches() {
File[] pendingPatches = patchesDir.listFiles(pathname -> pathname.exists() && pathname.getName().endsWith(".pending"));
if (pendingPatches == null || pendingPatches.length == 0) {
return;
}
final String dataCache = systemContext.getProperty("org.osgi.framework.storage");
for (File pending : pendingPatches) {
try {
Pending what = Pending.valueOf(FileUtils.readFileToString(pending, "UTF-8"));
final String prefix = what == Pending.ROLLUP_INSTALLATION ? "install" : "rollback";
String name = pending.getName().replaceFirst("\\.pending$", "");
if (isStandaloneChild()) {
if (name.endsWith("." + System.getProperty("karaf.name") + ".patch")) {
name = name.replaceFirst("\\." + System.getProperty("karaf.name"), "");
} else {
continue;
}
}
File patchFile = new File(pending.getParentFile(), name);
if (!patchFile.isFile()) {
Activator.log(LogService.LOG_INFO, "Ignoring patch result file: " + patchFile.getName());
continue;
}
PatchData patchData = PatchData.load(new FileInputStream(patchFile));
Patch patch = loadPatch(new PatchDetailsRequest(patchData.getId()));
String dataFilesName = patchData.getId() + ".datafiles";
if (isStandaloneChild()) {
dataFilesName = patchData.getId() + "." + System.getProperty("karaf.name") + ".datafiles";
}
final File dataFilesBackupDir = new File(pending.getParentFile(), dataFilesName);
final Properties backupProperties = new Properties();
FileInputStream inStream = new FileInputStream(new File(dataFilesBackupDir, "backup-" + prefix + ".properties"));
backupProperties.load(inStream);
Utils.closeQuietly(inStream);
// maybe one of those bundles has data directory to restore?
for (Bundle b : systemContext.getBundles()) {
if (b.getSymbolicName() != null) {
String key = String.format("%s$$%s", stripSymbolicName(b.getSymbolicName()), b.getVersion().toString());
if (backupProperties.containsKey(key)) {
String backupDirName = backupProperties.getProperty(key);
File backupDir = new File(dataFilesBackupDir, prefix + "/" + backupDirName + "/data");
restoreDataDirectory(dataCache, b, backupDir);
// we no longer want to restore this dir
backupProperties.remove(key);
}
}
}
// 2. We can however have more bundle data backups - we'll restore them after each bundle
// is INSTALLED and we'll use listener for this
BundleListener bundleListener = new SynchronousBundleListener() {
@Override
public void bundleChanged(BundleEvent event) {
Bundle b = event.getBundle();
if (event.getType() == BundleEvent.INSTALLED && b.getSymbolicName() != null) {
String key = String.format("%s$$%s", stripSymbolicName(b.getSymbolicName()), b.getVersion().toString());
if (backupProperties.containsKey(key)) {
String backupDirName = backupProperties.getProperty(key);
File backupDir = new File(dataFilesBackupDir, prefix + "/" + backupDirName + "/data");
restoreDataDirectory(dataCache, b, backupDir);
}
}
}
};
systemContext.addBundleListener(bundleListener);
pendingPatchesListeners.put(patchData.getId(), bundleListener);
} catch (Exception e) {
Activator.log(LogService.LOG_ERROR, null, e.getMessage(), e, true);
}
}
}
Aggregations