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:16 UTC

[18/24] git commit: [KARAF-2833] Make management/server independent of blueprint

[KARAF-2833] Make management/server independent of blueprint


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

Branch: refs/heads/master
Commit: 3091414d3430bd8e5674200575384fb6f7783696
Parents: 42b676b
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Sat Mar 22 16:13:32 2014 +0100
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Mon Mar 24 17:30:13 2014 +0100

----------------------------------------------------------------------
 .../standard/src/main/feature/feature.xml       |   1 -
 management/server/pom.xml                       |  17 +-
 .../karaf/management/internal/Activator.java    | 326 +++++++++++++++++++
 .../OSGI-INF/blueprint/karaf-management.xml     | 125 -------
 4 files changed, 342 insertions(+), 127 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/3091414d/assemblies/features/standard/src/main/feature/feature.xml
----------------------------------------------------------------------
diff --git a/assemblies/features/standard/src/main/feature/feature.xml b/assemblies/features/standard/src/main/feature/feature.xml
index 2b0f6c4..e6e6f3f 100644
--- a/assemblies/features/standard/src/main/feature/feature.xml
+++ b/assemblies/features/standard/src/main/feature/feature.xml
@@ -250,7 +250,6 @@
 
     <feature name="management" description="Provide a JMX MBeanServer and a set of MBeans in Karaf" version="${project.version}">
         <feature version="${project.version}">jaas</feature>
-        <feature version="${project.version}">aries-blueprint</feature>
         <bundle dependency="true" start-level="20">mvn:org.apache.aries/org.apache.aries.util/${aries.util.version}</bundle>
         <bundle start-level="30">mvn:org.apache.karaf.management/org.apache.karaf.management.server/${project.version}</bundle>
         <bundle start-level="30">mvn:org.apache.aries.jmx/org.apache.aries.jmx.api/${aries.jmx.api.version}</bundle>

http://git-wip-us.apache.org/repos/asf/karaf/blob/3091414d/management/server/pom.xml
----------------------------------------------------------------------
diff --git a/management/server/pom.xml b/management/server/pom.xml
index 3147278..f4a873a 100644
--- a/management/server/pom.xml
+++ b/management/server/pom.xml
@@ -69,6 +69,17 @@
             <artifactId>org.apache.karaf.service.guard</artifactId>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.karaf</groupId>
+            <artifactId>org.apache.karaf.util</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
 
         <dependency>
             <groupId>org.easymock</groupId>
@@ -103,8 +114,12 @@
                         <Export-Package>org.apache.karaf.management;version=${project.version};-split-package:=merge-first</Export-Package>
                         <Private-Package>
                             org.apache.karaf.management.internal,
-                            org.apache.karaf.service.guard.tools
+                            org.apache.karaf.service.guard.tools,
+                            org.apache.karaf.util.tracker
                         </Private-Package>
+                        <Bundle-Activator>
+                            org.apache.karaf.management.internal.Activator
+                        </Bundle-Activator>
                     </instructions>
                 </configuration>
             </plugin>

