use of org.apache.karaf.features.LocationPattern in project karaf by apache.
the class Blacklist method compileClauses.
/**
* Extracts blacklisting clauses related to bundles, features and repositories and changes them to more
* usable form.
*/
private void compileClauses() {
for (Clause c : clauses) {
String type = c.getAttribute(BLACKLIST_TYPE);
if (type == null) {
String url = c.getAttribute(BLACKLIST_URL);
if (url != null || c.getName().startsWith("mvn:")) {
// some special rules from etc/blacklisted.properties
type = TYPE_BUNDLE;
} else {
type = TYPE_FEATURE;
}
}
String location;
switch(type) {
case TYPE_REPOSITORY:
location = c.getName();
if (c.getAttribute(BLACKLIST_URL) != null) {
location = c.getAttribute(BLACKLIST_URL);
}
if (location == null) {
// should not happen?
LOG.warn("Repository blacklist URI is empty. Ignoring.");
} else {
try {
repositoryBlacklist.add(new LocationPattern(location));
} catch (IllegalArgumentException e) {
LOG.warn("Problem parsing repository blacklist URI \"" + location + "\": " + e.getMessage() + ". Ignoring.");
}
}
break;
case TYPE_FEATURE:
try {
featureBlacklist.add(new FeaturePattern(c.toString()));
} catch (IllegalArgumentException e) {
LOG.warn("Problem parsing blacklisted feature identifier \"" + c.toString() + "\": " + e.getMessage() + ". Ignoring.");
}
break;
case TYPE_BUNDLE:
location = c.getName();
if (c.getAttribute(BLACKLIST_URL) != null) {
location = c.getAttribute(BLACKLIST_URL);
}
if (location == null) {
// should not happen?
LOG.warn("Bundle blacklist URI is empty. Ignoring.");
} else {
try {
bundleBlacklist.add(new LocationPattern(location));
} catch (IllegalArgumentException e) {
LOG.warn("Problem parsing bundle blacklist URI \"" + location + "\": " + e.getMessage() + ". Ignoring.");
}
}
break;
}
}
}
use of org.apache.karaf.features.LocationPattern in project karaf by apache.
the class FeaturesProcessing method postUnmarshall.
/**
* <p>Perform <em>compilation</em> of rules declared in feature processing XML file.</p>
* <p>Additional blacklist and overrides definitions will be added to this model</p>
*
* @param blacklist additional {@link Blacklist} definition with lower priority
* @param overrides additional overrides definition with lower priority
*/
public void postUnmarshall(Blacklist blacklist, Set<String> overrides) {
// configure Blacklist tool
List<String> blacklisted = new LinkedList<>();
// compile blacklisted repository URIs (from XML and additional blacklist)
blacklist.getRepositoryBlacklist().stream().map(LocationPattern::getOriginalUri).forEach(uri -> getBlacklistedRepositories().add(uri));
for (String repositoryURI : getBlacklistedRepositories()) {
try {
blacklistedRepositoryLocationPatterns.add(new LocationPattern(repositoryURI));
blacklisted.add(repositoryURI + ";" + Blacklist.BLACKLIST_TYPE + "=" + Blacklist.TYPE_REPOSITORY);
} catch (IllegalArgumentException e) {
LOG.warn("Can't parse blacklisted repository location pattern: " + repositoryURI + ". Ignoring.");
}
}
// add external blacklisted features to this model
blacklist.getFeatureBlacklist().forEach(fb -> getBlacklistedFeatures().add(new BlacklistedFeature(fb.getName(), fb.getVersion())));
blacklisted.addAll(getBlacklistedFeatures().stream().map(bf -> bf.getName() + ";" + Blacklist.BLACKLIST_TYPE + "=" + Blacklist.TYPE_FEATURE + (bf.getVersion() == null ? "" : ";" + FeaturePattern.RANGE + "=\"" + bf.getVersion() + "\"")).collect(Collectors.toList()));
// add external blacklisted bundle URIs to this model
blacklist.getBundleBlacklist().stream().map(LocationPattern::getOriginalUri).forEach(uri -> getBlacklistedBundles().add(uri));
blacklisted.addAll(getBlacklistedBundles().stream().map(bl -> bl + ";" + Blacklist.BLACKLIST_TYPE + "=" + Blacklist.TYPE_BUNDLE).collect(Collectors.toList()));
this.blacklist = new Blacklist(blacklisted);
// verify bundle override definitions (from XML and additional overrides)
bundleReplacements.getOverrideBundles().addAll(parseOverridesClauses(overrides));
for (Iterator<BundleReplacements.OverrideBundle> iterator = bundleReplacements.getOverrideBundles().iterator(); iterator.hasNext(); ) {
BundleReplacements.OverrideBundle overrideBundle = iterator.next();
if (overrideBundle.getOriginalUri() == null) {
// we have to derive it from replacement - as with etc/overrides.properties entry
if (overrideBundle.getMode() == BundleReplacements.BundleOverrideMode.MAVEN) {
LOG.warn("Can't override bundle in maven mode without explicit original URL. Switching to osgi mode.");
overrideBundle.setMode(BundleReplacements.BundleOverrideMode.OSGI);
}
String originalUri = calculateOverridenURI(overrideBundle.getReplacement(), null);
if (originalUri != null) {
overrideBundle.setOriginalUri(originalUri);
} else {
iterator.remove();
continue;
}
}
try {
overrideBundle.compile();
} catch (MalformedURLException e) {
LOG.warn("Can't parse override URL location pattern: " + overrideBundle.getOriginalUri() + ". Ignoring.");
iterator.remove();
}
}
}
use of org.apache.karaf.features.LocationPattern 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.apache.karaf.features.LocationPattern in project karaf by apache.
the class Builder method generateConsistencyReport.
/**
* Produces human readable XML with <em>feature consistency report</em>.
* @param repositories
* @param result
*/
public void generateConsistencyReport(Map<String, Features> repositories, File result, boolean full) {
Map<String, String> featureId2repository = new HashMap<>();
// list of feature IDs containing given bundle URIs
Map<String, Set<String>> bundle2featureId = new TreeMap<>(new URIAwareComparator());
// map of groupId/artifactId to full URI list to detect "duplicates"
Map<String, List<String>> ga2uri = new TreeMap<>();
Set<String> haveDuplicates = new HashSet<>();
// collect closure of bundles and features
repositories.forEach((name, features) -> {
if (full || !features.isBlacklisted()) {
features.getFeature().forEach(feature -> {
if (full || !feature.isBlacklisted()) {
featureId2repository.put(feature.getId(), name);
feature.getBundle().forEach(bundle -> {
// normal bundles of feature
bundle2featureId.computeIfAbsent(bundle.getLocation().trim(), k -> new TreeSet<>()).add(feature.getId());
});
feature.getConditional().forEach(cond -> {
cond.asFeature().getBundles().forEach(bundle -> {
// conditional bundles of feature
bundle2featureId.computeIfAbsent(bundle.getLocation().trim(), k -> new TreeSet<>()).add(feature.getId());
});
});
}
});
}
});
// collect bundle URIs - for now, only wrap:mvn: and mvn: are interesting
bundle2featureId.keySet().forEach(uri -> {
String originalUri = uri;
if (uri.startsWith("wrap:mvn:")) {
uri = uri.substring(5);
if (uri.indexOf(";") > 0) {
uri = uri.substring(0, uri.indexOf(";"));
}
if (uri.indexOf("$") > 0) {
uri = uri.substring(0, uri.indexOf("$"));
}
}
if (uri.startsWith("mvn:")) {
try {
LocationPattern pattern = new LocationPattern(uri);
String ga = String.format("%s/%s", pattern.getGroupId(), pattern.getArtifactId());
ga2uri.computeIfAbsent(ga, k -> new LinkedList<>()).add(originalUri);
} catch (IllegalArgumentException ignored) {
/*
<!-- hibernate-validator-osgi-karaf-features-5.3.4.Final-features.xml -->
<feature name="hibernate-validator-paranamer" version="5.3.4.Final">
<feature>hibernate-validator</feature>
<bundle>wrap:mvn:com.thoughtworks.paranamer:paranamer:2.8</bundle>
</feature>
*/
}
}
});
ga2uri.values().forEach(l -> {
if (l.size() > 1) {
haveDuplicates.addAll(l);
}
});
if (result == null) {
return;
}
try (BufferedWriter writer = new BufferedWriter(new FileWriter(result))) {
writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
writer.write("<?xml-stylesheet type=\"text/xsl\" href=\"bundle-report.xslt\"?>\n");
writer.write("<consistency-report xmlns=\"urn:apache:karaf:consistency:1.0\">\n");
writer.write(" <duplicates>\n");
ga2uri.forEach((key, uris) -> {
if (uris.size() > 1) {
try {
writer.write(String.format(" <duplicate ga=\"%s\">\n", key));
for (String uri : uris) {
writer.write(String.format(" <bundle uri=\"%s\">\n", sanitize(uri)));
for (String fid : bundle2featureId.get(uri)) {
writer.write(String.format(" <feature repository=\"%s\">%s</feature>\n", featureId2repository.get(fid), fid));
}
writer.write(" </bundle>\n");
}
writer.write(" </duplicate>\n");
} catch (IOException e) {
}
}
});
writer.write(" </duplicates>\n");
writer.write(" <bundles>\n");
for (String uri : bundle2featureId.keySet()) {
writer.write(String.format(" <bundle uri=\"%s\" duplicate=\"%b\">\n", sanitize(uri), haveDuplicates.contains(uri)));
for (String fid : bundle2featureId.get(uri)) {
writer.write(String.format(" <feature>%s</feature>\n", fid));
}
writer.write(" </bundle>\n");
}
writer.write(" </bundles>\n");
writer.write("</consistency-report>\n");
} catch (IOException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
use of org.apache.karaf.features.LocationPattern in project karaf by apache.
the class Builder method processBlacklist.
/**
* Checks existing and configured blacklisting definitions
* @param initialProfile
* @return
* @throws IOException
*/
private Blacklist processBlacklist(Profile initialProfile) throws IOException {
Blacklist existingBlacklist = null;
Blacklist blacklist = new Blacklist();
Path existingBLacklistedLocation = etcDirectory.resolve("blacklisted.properties");
if (existingBLacklistedLocation.toFile().isFile()) {
LOGGER.warn("Found {} which is deprecated, please use new feature processor configuration.", homeDirectory.relativize(existingBLacklistedLocation));
existingBlacklist = new Blacklist(Files.readAllLines(existingBLacklistedLocation));
}
for (String br : blacklistedRepositoryURIs) {
// from Maven/Builder configuration
try {
blacklist.blacklistRepository(new LocationPattern(br));
} catch (IllegalArgumentException e) {
LOGGER.warn("Blacklisted features XML repository URI is invalid: {}, ignoring", br);
}
}
for (LocationPattern br : initialProfile.getBlacklistedRepositories()) {
// from profile configuration
blacklist.blacklistRepository(br);
}
for (String bf : blacklistedFeatureIdentifiers) {
// from Maven/Builder configuration
blacklist.blacklistFeature(new FeaturePattern(bf));
}
for (FeaturePattern bf : initialProfile.getBlacklistedFeatures()) {
// from profile configuration
blacklist.blacklistFeature(bf);
}
for (String bb : blacklistedBundleURIs) {
// from Maven/Builder configuration
try {
blacklist.blacklistBundle(new LocationPattern(bb));
} catch (IllegalArgumentException e) {
LOGGER.warn("Blacklisted bundle URI is invalid: {}, ignoring", bb);
}
}
for (LocationPattern bb : initialProfile.getBlacklistedBundles()) {
// from profile configuration
blacklist.blacklistBundle(bb);
}
if (existingBlacklist != null) {
blacklist.merge(existingBlacklist);
}
return blacklist;
}
Aggregations