Search in sources :

Example 16 with Feature

use of org.apache.karaf.features.internal.model.Feature in project karaf by apache.

the class GenerateDescriptorMojo method writeFeatures.

/*
     * Write all project dependencies as feature
     */
private void writeFeatures(PrintStream out) throws ArtifactResolutionException, ArtifactNotFoundException, IOException, JAXBException, SAXException, ParserConfigurationException, XMLStreamException, MojoExecutionException {
    getLog().info("Generating feature descriptor file " + outputFile.getAbsolutePath());
    //read in an existing feature.xml
    ObjectFactory objectFactory = new ObjectFactory();
    Features features;
    if (inputFile.exists()) {
        filter(inputFile, filteredInputFile);
        features = readFeaturesFile(filteredInputFile);
    } else {
        features = objectFactory.createFeaturesRoot();
    }
    if (features.getName() == null) {
        features.setName(project.getArtifactId());
    }
    Feature feature = null;
    for (Feature test : features.getFeature()) {
        if (test.getName().equals(primaryFeatureName)) {
            feature = test;
        }
    }
    if (feature == null) {
        feature = objectFactory.createFeature();
        feature.setName(primaryFeatureName);
    }
    if (!feature.hasVersion()) {
        feature.setVersion(project.getArtifact().getBaseVersion());
    }
    if (feature.getDescription() == null) {
        feature.setDescription(project.getName());
    }
    if (installMode != null) {
        feature.setInstall(installMode);
    }
    if (project.getDescription() != null && feature.getDetails() == null) {
        feature.setDetails(project.getDescription());
    }
    if (includeProjectArtifact) {
        Bundle bundle = objectFactory.createBundle();
        bundle.setLocation(this.dependencyHelper.artifactToMvn(project.getArtifact(), project.getVersion()));
        if (startLevel != null) {
            bundle.setStartLevel(startLevel);
        }
        feature.getBundle().add(bundle);
    }
    boolean needWrap = false;
    // First pass to look for features
    // Track other features we depend on and their repositories (we track repositories instead of building them from
    // the feature's Maven artifact to allow for multi-feature repositories)
    // TODO Initialise the repositories from the existing feature file if any
    Map<Dependency, Feature> otherFeatures = new HashMap<>();
    Map<Feature, String> featureRepositories = new HashMap<>();
    for (final LocalDependency entry : localDependencies) {
        Object artifact = entry.getArtifact();
        if (excludedArtifactIds.contains(this.dependencyHelper.getArtifactId(artifact))) {
            continue;
        }
        processFeatureArtifact(features, feature, otherFeatures, featureRepositories, artifact, entry.getParent(), true);
    }
    // Second pass to look for bundles
    if (addBundlesToPrimaryFeature) {
        localDependency: for (final LocalDependency entry : localDependencies) {
            Object artifact = entry.getArtifact();
            if (excludedArtifactIds.contains(this.dependencyHelper.getArtifactId(artifact))) {
                continue;
            }
            if (!this.dependencyHelper.isArtifactAFeature(artifact)) {
                String bundleName = this.dependencyHelper.artifactToMvn(artifact, getVersionOrRange(entry.getParent(), artifact));
                File bundleFile = this.dependencyHelper.resolve(artifact, getLog());
                Manifest manifest = getManifest(bundleFile);
                for (ConfigFile cf : feature.getConfigfile()) {
                    if (bundleName.equals(cf.getLocation().replace('\n', ' ').trim())) {
                        // The bundle matches a configfile, ignore it
                        continue localDependency;
                    }
                }
                if (manifest == null || !ManifestUtils.isBundle(getManifest(bundleFile))) {
                    bundleName = "wrap:" + bundleName;
                    needWrap = true;
                }
                Bundle bundle = null;
                for (Bundle b : feature.getBundle()) {
                    if (bundleName.equals(b.getLocation())) {
                        bundle = b;
                        break;
                    }
                }
                if (bundle == null) {
                    bundle = objectFactory.createBundle();
                    bundle.setLocation(bundleName);
                    // Check the features this feature depends on don't already contain the dependency
                    // TODO Perhaps only for transitive dependencies?
                    boolean includedTransitively = simplifyBundleDependencies && isBundleIncludedTransitively(feature, otherFeatures, bundle);
                    if (!includedTransitively && (!"provided".equals(entry.getScope()) || !ignoreScopeProvided)) {
                        feature.getBundle().add(bundle);
                    }
                }
                if ("runtime".equals(entry.getScope())) {
                    bundle.setDependency(true);
                }
                if (startLevel != null && bundle.getStartLevel() == 0) {
                    bundle.setStartLevel(startLevel);
                }
            }
        }
    }
    if (needWrap) {
        Dependency wrapDependency = new Dependency();
        wrapDependency.setName("wrap");
        wrapDependency.setDependency(false);
        wrapDependency.setPrerequisite(true);
        feature.getFeature().add(wrapDependency);
    }
    if ((!feature.getBundle().isEmpty() || !feature.getFeature().isEmpty()) && !features.getFeature().contains(feature)) {
        features.getFeature().add(feature);
    }
    // Add any missing repositories for the included features
    for (Feature includedFeature : features.getFeature()) {
        for (Dependency dependency : includedFeature.getFeature()) {
            Feature dependedFeature = otherFeatures.get(dependency);
            if (dependedFeature != null && !features.getFeature().contains(dependedFeature)) {
                String repository = featureRepositories.get(dependedFeature);
                if (repository != null && !features.getRepository().contains(repository)) {
                    features.getRepository().add(repository);
                }
            }
        }
    }
    JaxbUtil.marshal(features, out);
    try {
        checkChanges(features, objectFactory);
    } catch (Exception e) {
        throw new MojoExecutionException("Features contents have changed", e);
    }
    getLog().info("...done!");
}
Also used : MojoExecutionException(org.apache.maven.plugin.MojoExecutionException) HashMap(java.util.HashMap) ConfigFile(org.apache.karaf.features.internal.model.ConfigFile) Bundle(org.apache.karaf.features.internal.model.Bundle) Dependency(org.apache.karaf.features.internal.model.Dependency) LocalDependency(org.apache.karaf.tooling.utils.LocalDependency) Manifest(java.util.jar.Manifest) Feature(org.apache.karaf.features.internal.model.Feature) ProjectBuildingException(org.apache.maven.project.ProjectBuildingException) MavenFilteringException(org.apache.maven.shared.filtering.MavenFilteringException) XMLStreamException(javax.xml.stream.XMLStreamException) ArtifactNotFoundException(org.apache.maven.artifact.resolver.ArtifactNotFoundException) JAXBException(javax.xml.bind.JAXBException) SAXException(org.xml.sax.SAXException) ArtifactResolutionException(org.apache.maven.artifact.resolver.ArtifactResolutionException) IOException(java.io.IOException) MojoExecutionException(org.apache.maven.plugin.MojoExecutionException) MojoFailureException(org.apache.maven.plugin.MojoFailureException) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) LocalDependency(org.apache.karaf.tooling.utils.LocalDependency) ObjectFactory(org.apache.karaf.features.internal.model.ObjectFactory) Features(org.apache.karaf.features.internal.model.Features) ConfigFile(org.apache.karaf.features.internal.model.ConfigFile) File(java.io.File)

