use of org.apache.karaf.features.internal.model.Features in project karaf by apache.
the class Builder method bootStage.
private Set<Feature> bootStage(Profile bootProfile, Profile startupEffective) throws Exception {
LOGGER.info("Boot stage");
//
// Handle boot profiles
//
Profile bootOverlay = Profiles.getOverlay(bootProfile, allProfiles, environment);
Profile bootEffective = Profiles.getEffective(bootOverlay, false);
// Load startup repositories
Map<String, Features> bootRepositories = loadRepositories(manager, bootEffective.getRepositories(), true);
// Compute startup feature dependencies
Set<Feature> allBootFeatures = new HashSet<>();
for (Features repo : bootRepositories.values()) {
allBootFeatures.addAll(repo.getFeature());
}
// Generate a global feature
Map<String, Dependency> generatedDep = new HashMap<>();
Feature generated = new Feature();
generated.setName(UUID.randomUUID().toString());
// Add feature dependencies
for (String dependency : bootEffective.getFeatures()) {
Dependency dep = generatedDep.get(dependency);
if (dep == null) {
dep = createDependency(dependency);
generated.getFeature().add(dep);
generatedDep.put(dep.getName(), dep);
}
dep.setDependency(false);
}
// Add bundles
for (String location : bootEffective.getBundles()) {
location = location.replace("profile:", "file:etc/");
Bundle bun = new Bundle();
bun.setLocation(location);
generated.getBundle().add(bun);
}
Features rep = new Features();
rep.setName(UUID.randomUUID().toString());
rep.getRepository().addAll(bootEffective.getRepositories());
rep.getFeature().add(generated);
allBootFeatures.add(generated);
Downloader downloader = manager.createDownloader();
// Compute startup feature dependencies
Set<Feature> bootFeatures = new HashSet<>();
addFeatures(allBootFeatures, generated.getName(), bootFeatures, true);
for (Feature feature : bootFeatures) {
// the feature is a startup feature, updating startup.properties file
LOGGER.info(" Feature " + feature.getId() + " is defined as a boot feature");
// add the feature in the system folder
Set<String> locations = new HashSet<>();
for (Bundle bundle : feature.getBundle()) {
if (!ignoreDependencyFlag || !bundle.isDependency()) {
locations.add(bundle.getLocation().trim());
}
}
for (Conditional cond : feature.getConditional()) {
for (Bundle bundle : cond.getBundle()) {
if (!ignoreDependencyFlag || !bundle.isDependency()) {
locations.add(bundle.getLocation().trim());
}
}
}
// Build optional features and known prerequisites
Map<String, List<String>> prereqs = new HashMap<>();
prereqs.put("blueprint:", Arrays.asList("deployer", "aries-blueprint"));
prereqs.put("spring:", Arrays.asList("deployer", "spring"));
prereqs.put("wrap:", Arrays.asList("wrap"));
prereqs.put("war:", Arrays.asList("war"));
for (String location : locations) {
installArtifact(downloader, location);
for (Map.Entry<String, List<String>> entry : prereqs.entrySet()) {
if (location.startsWith(entry.getKey())) {
for (String prereq : entry.getValue()) {
Dependency dep = generatedDep.get(prereq);
if (dep == null) {
dep = new Dependency();
dep.setName(prereq);
generated.getFeature().add(dep);
generatedDep.put(dep.getName(), dep);
}
dep.setPrerequisite(true);
}
}
}
}
List<Content> contents = new ArrayList<>();
contents.add(feature);
contents.addAll(feature.getConditional());
for (Content content : contents) {
// Install config files
for (Config config : content.getConfig()) {
if (config.isExternal()) {
installArtifact(downloader, config.getValue().trim());
}
}
for (ConfigFile configFile : content.getConfigfile()) {
installArtifact(downloader, configFile.getLocation().trim());
}
// Extract configs
for (Config config : content.getConfig()) {
if (pidMatching(config.getName())) {
Path configFile = etcDirectory.resolve(config.getName() + ".cfg");
LOGGER.info(" adding config file: {}", homeDirectory.relativize(configFile));
if (config.isExternal()) {
downloader.download(config.getValue().trim(), provider -> {
synchronized (provider) {
Files.copy(provider.getFile().toPath(), configFile, StandardCopyOption.REPLACE_EXISTING);
}
});
} else {
Files.write(configFile, config.getValue().getBytes());
}
}
}
}
// Install libraries
List<String> libraries = new ArrayList<>();
for (Library library : feature.getLibraries()) {
String lib = library.getLocation() + ";type:=" + library.getType() + ";export:=" + library.isExport() + ";delegate:=" + library.isDelegate();
libraries.add(lib);
}
Path configPropertiesPath = etcDirectory.resolve("config.properties");
Properties configProperties = new Properties(configPropertiesPath.toFile());
downloadLibraries(downloader, configProperties, libraries, " ");
downloader.await();
// Reformat clauses
reformatClauses(configProperties, Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA);
reformatClauses(configProperties, Constants.FRAMEWORK_BOOTDELEGATION);
configProperties.save();
}
// If there are bundles to install, we can't use the boot features only
// so keep the generated feature
Path featuresCfgFile = etcDirectory.resolve("org.apache.karaf.features.cfg");
if (!generated.getBundle().isEmpty()) {
File output = etcDirectory.resolve(rep.getName() + ".xml").toFile();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
JaxbUtil.marshal(rep, baos);
ByteArrayInputStream bais;
String repoUrl;
if (karafVersion == KarafVersion.v24) {
String str = baos.toString();
str = str.replace("http://karaf.apache.org/xmlns/features/v1.3.0", "http://karaf.apache.org/xmlns/features/v1.2.0");
str = str.replaceAll(" dependency=\".*?\"", "");
str = str.replaceAll(" prerequisite=\".*?\"", "");
for (Feature f : rep.getFeature()) {
for (Dependency d : f.getFeature()) {
if (d.isPrerequisite()) {
if (!startupEffective.getFeatures().contains(d.getName())) {
LOGGER.warn("Feature " + d.getName() + " is a prerequisite and should be installed as a startup feature.");
}
}
}
}
bais = new ByteArrayInputStream(str.getBytes());
repoUrl = "file:etc/" + output.getName();
} else {
bais = new ByteArrayInputStream(baos.toByteArray());
repoUrl = "file:${karaf.home}/etc/" + output.getName();
}
Files.copy(bais, output.toPath());
Properties featuresProperties = new Properties(featuresCfgFile.toFile());
featuresProperties.put(FEATURES_REPOSITORIES, repoUrl);
featuresProperties.put(FEATURES_BOOT, generated.getName());
featuresProperties.save();
} else {
String repos = getRepos(rep);
String boot = getBootFeatures(generatedDep);
Properties featuresProperties = new Properties(featuresCfgFile.toFile());
featuresProperties.put(FEATURES_REPOSITORIES, repos);
featuresProperties.put(FEATURES_BOOT, boot);
reformatClauses(featuresProperties, FEATURES_REPOSITORIES);
reformatClauses(featuresProperties, FEATURES_BOOT);
featuresProperties.save();
}
downloader.await();
return allBootFeatures;
}
use of org.apache.karaf.features.internal.model.Features in project karaf by apache.
the class BuilderTest method consistencyReport.
// @Test
// @Ignore("no need to run this test")
public void consistencyReport() {
Map<String, Features> features = new LinkedHashMap<>();
Builder builder = new Builder();
File[] uris = new File("src/test/resources/repositories").listFiles((dir, name) -> name.endsWith(".xml"));
if (uris != null) {
for (File f : uris) {
features.put(f.getName(), new RepositoryImpl(f.toURI(), false).getFeaturesInternal());
}
}
builder.generateConsistencyReport(features, new File("target/consistency.xml"), false);
builder.generateConsistencyReport(features, new File("target/consistency-full.xml"), true);
}
use of org.apache.karaf.features.internal.model.Features in project karaf by apache.
the class VerifyMojo method doExecute.
protected void doExecute() throws MojoExecutionException {
System.setProperty("karaf.home", "target/karaf");
System.setProperty("karaf.data", "target/karaf/data");
Hashtable<String, String> properties = new Hashtable<>();
if (additionalMetadata != null) {
try (Reader reader = new FileReader(additionalMetadata)) {
Properties metadata = new Properties();
metadata.load(reader);
for (Enumeration<?> e = metadata.propertyNames(); e.hasMoreElements(); ) {
Object key = e.nextElement();
Object val = metadata.get(key);
properties.put(key.toString(), val.toString());
}
} catch (IOException e) {
throw new MojoExecutionException("Unable to load additional metadata from " + additionalMetadata, e);
}
}
Set<String> allDescriptors = new LinkedHashSet<>();
if (descriptors == null) {
if (framework == null) {
framework = Collections.singleton("framework");
}
descriptors = new LinkedHashSet<>();
if (framework.contains("framework")) {
allDescriptors.add("mvn:org.apache.karaf.features/framework/" + getVersion("org.apache.karaf.features:framework") + "/xml/features");
}
allDescriptors.add("file:" + project.getBuild().getDirectory() + "/feature/feature.xml");
} else {
allDescriptors.addAll(descriptors);
if (framework != null && framework.contains("framework")) {
allDescriptors.add("mvn:org.apache.karaf.features/framework/" + getVersion("org.apache.karaf.features:framework") + "/xml/features");
}
}
// TODO: allow using external configuration ?
ScheduledExecutorService executor = Executors.newScheduledThreadPool(8);
DownloadManager manager = new CustomDownloadManager(resolver, executor);
final Map<String, Features> repositories;
Map<String, List<Feature>> allFeatures = new HashMap<>();
try {
repositories = loadRepositories(manager, allDescriptors);
for (String repoUri : repositories.keySet()) {
List<Feature> features = repositories.get(repoUri).getFeature();
// Ack features to inline configuration files urls
for (Feature feature : features) {
for (org.apache.karaf.features.internal.model.Bundle bi : feature.getBundle()) {
String loc = bi.getLocation();
String nloc = null;
if (loc.contains("file:")) {
for (ConfigFile cfi : feature.getConfigfile()) {
if (cfi.getFinalname().substring(1).equals(loc.substring(loc.indexOf("file:") + "file:".length()))) {
nloc = cfi.getLocation();
}
}
}
if (nloc != null) {
Field field = bi.getClass().getDeclaredField("location");
field.setAccessible(true);
field.set(bi, loc.substring(0, loc.indexOf("file:")) + nloc);
}
}
}
allFeatures.put(repoUri, features);
}
} catch (Exception e) {
throw new MojoExecutionException("Unable to load features descriptors", e);
}
List<Feature> featuresToTest = new ArrayList<>();
if (verifyTransitive) {
for (List<Feature> features : allFeatures.values()) {
featuresToTest.addAll(features);
}
} else {
for (String uri : descriptors) {
featuresToTest.addAll(allFeatures.get(uri));
}
}
if (features != null && !features.isEmpty()) {
Pattern pattern = getPattern(features);
for (Iterator<Feature> iterator = featuresToTest.iterator(); iterator.hasNext(); ) {
Feature feature = iterator.next();
String id = feature.getName() + "/" + feature.getVersion();
if (!pattern.matcher(id).matches()) {
iterator.remove();
}
}
}
for (String fmk : framework) {
properties.put("feature.framework." + fmk, fmk);
}
Set<String> successes = new LinkedHashSet<>();
Set<String> ignored = new LinkedHashSet<>();
Map<String, Exception> failures = new LinkedHashMap<>();
for (Feature feature : featuresToTest) {
String id = feature.getId();
try {
verifyResolution(new CustomDownloadManager(resolver, executor), repositories, Collections.singleton(id), properties);
successes.add(id);
getLog().info("Verification of feature " + id + " succeeded");
} catch (Exception e) {
if (e.getCause() instanceof ResolutionException || !getLog().isDebugEnabled()) {
getLog().warn(e.getMessage());
} else {
getLog().warn(e);
}
failures.put(id, e);
if ("first".equals(fail)) {
throw e;
}
}
for (Conditional cond : feature.getConditional()) {
Set<String> ids = new LinkedHashSet<>();
ids.add(feature.getId());
ids.addAll(cond.getCondition());
String cid = String.join("+", ids);
try {
verifyResolution(manager, repositories, ids, properties);
successes.add(cid);
getLog().info("Verification of feature " + cid + " succeeded");
} catch (Exception e) {
if (ignoreMissingConditions && e.getCause() instanceof ResolutionException) {
boolean ignore = true;
Collection<Requirement> requirements = ((ResolutionException) e.getCause()).getUnresolvedRequirements();
for (Requirement req : requirements) {
ignore &= (IdentityNamespace.IDENTITY_NAMESPACE.equals(req.getNamespace()) && ResourceUtils.TYPE_FEATURE.equals(req.getAttributes().get("type")) && cond.getCondition().contains(req.getAttributes().get(IdentityNamespace.IDENTITY_NAMESPACE).toString()));
}
if (ignore) {
ignored.add(cid);
getLog().warn("Feature resolution failed for " + cid + "\nMessage: " + e.getCause().getMessage());
continue;
}
}
if (e.getCause() instanceof ResolutionException || !getLog().isDebugEnabled()) {
getLog().warn(e.getMessage());
} else {
getLog().warn(e);
}
failures.put(cid, e);
if ("first".equals(fail)) {
throw e;
}
}
}
}
int nb = successes.size() + ignored.size() + failures.size();
getLog().info("Features verified: " + nb + ", failures: " + failures.size() + ", ignored: " + ignored.size());
if (!failures.isEmpty()) {
getLog().info("Failures: " + String.join(", ", failures.keySet()));
}
if ("end".equals(fail) && !failures.isEmpty()) {
throw new MojoExecutionException("Verification failures", new MultiException("Verification failures", new ArrayList<>(failures.values())));
}
}
use of org.apache.karaf.features.internal.model.Features in project karaf by apache.
the class VerifyMojo method loadRepositories.
public static Map<String, Features> loadRepositories(DownloadManager manager, Set<String> uris) throws Exception {
final Map<String, Features> loaded = new HashMap<>();
final Downloader downloader = manager.createDownloader();
for (String repository : uris) {
downloader.download(repository, new DownloadCallback() {
@Override
public void downloaded(final StreamProvider provider) throws Exception {
try (InputStream is = provider.open()) {
Features featuresModel = JaxbUtil.unmarshal(provider.getUrl(), is, false);
synchronized (loaded) {
loaded.put(provider.getUrl(), featuresModel);
for (String innerRepository : featuresModel.getRepository()) {
downloader.download(innerRepository, this);
}
}
}
}
});
}
downloader.await();
return loaded;
}
use of org.apache.karaf.features.internal.model.Features in project karaf by apache.
the class Builder method installStage.
private void installStage(Profile installedProfile, Set<Feature> allBootFeatures, FeaturesProcessor processor) throws Exception {
LOGGER.info("Install stage");
//
// Handle installed profiles
//
Profile installedOverlay = Profiles.getOverlay(installedProfile, allProfiles, environment);
Profile installedEffective = Profiles.getEffective(installedOverlay, false);
Downloader downloader = manager.createDownloader();
// Load startup repositories
LOGGER.info(" Loading installed repositories");
Map<String, Features> installedRepositories = loadRepositories(manager, installedEffective.getRepositories(), true, processor);
// Compute startup feature dependencies
Set<Feature> allInstalledFeatures = new HashSet<>();
for (Features repo : installedRepositories.values()) {
allInstalledFeatures.addAll(repo.getFeature());
}
// Add boot features for search
allInstalledFeatures.addAll(allBootFeatures);
FeatureSelector selector = new FeatureSelector(allInstalledFeatures);
Set<Feature> installedFeatures = selector.getMatching(installedEffective.getFeatures());
ArtifactInstaller installer = new ArtifactInstaller(systemDirectory, downloader, blacklist);
for (Feature feature : installedFeatures) {
if (feature.isBlacklisted()) {
LOGGER.info(" Feature " + feature.getId() + " is blacklisted, ignoring");
continue;
}
LOGGER.info(" Feature {} is defined as an installed feature", feature.getId());
for (Bundle bundle : feature.getBundle()) {
if (!ignoreDependencyFlag || !bundle.isDependency()) {
installer.installArtifact(bundle);
}
}
// Install config files
for (ConfigFile configFile : feature.getConfigfile()) {
installer.installArtifact(configFile.getLocation().trim());
}
for (Conditional cond : feature.getConditional()) {
if (cond.isBlacklisted()) {
LOGGER.info(" Conditionial " + cond.getConditionId() + " is blacklisted, ignoring");
}
for (Bundle bundle : cond.getBundle()) {
if (!ignoreDependencyFlag || !bundle.isDependency()) {
installer.installArtifact(bundle);
}
}
}
}
for (String location : installedEffective.getBundles()) {
installer.installArtifact(location);
}
downloader.await();
}
Aggregations