You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by pi...@apache.org on 2012/10/09 10:16:46 UTC

svn commit: r1395904 - in /karaf/branches/karaf-2.3.x: deployer/features/src/main/java/org/apache/karaf/deployer/features/ features/core/src/main/java/org/apache/karaf/features/ features/core/src/main/java/org/apache/karaf/features/internal/ features/c...

Author: pieber
Date: Tue Oct  9 08:16:45 2012
New Revision: 1395904

URL: http://svn.apache.org/viewvc?rev=1395904&view=rev
Log:
[KARAF-1752] Correct hard coded features uri in features deployer feature discovery (thanks to Andrei Pozolotin for this patch)

Signed-off-by: Andreas Pieber <an...@gmail.com>

Added:
    karaf/branches/karaf-2.3.x/features/core/src/main/java/org/apache/karaf/features/FeaturesNamespaces.java
    karaf/branches/karaf-2.3.x/features/core/src/main/resources/org/apache/karaf/features/karaf-features-1.1.0.xsd
    karaf/branches/karaf-2.3.x/tooling/features-maven-plugin/src/test/resources/features-01.xml
Modified:
    karaf/branches/karaf-2.3.x/deployer/features/src/main/java/org/apache/karaf/deployer/features/FeatureDeploymentListener.java
    karaf/branches/karaf-2.3.x/features/core/src/main/java/org/apache/karaf/features/internal/FeatureValidationUtil.java
    karaf/branches/karaf-2.3.x/tooling/features-maven-plugin/src/main/java/org/apache/karaf/tooling/features/GenerateFeaturesXmlMojo.java
    karaf/branches/karaf-2.3.x/tooling/features-maven-plugin/src/test/java/org/apache/karaf/tooling/features/GenerateFeaturesXmlMojoTest.java

Modified: karaf/branches/karaf-2.3.x/deployer/features/src/main/java/org/apache/karaf/deployer/features/FeatureDeploymentListener.java
URL: http://svn.apache.org/viewvc/karaf/branches/karaf-2.3.x/deployer/features/src/main/java/org/apache/karaf/deployer/features/FeatureDeploymentListener.java?rev=1395904&r1=1395903&r2=1395904&view=diff
==============================================================================
--- karaf/branches/karaf-2.3.x/deployer/features/src/main/java/org/apache/karaf/deployer/features/FeatureDeploymentListener.java (original)
+++ karaf/branches/karaf-2.3.x/deployer/features/src/main/java/org/apache/karaf/deployer/features/FeatureDeploymentListener.java Tue Oct  9 08:16:45 2012
@@ -36,6 +36,7 @@ import org.w3c.dom.Document;
 
 import org.apache.felix.fileinstall.ArtifactUrlTransformer;
 import org.apache.karaf.features.Feature;
+import org.apache.karaf.features.FeaturesNamespaces;
 import org.apache.karaf.features.FeaturesService;
 import org.apache.karaf.features.Repository;
 import org.osgi.framework.Bundle;
@@ -88,14 +89,37 @@ public class FeatureDeploymentListener i
         bundleContext.removeBundleListener(this);
     }
 