Example 17 with Feature

use of org.apache.karaf.features.internal.model.Feature in project karaf by apache.

the class GenerateDescriptorMojo method processFeatureArtifact.

private void processFeatureArtifact(Features features, Feature feature, Map<Dependency, Feature> otherFeatures, Map<Feature, String> featureRepositories, Object artifact, Object parent, boolean add) throws MojoExecutionException, XMLStreamException, JAXBException, IOException {
    if (this.dependencyHelper.isArtifactAFeature(artifact) && FEATURE_CLASSIFIER.equals(this.dependencyHelper.getClassifier(artifact))) {
        File featuresFile = this.dependencyHelper.resolve(artifact, getLog());
        if (featuresFile == null || !featuresFile.exists()) {
            throw new MojoExecutionException("Cannot locate file for feature: " + artifact + " at " + featuresFile);
        }
        Features includedFeatures = readFeaturesFile(featuresFile);
        for (String repository : includedFeatures.getRepository()) {
            processFeatureArtifact(features, feature, otherFeatures, featureRepositories, new DefaultArtifact(MavenUtil.mvnToAether(repository)), parent, false);
        }
        for (Feature includedFeature : includedFeatures.getFeature()) {
            Dependency dependency = new Dependency(includedFeature.getName(), includedFeature.getVersion());
            dependency.setPrerequisite(prerequisiteFeatures.contains(dependency.getName()));
            dependency.setDependency(dependencyFeatures.contains(dependency.getName()));
            // Determine what dependency we're actually going to use
            Dependency matchingDependency = findMatchingDependency(feature.getFeature(), dependency);
            if (matchingDependency != null) {
                // The feature already has a matching dependency, merge
                mergeDependencies(matchingDependency, dependency);
                dependency = matchingDependency;
            }
            // We mustn't de-duplicate here, we may have seen a feature in !add mode
            otherFeatures.put(dependency, includedFeature);
            if (add) {
                if (!feature.getFeature().contains(dependency)) {
                    feature.getFeature().add(dependency);
                }
                if (aggregateFeatures) {
                    features.getFeature().add(includedFeature);
                }
            }
            if (!featureRepositories.containsKey(includedFeature)) {
                featureRepositories.put(includedFeature, this.dependencyHelper.artifactToMvn(artifact, getVersionOrRange(parent, artifact)));
            }
        }
    }
}
Also used : MojoExecutionException(org.apache.maven.plugin.MojoExecutionException) Features(org.apache.karaf.features.internal.model.Features) Dependency(org.apache.karaf.features.internal.model.Dependency) LocalDependency(org.apache.karaf.tooling.utils.LocalDependency) ConfigFile(org.apache.karaf.features.internal.model.ConfigFile) File(java.io.File) Feature(org.apache.karaf.features.internal.model.Feature) DefaultArtifact(org.eclipse.aether.artifact.DefaultArtifact)