http://git-wip-us.apache.org/repos/asf/karaf/blob/3091414d/management/server/src/main/java/org/apache/karaf/management/internal/Activator.java
----------------------------------------------------------------------
diff --git a/management/server/src/main/java/org/apache/karaf/management/internal/Activator.java b/management/server/src/main/java/org/apache/karaf/management/internal/Activator.java
new file mode 100644
index 0000000..b9a6917
--- /dev/null
+++ b/management/server/src/main/java/org/apache/karaf/management/internal/Activator.java
@@ -0,0 +1,326 @@
+/*
+ * 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.management.internal;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.management.MBeanServer;
+import javax.management.NotCompliantMBeanException;
+import javax.management.ObjectName;
+
+import org.apache.karaf.jaas.config.KeystoreManager;
+import org.apache.karaf.management.ConnectorServerFactory;
+import org.apache.karaf.management.JaasAuthenticator;
+import org.apache.karaf.management.KarafMBeanServerGuard;
+import org.apache.karaf.management.MBeanServerFactory;
+import org.apache.karaf.management.RmiRegistryFactory;
+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.ServiceRegistration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Activator implements BundleActivator, ManagedService, SingleServiceTracker.SingleServiceListener {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(Activator.class);
+
+    private ExecutorService executor = Executors.newSingleThreadExecutor();
+    private AtomicBoolean scheduled = new AtomicBoolean();
+    private BundleContext bundleContext;
+    private Dictionary<String, ?> configuration;
+    private ServiceRegistration registration;
+    private SingleServiceTracker<ConfigurationAdmin> configAdminTracker;
+    private SingleServiceTracker<KeystoreManager> keystoreManagerTracker;
+    private ServiceRegistration<MBeanServer> serverRegistration;
+    private ServiceRegistration securityRegistration;
+    private ConnectorServerFactory connectorServerFactory;
+    private RmiRegistryFactory rmiRegistryFactory;
+    private MBeanServerFactory mbeanServerFactory;
+
+    @Override
+    public void start(BundleContext context) throws Exception {
+        bundleContext = context;
+        scheduled.set(true);
+
+        Hashtable<String, Object> props = new Hashtable<String, Object>();
+        props.put(Constants.SERVICE_PID, "org.apache.karaf.management");
+        registration = bundleContext.registerService(ManagedService.class, this, props);
+
+        configAdminTracker = new SingleServiceTracker<ConfigurationAdmin>(
+                bundleContext, ConfigurationAdmin.class, this);
+        keystoreManagerTracker = new SingleServiceTracker<KeystoreManager>(
+                bundleContext, KeystoreManager.class, this);
+        configAdminTracker.open();
+        keystoreManagerTracker.open();
+
+        scheduled.set(false);
+        reconfigure();
+    }
+
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        keystoreManagerTracker.close();
+        configAdminTracker.close();
+        registration.unregister();
+        executor.shutdown();
+        executor.awaitTermination(30, TimeUnit.SECONDS);
+    }
+
+    @Override
+    public void updated(Dictionary<String, ?> properties) throws ConfigurationException {
+        this.configuration = properties;
+        reconfigure();
+    }
+
+    @Override
+    public void serviceFound() {
+        reconfigure();
+    }
+
+    @Override
+    public void serviceLost() {
+        reconfigure();
+    }
+
+    @Override
+    public void serviceReplaced() {
+        reconfigure();
+    }
+
+    protected void reconfigure() {
+        if (scheduled.compareAndSet(false, true)) {
+            executor.submit(new Runnable() {
+                @Override
+                public void run() {
+                    scheduled.set(false);
+                    doStop();
+                    try {
+                        doStart();
+                    } catch (Exception e) {
+                        LOGGER.warn("Error starting management layer", e);
+                        doStop();
+                    }
+                }
+            });
+        }
+    }
+
+    protected void doStart() throws Exception {
+        // This can happen while the bundle is starting as we register
+        // the ManagedService before creating the service trackers
+        if (configAdminTracker == null || keystoreManagerTracker == null) {
+            return;
+        }
+        // Verify dependencies
+        ConfigurationAdmin configurationAdmin = configAdminTracker.getService();
+        KeystoreManager keystoreManager = keystoreManagerTracker.getService();
+        Dictionary<String, ?> config = configuration;
+        if (configurationAdmin == null || keystoreManager == null) {
+            return;
+        }
+
+        String rmiRegistryHost = getString(config, "rmiRegistryHost", "");
+        int rmiRegistryPort = getInt(config, "rmiRegistryPort", 1099);
+        String rmiServerHost = getString(config, "rmiServerHost", "0.0.0.0");
+        int rmiServerPort = getInt(config, "rmiServerPort", 44444);
+
+        String jmxRealm = getString(config, "jmxRealm", "karaf");
+        String serviceUrl = getString(config, "serviceUrl",
+                "service:jmx:rmi://0.0.0.0:" + rmiServerPort + "/jndi/rmi://0.0.0.0:" + rmiRegistryPort + "/karaf-" + System.getProperty("karaf.name"));
+
+        boolean daemon = getBoolean(config, "daemon", true);
+        boolean threaded = getBoolean(config, "threaded", true);
+        ObjectName objectName = new ObjectName(getString(config, "objectName", "connector:name=rmi"));
+        long keyStoreAvailabilityTimeout = getLong(config, "keyStoreAvailabilityTimeout", 5000);
+        String authenticatorType = getString(config, "authenticatorType", "password");
+        boolean secured = getBoolean(config, "secured", false);
+        String secureAlgorithm = getString(config, "secureAlgorithm", "default");
+        String secureProtocol = getString(config, "secureProtocol", "TLS");
+        String keyStore = getString(config, "keyStore", "karaf.ks");
+        String keyAlias = getString(config, "keyAlias", "karaf");
+        String trustStore = getString(config, "trustStore", "karaf.ts");
+
+        KarafMBeanServerGuard guard = new KarafMBeanServerGuard();
+        guard.setConfigAdmin(configurationAdmin);
+        guard.init();
+
+        rmiRegistryFactory = new RmiRegistryFactory();
+        rmiRegistryFactory.setCreate(true);
+        rmiRegistryFactory.setLocate(true);
+        rmiRegistryFactory.setHost(rmiRegistryHost);
+        rmiRegistryFactory.setPort(rmiRegistryPort);
+        rmiRegistryFactory.setBundleContext(bundleContext);
+        rmiRegistryFactory.init();
+
+        mbeanServerFactory = new MBeanServerFactory();
+        mbeanServerFactory.setLocateExistingServerIfPossible(true);
+        mbeanServerFactory.init();
+
+        MBeanServer mbeanServer = mbeanServerFactory.getServer();
+
+        JaasAuthenticator jaasAuthenticator = new JaasAuthenticator();
+        jaasAuthenticator.setRealm(jmxRealm);
+
+        connectorServerFactory = new ConnectorServerFactory();
+        connectorServerFactory.setServer(mbeanServer);
+        connectorServerFactory.setServiceUrl(serviceUrl);
+        connectorServerFactory.setRmiServerHost(rmiServerHost);
+        connectorServerFactory.setDaemon(daemon);
+        connectorServerFactory.setThreaded(threaded);
+        connectorServerFactory.setObjectName(objectName);
+        Map<String, Object> environment = new HashMap<String, Object>();
+        environment.put("jmx.remote.authenticator", jaasAuthenticator);
+        connectorServerFactory.setEnvironment(environment);
+        connectorServerFactory.setKeyStoreAvailabilityTimeout(keyStoreAvailabilityTimeout);
+        connectorServerFactory.setAuthenticatorType(authenticatorType);
+        connectorServerFactory.setSecured(secured);
+        connectorServerFactory.setAlgorithm(secureAlgorithm);
+        connectorServerFactory.setSecureProtocol(secureProtocol);
+        connectorServerFactory.setKeyStore(keyStore);
+        connectorServerFactory.setKeyAlias(keyAlias);
+        connectorServerFactory.setTrustStore(trustStore);
+        connectorServerFactory.setKeystoreManager(keystoreManager);
+        connectorServerFactory.init();
+
+        try {
+            JMXSecurityMBeanImpl securityMBean = new JMXSecurityMBeanImpl();
+            securityMBean.setMBeanServer(mbeanServer);
+            Hashtable<String, Object> props = new Hashtable<String, Object>();
+            props.put("jmx.objectname", "org.apache.karaf:type=security,area=jmx,name=" + System.getProperty("karaf.name"));
+            securityRegistration = bundleContext.registerService(
+                    getInterfaceNames(securityMBean),
+                    securityMBean,
+                    props
+            );
+        } catch (NotCompliantMBeanException e) {
+            LOGGER.warn("Error creating JMX security mbean", e);
+        }
+
+        serverRegistration = bundleContext.registerService(MBeanServer.class, mbeanServer, null);
+    }
+
+    protected void doStop() {
+        if (securityRegistration != null) {
+            securityRegistration.unregister();
+            securityRegistration = null;
+        }
+        if (serverRegistration != null) {
+            serverRegistration.unregister();
+            serverRegistration = null;
+        }
+        if (connectorServerFactory != null) {
+            try {
+                connectorServerFactory.destroy();
+            } catch (Exception e) {
+                LOGGER.warn("Error destroying ConnectorServerFactory", e);
+            }
+            connectorServerFactory = null;
+        }
+        if (mbeanServerFactory != null) {
+            try {
+                mbeanServerFactory.destroy();
+            } catch (Exception e) {
+                LOGGER.warn("Error destroying MBeanServerFactory", e);
+            }
+            mbeanServerFactory = null;
+        }
+        if (rmiRegistryFactory != null) {
+            try {
+                rmiRegistryFactory.destroy();
+            } catch (Exception e) {
+                LOGGER.warn("Error destroying RMIRegistryFactory", e);
+            }
+            rmiRegistryFactory = null;
+        }
+    }
+
+    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 int getInt(Dictionary<String, ?> config, String key, int def) {
+        if (config != null) {
+            Object val = config.get(key);
+            if (val instanceof Number) {
+                return ((Number) val).intValue();
+            } else if (val != null) {
+                return Integer.parseInt(val.toString());
+            }
+        }
+        return def;
+    }
+
+    private long getLong(Dictionary<String, ?> config, String key, long def) {
+        if (config != null) {
+            Object val = config.get(key);
+            if (val instanceof Number) {
+                return ((Number) val).longValue();
+            } else if (val != null) {
+                return Long.parseLong(val.toString());
+            }
+        }
+        return def;
+    }
+
+    private boolean getBoolean(Dictionary<String, ?> config, String key, boolean def) {
+        if (config != null) {
+            Object val = config.get(key);
+            if (val instanceof Boolean) {
+                return (Boolean) val;
+            } else if (val != null) {
+                return Boolean.parseBoolean(val.toString());
+            }
+        }
+        return def;
+    }
+
+    private String getString(Dictionary<String, ?> config, String key, String def) {
+        if (config != null) {
+            Object val = config.get(key);
+            if (val != null) {
+                return val.toString();
+            }
+        }
+        return def;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/3091414d/management/server/src/main/resources/OSGI-INF/blueprint/karaf-management.xml
----------------------------------------------------------------------
diff --git a/management/server/src/main/resources/OSGI-INF/blueprint/karaf-management.xml b/management/server/src/main/resources/OSGI-INF/blueprint/karaf-management.xml
deleted file mode 100644
index 5795018..0000000
--- a/management/server/src/main/resources/OSGI-INF/blueprint/karaf-management.xml
+++ /dev/null
@@ -1,125 +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:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
-           xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"
-           xmlns:jaas="http://karaf.apache.org/xmlns/jaas/v1.0.0">
-
-    <!-- Allow the use of system properties -->
-    <ext:property-placeholder placeholder-prefix="$[" placeholder-suffix="]" />
-
-    <!-- Property place holder -->
-    <cm:property-placeholder persistent-id="org.apache.karaf.management" update-strategy="reload">
-        <cm:default-properties>
-            <cm:property name="rmiRegistryHost" value=""/>
-            <cm:property name="rmiRegistryPort" value="1099"/>
-            <cm:property name="rmiServerHost" value="0.0.0.0"/>
-            <cm:property name="rmiServerPort" value="44444"/>
-            <cm:property name="jmxRealm" value="karaf"/>
-            <cm:property name="serviceUrl" value="service:jmx:rmi://localhost:44444/jndi/rmi://localhost:1099/karaf-$[karaf.name]"/>
-            <cm:property name="daemon" value="true"/>
-            <cm:property name="threaded" value="true"/>
-            <cm:property name="objectName" value="connector:name=rmi"/>
-            <!-- SSL Support -->
-            <cm:property name="keyStoreAvailabilityTimeout" value="5000" />
-            <cm:property name="authenticatorType" value="password" />
-            <cm:property name="secured" value="false" />
-            <cm:property name="secureAlgorithm" value="default" />
-            <cm:property name="secureProtocol" value="TLS" />
-            <cm:property name="keyStore" value="karaf.ks"/>
-            <cm:property name="keyAlias" value="karaf"/>
-            <cm:property name="trustStore" value="karaf.ts"/>
-            <cm:property name="clientAuth" value="false"/>
-        </cm:default-properties>
-    </cm:property-placeholder>
-
-    <!-- MBeanServer bean -->
-    <bean id="mbeanServerFactory" class="org.apache.karaf.management.MBeanServerFactory" init-method="init"
-          destroy-method="destroy" depends-on="rmiRegistryFactory">
-        <property name="locateExistingServerIfPossible" value="true"/>
-    </bean>
-    <bean id="mbeanServer" factory-ref="mbeanServerFactory" factory-method="getServer"/>
-
-    <!-- Export the MBeanServer as an OSGi service -->
-    <service ref="mbeanServer" interface="javax.management.MBeanServer"/>
-
-    <!-- Create a RMI registry -->
-    <bean id="rmiRegistryFactory" class="org.apache.karaf.management.RmiRegistryFactory" init-method="init"
-          destroy-method="destroy">
-        <property name="create" value="true"/>
-        <property name="locate" value="true"/>
-        <property name="host" value="${rmiRegistryHost}"/>
-        <property name="port" value="${rmiRegistryPort}"/>
-        <property name="bundleContext" ref="blueprintBundleContext"/>
-    </bean>
-
-    <!-- Create a JMX connector ServiceFactory -->
-    <reference id="keystoreManager" interface="org.apache.karaf.jaas.config.KeystoreManager"/>
-
-    <bean id="connectorFactory" class="org.apache.karaf.management.ConnectorServerFactory" init-method="init"
-          destroy-method="destroy">
-        <property name="server" ref="mbeanServer"/>
-        <property name="serviceUrl" value="${serviceUrl}"/>
-        <property name="rmiServerHost" value="${rmiServerHost}"/>
-        <property name="daemon" value="${daemon}"/>
-        <property name="threaded" value="${threaded}"/>
-        <property name="objectName" value="${objectName}"/>
-        <property name="environment">
-            <map>
-                <entry key="jmx.remote.authenticator" value-ref="jaasAuthenticator"/>
-            </map>
-        </property>
-        <property name="keyStoreAvailabilityTimeout" value="${keyStoreAvailabilityTimeout}" />
-        <property name="authenticatorType" value="${authenticatorType}" />
-        <property name="secured" value="${secured}" />
-        <property name="algorithm" value="${secureAlgorithm}" />
-        <property name="secureProtocol" value="${secureProtocol}" />
-        <property name="keyStore" value="${keyStore}"/>
-        <property name="keyAlias" value="${keyAlias}"/>
-        <property name="trustStore" value="${trustStore}"/>
-        <property name="keystoreManager" ref="keystoreManager" />
-    </bean>
-
-    <!-- JAAS authenticator -->
-    <bean id="jaasAuthenticator" class="org.apache.karaf.management.JaasAuthenticator">
-        <property name="realm" value="${jmxRealm}"/>
-    </bean>
-
-    <!-- Get a reference to the ConfigurationAdmin service -->
-    <reference id="configAdmin" interface="org.osgi.service.cm.ConfigurationAdmin" />
-
-    <!-- For role-based security on the JMX API -->
-    <bean id="karafMBeanServerGuard" class="org.apache.karaf.management.KarafMBeanServerGuard" init-method="init">
-        <property name="configAdmin" ref="configAdmin" />
-    </bean>
-
-    <!-- JMX Security MBean -->
-    <bean id="jmxSecurityMBean" class="org.apache.karaf.management.internal.JMXSecurityMBeanImpl">
-        <property name="MBeanServer" ref="mbeanServer"/>
-    </bean>
-
-    <service ref="jmxSecurityMBean" auto-export="interfaces">
-        <service-properties>
-            <entry key="jmx.objectname" value="org.apache.karaf:type=security,area=jmx,name=$[karaf.name]" />
-        </service-properties>
-    </service>
-
-</blueprint>
-