You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2014/03/24 17:32:08 UTC

[10/24] git commit: [KARAF-2833] Make feature/core independant of blueprint

[KARAF-2833] Make feature/core independant of blueprint


Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/42ce5d7d
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/42ce5d7d
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/42ce5d7d

Branch: refs/heads/master
Commit: 42ce5d7d81d9cba6a6d949eae314a9c4087eea92
Parents: 3cf38e7
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Thu Mar 20 10:48:09 2014 +0100
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Mon Mar 24 17:30:12 2014 +0100

----------------------------------------------------------------------
 features/core/pom.xml                           |  14 +-
 .../internal/BootFeaturesInstaller.java         |   2 +-
 .../features/internal/FeaturesServiceImpl.java  |  12 +-
 .../karaf/features/internal/osgi/Activator.java | 255 +++++++++++++++++++
 .../resources/OSGI-INF/blueprint/blueprint.xml  | 107 --------
 5 files changed, 274 insertions(+), 116 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/42ce5d7d/features/core/pom.xml
----------------------------------------------------------------------
diff --git a/features/core/pom.xml b/features/core/pom.xml
index a076786..89d49b8 100644
--- a/features/core/pom.xml
+++ b/features/core/pom.xml
@@ -107,9 +107,10 @@
                 <configuration>
                     <instructions>
                         <Export-Package>
-                            org.apache.karaf.features,
-                            org.apache.karaf.features.management,
-                            org.apache.karaf.features.management.codec
+                            org.apache.karaf.features;
+                            org.apache.karaf.features.management;
+                            org.apache.karaf.features.management.codec;
+                                -noimport:=true
                         </Export-Package>
                         <Import-Package>
                             *
@@ -117,11 +118,16 @@
                         <Private-Package>
                             org.apache.karaf.features.internal,
                             org.apache.karaf.features.internal.model,
+                            org.apache.karaf.features.internal.osgi,
                             org.apache.karaf.features.management.internal,
                             org.apache.felix.utils.version,
                             org.apache.felix.utils.manifest,
-                            org.apache.karaf.util.collections
+                            org.apache.karaf.util.collections,
+                            org.apache.karaf.util.tracker
                         </Private-Package>
+                        <Bundle-Activator>
+                            org.apache.karaf.features.internal.osgi.Activator
+                        </Bundle-Activator>
                     </instructions>
                 </configuration>
             </plugin>