Example 18 with Feature

use of org.apache.karaf.features.internal.model.Feature in project karaf by apache.

the class VerifyMojo method doExecute.

protected void doExecute() throws MojoExecutionException, MojoFailureException {
    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);
    }
    List<Exception> failures = new ArrayList<>();
    for (Feature feature : featuresToTest) {
        try {
            String id = feature.getName() + "/" + feature.getVersion();
            verifyResolution(new CustomDownloadManager(resolver, executor), repositories, Collections.singleton(id), properties);
            getLog().info("Verification of feature " + id + " succeeded");
        } catch (Exception e) {
            if (e.getCause() instanceof ResolutionException) {
                getLog().warn(e.getMessage());
            } else {
                getLog().warn(e);
            }
            failures.add(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());
            try {
                verifyResolution(manager, repositories, ids, properties);
                getLog().info("Verification of feature " + ids + " 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) {
                        getLog().warn("Feature resolution failed for " + ids + "\nMessage: " + e.getCause().getMessage());
                        continue;
                    }
                }
                if (e.getCause() instanceof ResolutionException) {
                    getLog().warn(e.getMessage());
                } else {
                    getLog().warn(e);
                }
                failures.add(e);
                if ("first".equals(fail)) {
                    throw e;
                }
            }
        }
    }
    if ("end".equals(fail) && !failures.isEmpty()) {
        throw new MojoExecutionException("Verification failures", new MultiException("Verification failures", failures));
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Reader(java.io.Reader) FileReader(java.io.FileReader) Conditional(org.apache.karaf.features.internal.model.Conditional) Properties(java.util.Properties) CustomDownloadManager(org.apache.karaf.profile.assembly.CustomDownloadManager) DownloadManager(org.apache.karaf.features.internal.download.DownloadManager) Feature(org.apache.karaf.features.internal.model.Feature) Field(java.lang.reflect.Field) FileReader(java.io.FileReader) Features(org.apache.karaf.features.internal.model.Features) List(java.util.List) ArrayList(java.util.ArrayList) Pattern(java.util.regex.Pattern) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) MojoExecutionException(org.apache.maven.plugin.MojoExecutionException) ConfigFile(org.apache.karaf.features.internal.model.ConfigFile) Hashtable(java.util.Hashtable) IOException(java.io.IOException) MultiException(org.apache.karaf.features.internal.util.MultiException) BundleException(org.osgi.framework.BundleException) InvalidSyntaxException(org.osgi.framework.InvalidSyntaxException) ResolutionException(org.osgi.service.resolver.ResolutionException) IOException(java.io.IOException) MojoExecutionException(org.apache.maven.plugin.MojoExecutionException) MojoFailureException(org.apache.maven.plugin.MojoFailureException) ResolutionException(org.osgi.service.resolver.ResolutionException) BundleRequirement(org.osgi.framework.wiring.BundleRequirement) Requirement(org.osgi.resource.Requirement) Collection(java.util.Collection) CustomDownloadManager(org.apache.karaf.profile.assembly.CustomDownloadManager) MultiException(org.apache.karaf.features.internal.util.MultiException)