+    private boolean isKnownFeaturesURI(String uri){
+    	if(uri == null){
+    		return true;
+    	}
+    	if(FeaturesNamespaces.URI_0_0_0.equalsIgnoreCase(uri)){
+    		return true;
+    	}
+    	if(FeaturesNamespaces.URI_1_0_0.equalsIgnoreCase(uri)){
+    		return true;
+    	}
+    	if(FeaturesNamespaces.URI_1_1_0.equalsIgnoreCase(uri)){
+    		return true;
+    	}
+    	if(FeaturesNamespaces.URI_CURRENT.equalsIgnoreCase(uri)){
+    		return true;
+    	}
+    	return false;
+    }
+
     public boolean canHandle(File artifact) {
         try {
             if (artifact.isFile() && artifact.getName().endsWith(".xml")) {
                 Document doc = parse(artifact);
                 String name = doc.getDocumentElement().getLocalName();
                 String uri  = doc.getDocumentElement().getNamespaceURI();
-                if ("features".equals(name) && (uri == null || "".equals(uri)  || "http://karaf.apache.org/xmlns/features/v1.0.0".equalsIgnoreCase(uri))) {
-                    return true;
+                if ("features".equals(name) ) {
+                	if(isKnownFeaturesURI(uri)){
+                        return true;
+                	} else {
+                		logger.error("unknown features uri", new Exception("" + uri));
+                	}
                 }
             }
         } catch (Exception e) {

Added: karaf/branches/karaf-2.3.x/features/core/src/main/java/org/apache/karaf/features/FeaturesNamespaces.java
URL: http://svn.apache.org/viewvc/karaf/branches/karaf-2.3.x/features/core/src/main/java/org/apache/karaf/features/FeaturesNamespaces.java?rev=1395904&view=auto
==============================================================================
--- karaf/branches/karaf-2.3.x/features/core/src/main/java/org/apache/karaf/features/FeaturesNamespaces.java (added)
+++ karaf/branches/karaf-2.3.x/features/core/src/main/java/org/apache/karaf/features/FeaturesNamespaces.java Tue Oct  9 08:16:45 2012
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.karaf.features;
+
+import javax.xml.namespace.QName;
+
+/**
+ * Provides features XML/XSD constants.
+ */
+public interface FeaturesNamespaces {
+
+    String URI_0_0_0 = "";
+    String URI_1_0_0 = "http://karaf.apache.org/xmlns/features/v1.0.0";
+    String URI_1_1_0 = "http://karaf.apache.org/xmlns/features/v1.1.0";
+
+    String URI_CURRENT = URI_1_1_0;
+
+    QName FEATURES_0_0_0 = new QName("features");
+    QName FEATURES_1_0_0 = new QName(URI_1_0_0, "features");
+    QName FEATURES_1_1_0 = new QName(URI_1_1_0, "features");
+
+    QName FEATURES_CURRENT = FEATURES_1_1_0;
+
+}

Modified: karaf/branches/karaf-2.3.x/features/core/src/main/java/org/apache/karaf/features/internal/FeatureValidationUtil.java
URL: http://svn.apache.org/viewvc/karaf/branches/karaf-2.3.x/features/core/src/main/java/org/apache/karaf/features/internal/FeatureValidationUtil.java?rev=1395904&r1=1395903&r2=1395904&view=diff
==============================================================================
--- karaf/branches/karaf-2.3.x/features/core/src/main/java/org/apache/karaf/features/internal/FeatureValidationUtil.java (original)
+++ karaf/branches/karaf-2.3.x/features/core/src/main/java/org/apache/karaf/features/internal/FeatureValidationUtil.java Tue Oct  9 08:16:45 2012
@@ -56,6 +56,8 @@ public class FeatureValidationUtil {
         }
 
         SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+        
+        /** FIXME should move to 1.1.0 ? */
         // root element has namespace - we can use schema validation
         Schema schema = factory.newSchema(new StreamSource(FeatureValidationUtil.class
             .getResourceAsStream("/org/apache/karaf/features/karaf-features-1.0.0.xsd")));

Added: karaf/branches/karaf-2.3.x/features/core/src/main/resources/org/apache/karaf/features/karaf-features-1.1.0.xsd
URL: http://svn.apache.org/viewvc/karaf/branches/karaf-2.3.x/features/core/src/main/resources/org/apache/karaf/features/karaf-features-1.1.0.xsd?rev=1395904&view=auto
==============================================================================
--- karaf/branches/karaf-2.3.x/features/core/src/main/resources/org/apache/karaf/features/karaf-features-1.1.0.xsd (added)
+++ karaf/branches/karaf-2.3.x/features/core/src/main/resources/org/apache/karaf/features/karaf-features-1.1.0.xsd Tue Oct  9 08:16:45 2012
@@ -0,0 +1,237 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements. See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License. You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<xs:schema elementFormDefault="qualified"
+    targetNamespace="http://karaf.apache.org/xmlns/features/v1.1.0"
+    xmlns:tns="http://karaf.apache.org/xmlns/features/v1.1.0"
+    xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+    <xs:annotation>
+        <xs:documentation><![CDATA[
+Karaf features mechanism. For documentation please visit the
+<a href="http://karaf.apache.org/">Karaf website</a>.
+        ]]></xs:documentation>
+    </xs:annotation>
+
+    <xs:complexType name="features">
+        <xs:annotation>
+            <xs:documentation><![CDATA[
+Root element of Feature definition. It contains an required attribute for
+designating from which repository this feature should be loaded. The Karaf
+shell will show the repository name when displaying information about the feature.
+            ]]></xs:documentation>
+        </xs:annotation>
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+            <xs:element name="repository" type="xs:anyURI">
+                <xs:annotation>
+                    <xs:documentation><![CDATA[
+Additional repositories where dependencies are stored.
+                    ]]></xs:documentation>
+                </xs:annotation>
+            </xs:element>
+            <xs:element name="feature" type="tns:feature">
+                <xs:annotation>
+                    <xs:documentation><![CDATA[
+Feature definition.
+                    ]]></xs:documentation>
+                </xs:annotation>
+            </xs:element>
+        </xs:choice>
+        <xs:attribute name="name" type="xs:string" use="required"/>
+    </xs:complexType>
+
+    <xs:complexType name="feature">
+        <xs:annotation>
+            <xs:documentation><![CDATA[
+Definition of the Feature.
+            ]]></xs:documentation>
+        </xs:annotation>
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+            <xs:element name="details" minOccurs="0" type="xs:string">
+                <xs:annotation>
+                    <xs:documentation><![CDATA[
+The help text shown for this feature when using feature:info console command.
+                    ]]>
+                    </xs:documentation>
+                </xs:annotation>
+            </xs:element>
+            <xs:element name="config" type="tns:config" />
+            <xs:element name="configfile" type="tns:configFile" />
+            <xs:element name="feature" type="tns:dependency" />
+            <xs:element name="bundle" type="tns:bundle" />
+        </xs:choice>
+        <xs:attribute name="name" type="tns:featureName" use="required" />
+        <xs:attribute name="version" type="xs:string" default="0.0.0" />
+        <xs:attribute name="description" type="xs:string" />
+        <xs:attribute name="resolver" type="tns:resolver">
+            <xs:annotation>
+                <xs:documentation><![CDATA[
+Optional alternative resolver to use for determining the list of bundles to install for a given feature.
+                ]]>
+                </xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="install" type="tns:install">
+            <xs:annotation>
+                <xs:documentation><![CDATA[
+Marks if the feaute will be automatically started when thrown to the deploy folder.
+                ]]>
+                </xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="start-level" type="xs:int">
+             <xs:annotation>
+                <xs:documentation><![CDATA[
+Set this attribute to have an OSGi start level for this feature different
+from the default start level defined in Karaf's config.properties.
+                ]]>
+                </xs:documentation>
+             </xs:annotation>
+         </xs:attribute>
+    </xs:complexType>
+
+    <xs:complexType name="bundle">
+        <xs:annotation>
+            <xs:documentation><![CDATA[
+Deployable element to install.
+            ]]></xs:documentation>
+        </xs:annotation>
+        <xs:simpleContent>
+            <xs:extension base="xs:anyURI">
+                <xs:attribute name="start-level" type="xs:int">
+                    <xs:annotation>
+                        <xs:documentation><![CDATA[
+Set this attribute to have an OSGi start level for this bundle different
+from the default start level defined in the Karaf's config.properties.
+                        ]]>
+                        </xs:documentation>
+                    </xs:annotation>
+                </xs:attribute>
+                <xs:attribute name="start" type="xs:boolean" default="true">
+                    <xs:annotation>
+                        <xs:documentation><![CDATA[
+If false, leaves bundle in resolved state rather than the default active state.
+                        ]]>
+                        </xs:documentation>
+                    </xs:annotation>
+                </xs:attribute>
+                <xs:attribute name="dependency" type="xs:boolean">
+                    <xs:annotation>
+                        <xs:documentation><![CDATA[
+Mark this bundle as a dependency for the resolver.
+                        ]]>
+                        </xs:documentation>
+                    </xs:annotation>
+                </xs:attribute>
+            </xs:extension>
+        </xs:simpleContent>
+    </xs:complexType>
+
+    <xs:complexType name="dependency">
+        <xs:annotation>
+            <xs:documentation><![CDATA[
+Dependency of feature.
+            ]]></xs:documentation>
+        </xs:annotation>
+        <xs:simpleContent>
+            <xs:extension base="tns:featureName">
+                <xs:attribute name="version" type="xs:string" default="0.0.0" />
+            </xs:extension>
+        </xs:simpleContent>
+    </xs:complexType>
+
+    <xs:complexType name="config">
+        <xs:annotation>
+            <xs:documentation><![CDATA[
+Configuration entries which should be created during feature installation. This
+configuration may be used with OSGi Configuration Admin. The element content is
+read in as a properties file.
+            ]]></xs:documentation>
+        </xs:annotation>
+        <xs:simpleContent>
+            <xs:extension base="xs:string">
+                <xs:attribute name="name" type="xs:string" use="required" />
+            </xs:extension>
+        </xs:simpleContent>
+    </xs:complexType>
+
+    <xs:complexType name="configFile">
+        <xs:annotation>
+            <xs:documentation><![CDATA[
+Additional configuration files which should be created during feature installation.
+            ]]></xs:documentation>
+        </xs:annotation>
+        <xs:simpleContent>
+            <xs:extension base="xs:anyURI">
+                <xs:attribute name="finalname" type="xs:string" use="required">
+                    <xs:annotation>
+                        <xs:documentation><![CDATA[
+The final destination path and name for the configuration file.
+                        ]]></xs:documentation>
+                    </xs:annotation>
+                </xs:attribute>
+                <xs:attribute name="override" type="xs:boolean">
+                    <xs:annotation>
+                        <xs:documentation><![CDATA[
+If the configFile already exists at the finalname location, whether or not to replace it.
+                        ]]></xs:documentation>
+                    </xs:annotation>
+                </xs:attribute>
+
+            </xs:extension>
+        </xs:simpleContent>
+    </xs:complexType>
+
+    <xs:simpleType name="featureName">
+        <xs:annotation>
+            <xs:documentation><![CDATA[
+Feature name should be non empty string.
+            ]]></xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:minLength value="1" />
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="resolver">
+        <xs:annotation>
+            <xs:documentation><![CDATA[
+Resolver to use. Karaf will look for OSGi service which have following properties:
+objectClass: org.apache.karaf.features.Resolver
+name: the value
+            ]]></xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:minLength value="1" />
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="install">
+        <xs:annotation>
+            <xs:documentation><![CDATA[
+Installation mode. Can be either manual or auto. Specifies whether the feature should be automatically installed when
+dropped inside the deploy folder. Note: This attribute doesn't affect feature descriptors that are installed from the
+command line or as part of the org.apache.karaf.features.cfg.
+            ]]></xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+            <xs:minLength value="1" />
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:element name="features" type="tns:features" />
+
+</xs:schema>

Modified: karaf/branches/karaf-2.3.x/tooling/features-maven-plugin/src/main/java/org/apache/karaf/tooling/features/GenerateFeaturesXmlMojo.java
URL: http://svn.apache.org/viewvc/karaf/branches/karaf-2.3.x/tooling/features-maven-plugin/src/main/java/org/apache/karaf/tooling/features/GenerateFeaturesXmlMojo.java?rev=1395904&r1=1395903&r2=1395904&view=diff
==============================================================================
--- karaf/branches/karaf-2.3.x/tooling/features-maven-plugin/src/main/java/org/apache/karaf/tooling/features/GenerateFeaturesXmlMojo.java (original)
+++ karaf/branches/karaf-2.3.x/tooling/features-maven-plugin/src/main/java/org/apache/karaf/tooling/features/GenerateFeaturesXmlMojo.java Tue Oct  9 08:16:45 2012
@@ -87,6 +87,19 @@ public class GenerateFeaturesXmlMojo ext
     private ArtifactCollector collector;
 
     /**
+     * Installation mode. If present, generate "feature.install" attribute:
+     *
+     * <a href="http://karaf.apache.org/xmlns/features/v1.1.0">Installation mode</a>
+     *
+     * Can be either manual or auto. Specifies whether the feature should be automatically installed when
+     * dropped inside the deploy folder. Note: this attribute doesn't affect feature descriptors that are installed
+     * from the feature:install command or as part of the etc/org.apache.karaf.features.cfg file.
+     *
+     * @parameter
+     */
+    protected String installMode;
+
+    /**
      * The file to generate
      * 
      * @parameter default-value="${project.build.directory}/classes/feature.xml"
@@ -524,12 +537,12 @@ public class GenerateFeaturesXmlMojo ext
         return String.format("%s/%s/%s/%s", artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(), artifact.getType());
     }
 
-    private class Feature {
+    /*package*/ class Feature {
 
         private Stack<Artifact> artifacts = new Stack<Artifact>();
         private final Artifact artifact;
         
-        private Feature(Artifact artifact) {
+        /*package*/ Feature(Artifact artifact) {
             super();
             this.artifact = artifact;
             artifacts.push(artifact);
@@ -547,10 +560,25 @@ public class GenerateFeaturesXmlMojo ext
             }
             return false;
         }
+        
+        private String writeAttr(String name, String value){
+        	return " " + name + "=" + "'" + value + "'" + " ";
+        }
 
         public void write(PrintStream out) {
-            out.println("  <feature name='" + artifact.getArtifactId() + "' version='"
-            		+ artifact.getBaseVersion() + "'>");
+        	
+            out.print(
+				" <feature " +
+				writeAttr("name", artifact.getArtifactId()) + 
+				writeAttr("version", artifact.getBaseVersion()) +
+				" "
+				);
+
+            if(installMode != null){
+                out.print(writeAttr("install", installMode));
+            }
+            
+            out.println(" > ");
             
             Stack<Artifact> resulting = new Stack<Artifact>();
             resulting.addAll(artifacts);
@@ -575,7 +603,9 @@ public class GenerateFeaturesXmlMojo ext
                     }
                 }
             }
-            out.println("  </feature>");
+            
+            out.println(" </feature>");
+            
         }
         
         public List<Artifact> getDependencies() {

Modified: karaf/branches/karaf-2.3.x/tooling/features-maven-plugin/src/test/java/org/apache/karaf/tooling/features/GenerateFeaturesXmlMojoTest.java
URL: http://svn.apache.org/viewvc/karaf/branches/karaf-2.3.x/tooling/features-maven-plugin/src/test/java/org/apache/karaf/tooling/features/GenerateFeaturesXmlMojoTest.java?rev=1395904&r1=1395903&r2=1395904&view=diff
==============================================================================
--- karaf/branches/karaf-2.3.x/tooling/features-maven-plugin/src/test/java/org/apache/karaf/tooling/features/GenerateFeaturesXmlMojoTest.java (original)
+++ karaf/branches/karaf-2.3.x/tooling/features-maven-plugin/src/test/java/org/apache/karaf/tooling/features/GenerateFeaturesXmlMojoTest.java Tue Oct  9 08:16:45 2012
@@ -16,7 +16,14 @@
  */
 package org.apache.karaf.tooling.features;
 
+import java.io.ByteArrayOutputStream;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.io.StringWriter;
+
+import org.apache.karaf.tooling.features.GenerateFeaturesXmlMojo.Feature;
 import org.apache.maven.artifact.Artifact;
+import org.codehaus.plexus.util.FileUtils;
 import org.easymock.EasyMock;
 
 import static org.easymock.EasyMock.*;
@@ -28,6 +35,14 @@ import junit.framework.TestCase;
  */
 public class GenerateFeaturesXmlMojoTest extends TestCase {
     
+    private GenerateFeaturesXmlMojo mojo;
+    
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mojo = new GenerateFeaturesXmlMojo();
+    }
+
     public void testToString() throws Exception {
         Artifact artifact = EasyMock.createMock(Artifact.class);
 
@@ -41,4 +56,36 @@ public class GenerateFeaturesXmlMojoTest
         assertEquals("org.apache.karaf.test/test-artifact/1.2.3", GenerateFeaturesXmlMojo.toString(artifact));
     } 
 
+    public void testInstallMode() throws Exception {
+    	
+        Artifact artifact = EasyMock.createMock(Artifact.class);
+
+        expect(artifact.getGroupId()).andReturn("org.apache.karaf.test").anyTimes();
+        expect(artifact.getArtifactId()).andReturn("test-artifact").anyTimes();
+        expect(artifact.getBaseVersion()).andReturn("1.2.3").anyTimes();
+        expect(artifact.getVersion()).andReturn("1.2.3").anyTimes();
+        expect(artifact.getType()).andReturn("jar").anyTimes();
+        
+        replay(artifact);
+        
+        mojo.installMode="auto";
+        
+        Feature feature = mojo.new Feature(artifact);
+        
+        ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+        
+        PrintStream out = new PrintStream(byteStream);
+        
+		feature.write(out);
+		
+		String source = byteStream.toString("UTF-8");
+		
+		System.out.println(source);
+		
+		String target = FileUtils.fileRead("./src/test/resources/features-01.xml", "UTF-8");
+		
+		assertTrue(target.contains(source));
+        
+    } 
+
 }

Added: karaf/branches/karaf-2.3.x/tooling/features-maven-plugin/src/test/resources/features-01.xml
URL: http://svn.apache.org/viewvc/karaf/branches/karaf-2.3.x/tooling/features-maven-plugin/src/test/resources/features-01.xml?rev=1395904&view=auto
==============================================================================
--- karaf/branches/karaf-2.3.x/tooling/features-maven-plugin/src/test/resources/features-01.xml (added)
+++ karaf/branches/karaf-2.3.x/tooling/features-maven-plugin/src/test/resources/features-01.xml Tue Oct  9 08:16:45 2012
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<features xmlns="http://karaf.apache.org/xmlns/features/v1.0.0" name="test-repo">
+
+ <feature  name='test-artifact'  version='1.2.3'   install='auto'  > 
+    <bundle>mvn:org.apache.karaf.test/test-artifact/1.2.3</bundle>
+ </feature>
+ 
+</features>