http://git-wip-us.apache.org/repos/asf/karaf/blob/42ce5d7d/features/core/src/main/java/org/apache/karaf/features/internal/BootFeaturesInstaller.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/BootFeaturesInstaller.java b/features/core/src/main/java/org/apache/karaf/features/internal/BootFeaturesInstaller.java
index 531f1b0..1b4fa9d 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/BootFeaturesInstaller.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/BootFeaturesInstaller.java
@@ -63,7 +63,7 @@ public class BootFeaturesInstaller {
      * Install boot features
      * @throws Exception
      */
-    public void start() throws Exception {
+    public void start() {
         if (boot != null) {
             if (bootAsynchronous) {
                 new Thread() {

http://git-wip-us.apache.org/repos/asf/karaf/blob/42ce5d7d/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java b/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java
index 381ac4c..909a963 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java
@@ -154,13 +154,17 @@ public class FeaturesServiceImpl implements FeaturesService {
         listeners.remove(listener);
     }
 
-    public void setUrls(String uris) throws URISyntaxException {
+    public void setUrls(String uris) {
         String[] s = uris.split(",");
         this.uris = new HashSet<URI>();
         for (String value : s) {
             value = value.trim();
             if (!value.isEmpty()) {
-                this.uris.add(new URI(value));
+                try {
+                    this.uris.add(new URI(value));
+                } catch (URISyntaxException e) {
+                    LOGGER.warn("Invalid features repository URI: " + value);
+                }
             }
         }
     }
@@ -878,12 +882,12 @@ public class FeaturesServiceImpl implements FeaturesService {
         }
 	}
     
-    public void start() throws Exception {
+    public void start() {
         this.eventAdminListener = bundleManager.createAndRegisterEventAdminListener();
         initState();
     }
 
-    public void stop() throws Exception {
+    public void stop() {
         stopped.set(true);
         uris = new HashSet<URI>(repositories.keySet());
         while (!repositories.isEmpty()) {

http://git-wip-us.apache.org/repos/asf/karaf/blob/42ce5d7d/features/core/src/main/java/org/apache/karaf/features/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/osgi/Activator.java b/features/core/src/main/java/org/apache/karaf/features/internal/osgi/Activator.java
new file mode 100644
index 0000000..c6abdb4
--- /dev/null
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/osgi/Activator.java
@@ -0,0 +1,255 @@
+/*
+ * 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.internal.osgi;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import javax.management.NotCompliantMBeanException;
+
+import org.apache.karaf.features.FeaturesListener;
+import org.apache.karaf.features.FeaturesService;
+import org.apache.karaf.features.internal.BootFeaturesInstaller;
+import org.apache.karaf.features.internal.BundleManager;
+import org.apache.karaf.features.internal.FeatureConfigInstaller;
+import org.apache.karaf.features.internal.FeatureFinder;
+import org.apache.karaf.features.internal.FeaturesServiceImpl;
+import org.apache.karaf.features.management.internal.FeaturesServiceMBeanImpl;
+import org.apache.karaf.region.persist.RegionsPersistence;
+import org.apache.karaf.util.tracker.SingleServiceTracker;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ManagedService;
+import org.osgi.service.url.URLStreamHandlerService;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Activator implements BundleActivator, SingleServiceTracker.SingleServiceListener {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(Activator.class);
+
+    private ExecutorService executor = Executors.newSingleThreadExecutor();
+    private BundleContext bundleContext;
+    private SingleServiceTracker<RegionsPersistence> regionsPersistenceTracker;
+    private SingleServiceTracker<URLStreamHandlerService> mvnUrlHandlerTracker;
+    private SingleServiceTracker<ConfigurationAdmin> configurationAdminTracker;
+    private ServiceTracker<FeaturesListener, FeaturesListener> featuresListenerTracker;
+
+    private FeaturesServiceImpl featuresService;
+    private ServiceRegistration<ManagedService> featureFinderRegistration;
+    private ServiceRegistration<FeaturesService> featuresServiceRegistration;
+    private ServiceRegistration featuresServiceMBeanRegistration;
+
+    @Override
+    public void start(BundleContext context) throws Exception {
+        bundleContext = context;
+        regionsPersistenceTracker = new SingleServiceTracker<RegionsPersistence>(
+                bundleContext, RegionsPersistence.class, this
+        );
+        mvnUrlHandlerTracker = new SingleServiceTracker<URLStreamHandlerService>(
+                bundleContext, URLStreamHandlerService.class, "(url.handler.protocol=mvn)", this
+        );
+        configurationAdminTracker = new SingleServiceTracker<ConfigurationAdmin>(
+                bundleContext, ConfigurationAdmin.class, this
+        );
+        regionsPersistenceTracker.open();
+        mvnUrlHandlerTracker.open();
+        configurationAdminTracker.open();
+    }
+
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        configurationAdminTracker.close();
+        mvnUrlHandlerTracker.close();
+        regionsPersistenceTracker.close();
+        executor.shutdown();
+        executor.awaitTermination(30, TimeUnit.SECONDS);
+    }
+
+    protected void doStart() {
+        ConfigurationAdmin configurationAdmin = configurationAdminTracker.getService();
+        RegionsPersistence regionsPersistence = regionsPersistenceTracker.getService();
+        URLStreamHandlerService mvnUrlHandler = mvnUrlHandlerTracker.getService();
+
+        if (configurationAdmin == null || mvnUrlHandler == null) {
+            return;
+        }
+
+        Properties configuration = new Properties();
+        File configFile = new File(System.getProperty("karaf.etc"), "org.apache.karaf.features.cfg");
+        if (configFile.isFile() && configFile.canRead()) {
+            try {
+                configuration.load(new FileReader(configFile));
+            } catch (IOException e) {
+                LOGGER.warn("Error reading configuration file " + configFile.toString(), e);
+            }
+        }
+
+        FeatureFinder featureFinder = new FeatureFinder();
+        Hashtable<String, Object> props = new Hashtable<String, Object>();
+        props.put(Constants.SERVICE_PID, "org.apache.karaf.features.repos");
+        featureFinderRegistration = bundleContext.registerService(ManagedService.class, featureFinder, props);
+
+        BundleManager bundleManager = new BundleManager(bundleContext, regionsPersistence);
+        FeatureConfigInstaller configInstaller = new FeatureConfigInstaller(configurationAdmin);
+        String featuresRepositories = getString(configuration, "featuresRepositories", "");
+        boolean respectStartLvlDuringFeatureStartup = getBoolean(configuration, "respectStartLvlDuringFeatureStartup", true);
+        boolean respectStartLvlDuringFeatureUninstall = getBoolean(configuration, "respectStartLvlDuringFeatureUninstall", true);
+        long resolverTimeout = getLong(configuration, "resolverTimeout", 5000);
+        String overrides = getString(configuration, "overrides", new File(System.getProperty("karaf.etc"), "overrides.properties").toString());
+        featuresService = new FeaturesServiceImpl(bundleManager, configInstaller);
+        featuresService.setUrls(featuresRepositories);
+        featuresService.setRespectStartLvlDuringFeatureStartup(respectStartLvlDuringFeatureStartup);
+        featuresService.setRespectStartLvlDuringFeatureUninstall(respectStartLvlDuringFeatureUninstall);
+        featuresService.setResolverTimeout(resolverTimeout);
+        featuresService.setOverrides(overrides);
+        featuresService.setFeatureFinder(featureFinder);
+        featuresService.start();
+        featuresServiceRegistration = bundleContext.registerService(FeaturesService.class, featuresService, null);
+
+        featuresListenerTracker = new ServiceTracker<FeaturesListener, FeaturesListener>(
+                bundleContext, FeaturesListener.class, new ServiceTrackerCustomizer<FeaturesListener, FeaturesListener>() {
+            @Override
+            public FeaturesListener addingService(ServiceReference<FeaturesListener> reference) {
+                FeaturesListener service = bundleContext.getService(reference);
+                featuresService.registerListener(service);
+                return service;
+            }
+            @Override
+            public void modifiedService(ServiceReference<FeaturesListener> reference, FeaturesListener service) {
+            }
+            @Override
+            public void removedService(ServiceReference<FeaturesListener> reference, FeaturesListener service) {
+                featuresService.unregisterListener(service);
+                bundleContext.ungetService(reference);
+            }
+        }
+        );
+        featuresListenerTracker.open();
+
+        String featuresBoot = getString(configuration, "featuresBoot", "");
+        boolean featuresBootAsynchronous = getBoolean(configuration, "featuresBootAsynchronous", false);
+        BootFeaturesInstaller bootFeaturesInstaller = new BootFeaturesInstaller(bundleContext, featuresService, featuresBoot, featuresBootAsynchronous);
+        bootFeaturesInstaller.start();
+
+        try {
+            FeaturesServiceMBeanImpl featuresServiceMBean = new FeaturesServiceMBeanImpl();
+            featuresServiceMBean.setBundleContext(bundleContext);
+            featuresServiceMBean.setFeaturesService(featuresService);
+            props = new Hashtable<String, Object>();
+            props.put("jmx.objectname", "org.apache.karaf:type=feature,name=" + System.getProperty("karaf.name"));
+            featuresServiceMBeanRegistration = bundleContext.registerService(
+                    getInterfaceNames(featuresServiceMBean),
+                    featuresServiceMBean,
+                    props
+            );
+        } catch (NotCompliantMBeanException e) {
+            LOGGER.warn("Error creating FeaturesService mbean", e);
+        }
+    }
+
+    protected void doStop() {
+        if (featuresListenerTracker != null) {
+            featuresListenerTracker.close();
+            featuresListenerTracker = null;
+        }
+        if (featureFinderRegistration != null) {
+            featureFinderRegistration.unregister();
+            featureFinderRegistration = null;
+        }
+        if (featuresServiceRegistration != null) {
+            featuresServiceRegistration.unregister();
+            featuresServiceRegistration = null;
+        }
+        if (featuresServiceMBeanRegistration != null) {
+            featuresServiceMBeanRegistration.unregister();
+            featuresServiceMBeanRegistration = null;
+        }
+        if (featuresService != null) {
+            featuresService.stop();
+            featuresService = null;
+        }
+    }
+
+    @Override
+    public void serviceFound() {
+        executor.submit(new Runnable() {
+            @Override
+            public void run() {
+                doStop();
+                try {
+                    doStart();
+                } catch (Exception e) {
+                    LOGGER.warn("Error starting FeaturesService", e);
+                    doStop();
+                }
+            }
+        });
+    }
+
+    @Override
+    public void serviceLost() {
+        serviceFound();
+    }
+
+    @Override
+    public void serviceReplaced() {
+        serviceFound();
+    }
+
+    private String[] getInterfaceNames(Object object) {
+        List<String> names = new ArrayList<String>();
+        for (Class cl = object.getClass(); cl != Object.class; cl = cl.getSuperclass()) {
+            addSuperInterfaces(names, cl);
+        }
+        return names.toArray(new String[names.size()]);
+    }
+
+    private void addSuperInterfaces(List<String> names, Class clazz) {
+        for (Class cl : clazz.getInterfaces()) {
+            names.add(cl.getName());
+            addSuperInterfaces(names, cl);
+        }
+    }
+
+    private String getString(Properties configuration, String key, String value) {
+        return configuration.getProperty(key, value);
+    }
+
+    private boolean getBoolean(Properties configuration, String key, boolean value) {
+        return Boolean.parseBoolean(getString(configuration, key, Boolean.toString(value)));
+    }
+
+    private long getLong(Properties configuration, String key, long value) {
+        return Long.parseLong(getString(configuration, key, Long.toString(value)));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/42ce5d7d/features/core/src/main/resources/OSGI-INF/blueprint/blueprint.xml
----------------------------------------------------------------------
diff --git a/features/core/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/features/core/src/main/resources/OSGI-INF/blueprint/blueprint.xml
deleted file mode 100644
index 38391be..0000000
--- a/features/core/src/main/resources/OSGI-INF/blueprint/blueprint.xml
+++ /dev/null
@@ -1,107 +0,0 @@
-<?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.
-
--->
-<blueprint
-        xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
-        xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"
-        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-        xsi:schemaLocation="
-        http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
-        http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0 http://aries.apache.org/schemas/blueprint-ext/blueprint-ext.xsd">
-
-    <ext:property-placeholder placeholder-prefix="$(" placeholder-suffix=")"/>
-
-    <ext:property-placeholder placeholder-prefix="$[" placeholder-suffix="]" ignore-missing-locations="true">
-        <ext:default-properties>
-            <ext:property name="featuresRepositories" value=""/>
-            <ext:property name="featuresBoot" value=""/>
-            <ext:property name="resolverTimeout" value="5000"/>
-            <ext:property name="respectStartLvlDuringFeatureStartup" value="true"/>
-            <ext:property name="respectStartLvlDuringFeatureUninstall" value="true"/>
-            <ext:property name="featuresBootAsynchronous" value="false"/>
-            <ext:property name="overrides" value="file:$(karaf.etc)/overrides.properties"/>
-        </ext:default-properties>
-        <ext:location>file:$(karaf.etc)/org.apache.karaf.features.cfg</ext:location>
-    </ext:property-placeholder>
-
-    <reference-list id="featuresListeners" interface="org.apache.karaf.features.FeaturesListener"
-                    availability="optional">
-
-    <reference-listener ref="featuresService"
-                            bind-method="registerListener"
-                            unbind-method="unregisterListener"/>
-    </reference-list>
-
-    <reference id="configAdmin" interface="org.osgi.service.cm.ConfigurationAdmin"/>
-
-    <reference id="mvnUrlHandler" interface="org.osgi.service.url.URLStreamHandlerService"
-               filter="(url.handler.protocol=mvn)"/>
-
-    <reference id="regionsPersistence" availability="optional"
-               interface="org.apache.karaf.region.persist.RegionsPersistence"/>
-
-    <bean id="bundleManager" class="org.apache.karaf.features.internal.BundleManager">
-        <argument ref="blueprintBundleContext"/>
-        <argument ref="regionsPersistence"/>
-    </bean>
-    <bean id="configInstaller" class="org.apache.karaf.features.internal.FeatureConfigInstaller">
-        <argument ref="configAdmin"/>
-    </bean>
-    <bean id="featuresService" class="org.apache.karaf.features.internal.FeaturesServiceImpl" init-method="start"
-          destroy-method="stop">
-        <argument ref="bundleManager"/>
-        <argument ref="configInstaller"/>
-        <property name="urls" value="$[featuresRepositories]"/>
-        <property name="respectStartLvlDuringFeatureStartup" value="$[respectStartLvlDuringFeatureStartup]"/>
-        <property name="respectStartLvlDuringFeatureUninstall" value="$[respectStartLvlDuringFeatureUninstall]"/>
-        <property name="resolverTimeout" value="$[resolverTimeout]"/>
-        <property name="overrides" value="$[overrides]"/>
-        <property name="featureFinder" ref="featureFinder" />
-    </bean>
-
-
-    <bean id="featureFinder" class="org.apache.karaf.features.internal.FeatureFinder"/>
-    <service ref="featureFinder" interface="org.osgi.service.cm.ManagedService" >
-        <service-properties>
-            <entry key="service.pid" value="org.apache.karaf.features.repos" />
-        </service-properties>
-    </service>
-
-    <bean id="bootFeaturesInstaller" class="org.apache.karaf.features.internal.BootFeaturesInstaller"
-          init-method="start">
-        <argument ref="blueprintBundleContext"/>
-        <argument ref="featuresService"/>
-        <argument value="$[featuresBoot]"/>
-        <argument value="$[featuresBootAsynchronous]"/>
-    </bean>
-
-    <bean id="featuresServiceMBean" class="org.apache.karaf.features.management.internal.FeaturesServiceMBeanImpl">
-        <property name="bundleContext" ref="blueprintBundleContext"/>
-        <property name="featuresService" ref="featuresService"/>
-    </bean>
-
-    <service ref="featuresService" interface="org.apache.karaf.features.FeaturesService"/>
-
-    <service ref="featuresServiceMBean" auto-export="interfaces">
-        <service-properties>
-            <entry key="jmx.objectname" value="org.apache.karaf:type=feature,name=$(karaf.name)"/>
-        </service-properties>
-    </service>
-
-</blueprint>