Example 19 with Feature

use of org.apache.karaf.features.internal.model.Feature in project karaf by apache.

the class AbstractFeatureMojo method addFeaturesDependencies.

protected void addFeaturesDependencies(List<Dependency> featureNames, Set<Feature> features, Map<String, Feature> featuresMap, boolean transitive) {
    for (Dependency dependency : featureNames) {
        Feature f = getMatchingFeature(featuresMap, dependency.getName(), dependency.getVersion());
        features.add(f);
        if (transitive) {
            addFeaturesDependencies(f.getFeature(), features, featuresMap, true);
        }
    }
}
Also used : Dependency(org.apache.karaf.features.internal.model.Dependency) Feature(org.apache.karaf.features.internal.model.Feature)

Example 20 with Feature

use of org.apache.karaf.features.internal.model.Feature in project karaf by apache.

the class AbstractFeatureMojo method getMatchingFeature.

private Feature getMatchingFeature(Map<String, Feature> featuresMap, String feature, String version) {
    Feature f = null;
    if (version != null && !version.equals(Feature.DEFAULT_VERSION)) {
        // looking for a specific feature with name and version
        f = featuresMap.get(feature + "/" + version);
        if (f == null) {
            //it's probably is a version range so try to use VersionRange Utils
            VersionRange versionRange = new VersionRange(version);
            for (String key : featuresMap.keySet()) {
                String[] nameVersion = key.split("/");
                if (feature.equals(nameVersion[0])) {
                    String verStr = featuresMap.get(key).getVersion();
                    Version ver = VersionTable.getVersion(verStr);
                    if (versionRange.contains(ver)) {
                        if (f == null || VersionTable.getVersion(f.getVersion()).compareTo(VersionTable.getVersion(featuresMap.get(key).getVersion())) < 0) {
                            f = featuresMap.get(key);
                        }
                    }
                }
            }
        }
    } else {
        // looking for the first feature name (whatever the version is)
        for (String key : featuresMap.keySet()) {
            String[] nameVersion = key.split("/");
            if (feature.equals(nameVersion[0])) {
                f = featuresMap.get(key);
                break;
            }
        }
    }
    if (f == null) {
        throw new IllegalArgumentException("Unable to find the feature '" + feature + "'");
    }
    return f;
}
Also used : Version(org.osgi.framework.Version) VersionRange(org.apache.felix.utils.version.VersionRange) Feature(org.apache.karaf.features.internal.model.Feature)

Aggregations

Feature (org.apache.karaf.features.internal.model.Feature)25 Features (org.apache.karaf.features.internal.model.Features)16 ArrayList (java.util.ArrayList)10 Bundle (org.apache.karaf.features.internal.model.Bundle)9 ConfigFile (org.apache.karaf.features.internal.model.ConfigFile)8 HashMap (java.util.HashMap)7 Downloader (org.apache.karaf.features.internal.download.Downloader)6 Dependency (org.apache.karaf.features.internal.model.Dependency)6 MojoExecutionException (org.apache.maven.plugin.MojoExecutionException)6 IOException (java.io.IOException)5 HashSet (java.util.HashSet)5 File (java.io.File)4 URL (java.net.URL)4 LinkedHashSet (java.util.LinkedHashSet)4 Properties (org.apache.felix.utils.properties.Properties)4 Conditional (org.apache.karaf.features.internal.model.Conditional)4 Profile (org.apache.karaf.profile.Profile)4 Test (org.junit.Test)4 Hashtable (java.util.Hashtable)3 LinkedHashMap (java.util.LinkedHashMap)3