in profile/src/main/java/org/apache/karaf/profile/assembly/Builder.java [1745:1931]
private Set<Feature> bootStage(Profile bootProfile, Profile startupEffective, FeaturesProcessor processor) 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
LOGGER.info(" Loading boot repositories");
Map<String, Features> bootRepositories = loadRepositories(manager, bootEffective.getRepositories(), true, processor);
// 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<>();
generatedBootFeatureName = UUID.randomUUID().toString();
Feature generated = new Feature();
generated.setName(generatedBootFeatureName);
// Add feature dependencies
for (String nameOrPattern : bootEffective.getFeatures()) {
// KARAF-5273: feature may be a pattern
for (String dependency : FeatureSelector.getMatchingFeatures(nameOrPattern, bootRepositories.values())) {
Dependency dep = generatedDep.get(dependency);
if (dep == null) {
dep = createDependency(dependency);
generated.getFeature().add(dep);
generatedDep.put(dep.getName(), dep);
}
dep.setDependency(false);
dep.setPrerequisite(firstStageBootFeatures.contains(dep.getName()) || firstStageBootFeatures.contains(
nameOrPattern));
}
}
// Add bundles
for (String location : bootEffective.getBundles()) {
location = location.replace("profile:", "file:etc/");
int intLevel = -100;
if (location.contains(START_LEVEL)) {
//extract start-level for this bundle
String level = location.substring(location.indexOf(START_LEVEL));
level = level.substring(START_LEVEL.length() + 1);
if (level.startsWith("\"")) {
level = level.substring(1, level.length() - 1);
}
intLevel = Integer.parseInt(level);
LOGGER.debug("bundle start-level: " + level);
location = location.substring(0, location.indexOf(START_LEVEL) - 1);
LOGGER.debug("new bundle location after strip start-level: " + location);
}
Bundle bun = new Bundle();
if (intLevel > 0) {
bun.setStartLevel(intLevel);
}
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
FeatureSelector selector = new FeatureSelector(allBootFeatures);
Set<Feature> bootFeatures = selector.getMatching(singletonList(generated.getName()));
for (Feature feature : bootFeatures) {
if (feature.isBlacklisted()) {
LOGGER.info(" Feature " + feature.getId() + " is blacklisted, ignoring");
continue;
}
LOGGER.info(" Feature " + feature.getId() + " is defined as a boot feature");
// add the feature in the system folder
Set<BundleInfo> bundleInfos = new HashSet<>();
for (Bundle bundle : feature.getBundle()) {
if (!ignoreDependencyFlag || !bundle.isDependency()) {
bundleInfos.add(bundle);
}
}
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()) {
bundleInfos.add(bundle);
}
}
}
// 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:", Collections.singletonList("wrap"));
prereqs.put("war:", Collections.singletonList("war"));
ArtifactInstaller installer = new ArtifactInstaller(systemDirectory, downloader, blacklist);
for (BundleInfo bundleInfo : bundleInfos) {
installer.installArtifact(bundleInfo);
for (Map.Entry<String, List<String>> entry : prereqs.entrySet()) {
if (bundleInfo.getLocation().trim().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);
}
}
}
}
new ConfigInstaller(etcDirectory, pidsToExtract)
.installConfigs(feature, downloader, installer);
// 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.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;
}