ace-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From br...@apache.org
Subject svn commit: r1517469 - in /ace/trunk/org.apache.ace.agent: ./ src/org/apache/ace/agent/impl/
Date Mon, 26 Aug 2013 08:58:30 GMT
Author: bramk
Date: Mon Aug 26 08:58:30 2013
New Revision: 1517469

URL: http://svn.apache.org/r1517469
Log:
ACE-347 Extracted some inner classes / Replace DM

Added:
    ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/DependencyTrackerImpl.java
    ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/EventsHandler.java
    ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/EventsHandlerImpl.java
    ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/LoggingHandler.java
    ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/LoggingHandlerImpl.java
Modified:
    ace/trunk/org.apache.ace.agent/bnd.bnd
    ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/Activator.java
    ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/EventLoggerImpl.java

Modified: ace/trunk/org.apache.ace.agent/bnd.bnd
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/bnd.bnd?rev=1517469&r1=1517468&r2=1517469&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/bnd.bnd (original)
+++ ace/trunk/org.apache.ace.agent/bnd.bnd Mon Aug 26 08:58:30 2013
@@ -15,14 +15,6 @@ Private-Package: org.apache.ace.range,\
 	org.apache.commons.codec.net,\
 	org.apache.felix.deploymentadmin,\
 	org.apache.felix.deploymentadmin.spi,\
-	org.apache.felix.dm.impl.dependencies,\
-	org.apache.felix.dm,\
-	org.apache.felix.dm.impl,\
-	org.apache.felix.dm.impl.index,\
-	org.apache.felix.dm.impl.metatype,\
-	org.apache.felix.dm.tracker,\
-	org.osgi.service.metatype,\
-	org.osgi.service.cm,\
 	org.osgi.service.event,\
 	org.osgi.service.log,\
 	org.osgi.util.tracker
@@ -39,12 +31,12 @@ Export-Package: org.apache.ace.agent,\
 	org.osgi.service.deploymentadmin;-split-package:=merge-last,\
 	org.osgi.service.deploymentadmin.spi;-split-package:=merge-last
 
+
 -buildpath: osgi.core;version=4.2,\
 	osgi.cmpn;version=4.2,\
 	javax.servlet;version=2.5,\
 	org.apache.felix.deploymentadmin;version=0.9.4,\
 	org.easymock,\
-	org.apache.felix.dependencymanager,\
 	commons-codec;version=1.4.0,\
 	org.apache.felix.http.jetty;version=2.2.1,\
 	org.apache.ace.range.api;version=latest,\

Modified: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/Activator.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/Activator.java?rev=1517469&r1=1517468&r2=1517469&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/Activator.java (original)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/Activator.java Mon Aug 26
08:58:30 2013
@@ -21,11 +21,8 @@ package org.apache.ace.agent.impl;
 import static org.apache.ace.agent.impl.ReflectionUtil.configureField;
 import static org.apache.ace.agent.impl.ReflectionUtil.invokeMethod;
 
-import java.util.Date;
 import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
+import java.util.Hashtable;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ThreadFactory;
@@ -34,224 +31,200 @@ import org.apache.ace.agent.AgentControl
 import org.apache.ace.agent.ConnectionHandler;
 import org.apache.ace.agent.DiscoveryHandler;
 import org.apache.ace.agent.IdentificationHandler;
+import org.apache.ace.agent.impl.DependencyTrackerImpl.DependencyCallback;
+import org.apache.ace.agent.impl.DependencyTrackerImpl.LifecycleCallbacks;
 import org.apache.felix.deploymentadmin.DeploymentAdminImpl;
-import org.apache.felix.dm.Component;
-import org.apache.felix.dm.DependencyActivatorBase;
-import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.deploymentadmin.DeploymentAdmin;
 import org.osgi.service.event.Event;
 import org.osgi.service.event.EventAdmin;
-import org.osgi.service.event.EventHandler;
 import org.osgi.service.log.LogService;
 import org.osgi.service.packageadmin.PackageAdmin;
 
-// TODO Decouple from DM to save 170k in agent size. Or: just include what we use
-public class Activator extends DependencyActivatorBase {
+/**
+ * 
+ */
+public class Activator implements BundleActivator {
 
     // internal delegates
-    private final InternalEvents m_internalEvents = new InternalEvents();
-    private final InternalLogger m_internalLogger = new InternalLogger(LogService.LOG_DEBUG);
+    private final EventsHandlerImpl m_internalEvents = new EventsHandlerImpl();
+    private final LoggingHandlerImpl m_internalLogger = new LoggingHandlerImpl(LogService.LOG_DEBUG);
 
     // managed state
     private AgentContextImpl m_agentContext;
-    private AgentControl m_agentControl;
+    private AgentControlImpl m_agentControl;
     private ScheduledExecutorService m_executorService;
-    private DeploymentAdmin m_deploymentAdmin;
-    private Component m_agentControlComponent = null;
     private EventLoggerImpl m_eventLoggerImpl;
     private DefaultController m_defaultController;
+    private volatile DeploymentAdmin m_deploymentAdmin;
+    private ServiceRegistration m_agentControlRegistration;
 
     // injected services
     private volatile PackageAdmin m_packageAdmin;
+    private volatile IdentificationHandler m_identificationHandler;
+    private volatile DiscoveryHandler m_discoveryHandler;
+    private volatile ConnectionHandler m_connectionHandler;
+
+    private volatile BundleContext m_bundleContext;
+    private DependencyTrackerImpl m_dependencyTracker;
 
     @Override
-    public void init(BundleContext context, DependencyManager manager) throws Exception {
+    public void start(final BundleContext bundleContext) throws Exception {
 
+        m_bundleContext = bundleContext;
         m_executorService = Executors.newScheduledThreadPool(1, new InternalThreadFactory());
 
-        m_deploymentAdmin = new DeploymentAdminImpl();
-        configureField(m_deploymentAdmin, BundleContext.class, context);
-        configureField(m_deploymentAdmin, PackageAdmin.class, null);
-        configureField(m_deploymentAdmin, EventAdmin.class, new InternalEventAdmin(m_internalEvents));
-        configureField(m_deploymentAdmin, LogService.class, new InternalLogService(m_internalLogger,
"deployment"));
+        m_dependencyTracker = new DependencyTrackerImpl(bundleContext, new LifecycleCallbacks()
{
 
-        m_agentContext = new AgentContextImpl(context.getDataFile(""));
-        m_agentControl = new AgentControlImpl(m_agentContext);
+            @Override
+            public void started() {
+                try {
+                    startAgent();
+                }
+                catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
 
-        m_agentContext.setLoggingHandler(m_internalLogger);
-        m_agentContext.setEventsHandler(m_internalEvents);
-        m_agentContext.setConfigurationHandler(new ConfigurationHandlerImpl());
-        m_agentContext.setExecutorService(m_executorService);
-        m_agentContext.setConnectionHandler(new ConnectionHandlerImpl());
-        m_agentContext.setIdentificationHandler(new IdentificationHandlerImpl());
-        m_agentContext.setDiscoveryHandler(new DiscoveryHandlerImpl());
-        m_agentContext.setDownloadHandler(new DownloadHandlerImpl());
-        m_agentContext.setDeploymentHandler(new DeploymentHandlerImpl(m_deploymentAdmin));
-        m_agentContext.setAgentUpdateHandler(new AgentUpdateHandlerImpl(context));
-        m_agentContext.setFeedbackHandler(new FeedbackHandlerImpl());
+            @Override
+            public void stopped() {
+                try {
+                    stopAgent();
+                }
+                catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        });
+
+        m_dependencyTracker.addDependency(PackageAdmin.class, null, new DependencyCallback()
{
 
-        Component agentContextComponent = createComponent()
-            .setImplementation(m_agentContext)
-            .setCallbacks(this, null, "startAgent", "stopAgent", null)
-            .setAutoConfig(BundleContext.class, false)
-            .setAutoConfig(DependencyManager.class, false)
-            .setAutoConfig(Component.class, false)
-            .add(createServiceDependency()
-                .setService(PackageAdmin.class).setRequired(true)
-                .setCallbacks(this, "packageAdminAdded", "packageAdminRemoved"));
+            @Override
+            public void updated(Object service) {
+                m_packageAdmin = (PackageAdmin) service;
+            }
+        });
 
         // FIXME fake config
         if (Boolean.parseBoolean(System.getProperty("agent.identificationhandler.disabled")))
{
-            m_internalLogger.logInfo("activator", "Initializing agent...", null);
-            agentContextComponent.add(createServiceDependency().setService(IdentificationHandler.class).setRequired(true));
+            m_dependencyTracker.addDependency(IdentificationHandler.class, null, new DependencyCallback()
{
+                @Override
+                public void updated(Object service) {
+                    m_identificationHandler = (IdentificationHandler) service;
+                }
+            });
         }
         // FIXME fake config
         if (Boolean.parseBoolean(System.getProperty("agent.discoveryhandler.disabled")))
{
-            m_internalLogger.logInfo("activator", "Initializing agent...", null);
-            agentContextComponent.add(createServiceDependency().setService(DiscoveryHandler.class).setRequired(true));
+            m_dependencyTracker.addDependency(DiscoveryHandler.class, null, new DependencyCallback()
{
+                @Override
+                public void updated(Object service) {
+                    m_discoveryHandler = (DiscoveryHandler) service;
+                }
+            });
         }
         // FIXME fake config
         if (Boolean.parseBoolean(System.getProperty("agent.connectionhandler.disabled")))
{
-            agentContextComponent.add(createServiceDependency().setService(ConnectionHandler.class).setRequired(true));
+            m_dependencyTracker.addDependency(ConnectionHandler.class, null, new DependencyCallback()
{
+                @Override
+                public void updated(Object service) {
+                    m_connectionHandler = (ConnectionHandler) service;
+                }
+            });
         }
-        manager.add(agentContextComponent);
+
+        m_dependencyTracker.startTracking();
     }
 
     @Override
-    public void destroy(BundleContext context, DependencyManager manager) throws Exception
{
+    public void stop(BundleContext context) throws Exception {
+        m_dependencyTracker.stopTracking();
         m_executorService.shutdownNow();
         m_executorService = null;
     }
 
-    synchronized void packageAdminAdded(PackageAdmin packageAdmin) {
-        if (m_packageAdmin == null) {
-            m_packageAdmin = packageAdmin;
-            configureField(m_deploymentAdmin, PackageAdmin.class, packageAdmin);
-        }
-    }
-
-    synchronized void packageAdminRemoved(PackageAdmin packageAdmin) {
-        if (m_packageAdmin == packageAdmin) {
-            m_packageAdmin = null;
-            configureField(m_deploymentAdmin, PackageAdmin.class, null);
-        }
-    }
-
     void startAgent() throws Exception {
 
         m_internalLogger.logInfo("activator", "Agent starting...", null);
 
+        m_deploymentAdmin = new DeploymentAdminImpl();
+        configureField(m_deploymentAdmin, BundleContext.class, m_bundleContext);
+        configureField(m_deploymentAdmin, PackageAdmin.class, m_packageAdmin);
+        configureField(m_deploymentAdmin, EventAdmin.class, new InternalEventAdmin(m_internalEvents));
+        configureField(m_deploymentAdmin, LogService.class, new InternalLogService(m_internalLogger,
"deployment"));
         invokeMethod(m_deploymentAdmin, "start", new Class<?>[] {}, new Object[] {});
+
+        m_agentContext = new AgentContextImpl(m_bundleContext.getDataFile(""));
+        m_agentContext.setLoggingHandler(m_internalLogger);
+        m_agentContext.setEventsHandler(m_internalEvents);
+        m_agentContext.setConfigurationHandler(new ConfigurationHandlerImpl());
+        m_agentContext.setExecutorService(m_executorService);
+        m_agentContext.setConnectionHandler(new ConnectionHandlerImpl());
+        m_agentContext.setIdentificationHandler(new IdentificationHandlerImpl());
+        m_agentContext.setDiscoveryHandler(new DiscoveryHandlerImpl());
+        m_agentContext.setDownloadHandler(new DownloadHandlerImpl());
+        m_agentContext.setDeploymentHandler(new DeploymentHandlerImpl(m_deploymentAdmin));
+        m_agentContext.setAgentUpdateHandler(new AgentUpdateHandlerImpl(m_bundleContext));
+        m_agentContext.setFeedbackHandler(new FeedbackHandlerImpl());
         m_agentContext.start();
+        m_internalLogger.logInfo("activator", "AgentContext started", null);
 
-        m_internalLogger.logInfo("activator", "Agent control service started", null);
-        m_agentControlComponent = createComponent()
-            .setInterface(AgentControl.class.getName(), null)
-            .setImplementation(m_agentControl);
-        getDependencyManager().add(m_agentControlComponent);
+        m_agentControl = new AgentControlImpl(m_agentContext);
+        m_agentControlRegistration = m_bundleContext.registerService(AgentControl.class.getName(),
m_agentControl, null);
+        m_internalLogger.logInfo("activator", "AgentControl registered", null);
 
-        // FIXME fake config
-        if (!Boolean.parseBoolean(System.getProperty("agent.defaultcontroller.disabled")))
{
-            m_defaultController = new DefaultController();
-            m_defaultController.start(m_agentContext);
-            m_internalLogger.logInfo("activator", "Default controller started", null);
-        }
-        else {
-            m_internalLogger.logInfo("activator", "Default controller disabled", null);
-        }
+        m_defaultController = new DefaultController();
+        m_defaultController.start(m_agentContext);
+        m_internalLogger.logInfo("activator", "DefaultController started", null);
 
         // FIXME fake config
         if (!Boolean.parseBoolean(System.getProperty("agent.auditlogging.disabled"))) {
-            m_eventLoggerImpl = new EventLoggerImpl(m_agentControl, getDependencyManager().getBundleContext());
-            BundleContext bundleContext = getDependencyManager().getBundleContext();
-            bundleContext.addBundleListener(m_eventLoggerImpl);
-            bundleContext.addFrameworkListener(m_eventLoggerImpl);
+            m_eventLoggerImpl = new EventLoggerImpl(m_agentControl, m_bundleContext);
+            m_bundleContext.addBundleListener(m_eventLoggerImpl);
+            m_bundleContext.addFrameworkListener(m_eventLoggerImpl);
             m_internalEvents.registerHandler(m_eventLoggerImpl, EventLoggerImpl.TOPICS_INTEREST);
             m_internalLogger.logInfo("activator", "Audit logger started", null);
         }
         else {
             m_internalLogger.logInfo("activator", "Audit logger disabled", null);
         }
-
-        m_internalLogger.logInfo("activator", "Agent started", null);
+        m_internalLogger.logInfo("activator", "Agent statup complete", null);
     }
 
     void stopAgent() throws Exception {
 
         m_internalLogger.logInfo("activator", "Agent stopping..", null);
 
-        if (m_agentControlComponent != null) {
-            getDependencyManager().remove(m_agentControlComponent);
-            m_agentControlComponent = null;
-        }
+        m_agentControlRegistration.unregister();
+        m_agentControlRegistration = null;
 
-        if (m_defaultController != null) {
-            m_defaultController.stop();
-            m_defaultController = null;
-        }
+        m_defaultController.stop();
+        m_defaultController = null;
+
+        invokeMethod(m_deploymentAdmin, "stop", new Class<?>[] {}, new Object[] {});
 
         if (m_eventLoggerImpl != null) {
-            BundleContext bundleContext = getDependencyManager().getBundleContext();
-            bundleContext.removeFrameworkListener(m_eventLoggerImpl);
-            bundleContext.removeBundleListener(m_eventLoggerImpl);
+            m_bundleContext.removeFrameworkListener(m_eventLoggerImpl);
+            m_bundleContext.removeBundleListener(m_eventLoggerImpl);
             m_internalEvents.unregisterHandler(m_eventLoggerImpl);
         }
 
         m_agentContext.stop();
-        invokeMethod(m_deploymentAdmin, "stop", new Class<?>[] {}, new Object[] {});
+        m_agentContext = null;
+
         m_internalLogger.logInfo("activator", "Agent stopped", null);
     }
 
-    /**
-     * InternalEvents that posts events to internal handlers and external admins.
-     */
-    static class InternalEvents implements EventsHandler {
-
-        private final Map<EventHandler, String[]> m_eventHandlers = new HashMap<EventHandler,
String[]>();
-
-        public void postEvent(String topic, Dictionary<String, String> payload) {
-            Event event = new Event(topic, payload);
-            postEvent(event);
-        }
-
-        public void postEvent(Event event) {
-            sendInternal(event);
-            sendExternal(event);
-        }
-
-        void registerHandler(EventHandler eventHandler, String[] topics) {
-            synchronized (m_eventHandlers) {
-                m_eventHandlers.put(eventHandler, topics);
-            }
-        }
-
-        void unregisterHandler(EventHandler eventHandler) {
-            synchronized (m_eventHandlers) {
-                m_eventHandlers.remove(eventHandler);
-            }
-        }
-
-        private void sendInternal(Event event) {
-            String topic = event.getTopic();
-            synchronized (m_eventHandlers) {
-                for (Entry<EventHandler, String[]> entry : m_eventHandlers.entrySet())
{
-                    for (String interest : entry.getValue()) {
-                        if ((interest.endsWith("*") && topic.startsWith(interest.substring(0,
interest.length() - 1))
-                        || topic.equals(interest))) {
-                            entry.getKey().handleEvent(event);
-                            break;
-                        }
-                    }
-                }
-            }
-        }
-
-        private void sendExternal(Event event) {
-            // TODO this requires looking for all service references and invoking any found
admins using reflection
-        }
-
+    private void configureDeploymentAdmin() {
+        m_deploymentAdmin = new DeploymentAdminImpl();
+        configureField(m_deploymentAdmin, BundleContext.class, m_bundleContext);
+        configureField(m_deploymentAdmin, PackageAdmin.class, m_packageAdmin);
+        configureField(m_deploymentAdmin, EventAdmin.class, new InternalEventAdmin(m_internalEvents));
+        configureField(m_deploymentAdmin, LogService.class, new InternalLogService(m_internalLogger,
"deployment"));
+        invokeMethod(m_deploymentAdmin, "start", new Class<?>[] {}, new Object[] {});
     }
 
     /**
@@ -259,64 +232,28 @@ public class Activator extends Dependenc
      */
     static class InternalEventAdmin implements EventAdmin {
 
-        private final InternalEvents m_events;
+        private final EventsHandler m_events;
 
-        public InternalEventAdmin(InternalEvents events) {
+        public InternalEventAdmin(EventsHandler events) {
             m_events = events;
         }
 
         @Override
         public void postEvent(Event event) {
-            m_events.postEvent(event);
+            m_events.postEvent(event.getTopic(), getPayload(event));
         }
 
         @Override
         public void sendEvent(Event event) {
-            m_events.postEvent(event);
+            m_events.postEvent(event.getTopic(), getPayload(event));
         }
-    }
-
-    /**
-     * Internal logger that writes to system out for now. It minimizes work until it is determined
the loglevel is
-     * loggable.
-     */
-    static class InternalLogger implements LoggingHandler {
-
-        private final int m_level;
 
-        public InternalLogger(int level) {
-            m_level = level;
-        }
-
-        private void log(String level, String component, String message, Throwable exception,
Object... args) {
-            if (args.length > 0)
-                message = String.format(message, args);
-            String line = String.format("[%s] %TT (%s) %s", level, new Date(), component,
message);
-            System.out.println(line);
-            if (exception != null)
-                exception.printStackTrace(System.out);
-        }
-
-        public void logDebug(String component, String message, Throwable exception, Object...
args) {
-            if (m_level < LogService.LOG_DEBUG)
-                return;
-            log("DEBUG", component, message, exception, args);
-        }
-
-        public void logInfo(String component, String message, Throwable exception, Object...
args) {
-            if (m_level < LogService.LOG_INFO)
-                return;
-            log("INFO", component, message, exception, args);
-        }
-
-        public void logWarning(String component, String message, Throwable exception, Object...
args) {
-            if (m_level < LogService.LOG_WARNING)
-                return;
-            log("WARNING", component, message, exception, args);
-        }
-
-        public void logError(String component, String message, Throwable exception, Object...
args) {
-            log("ERROR", component, message, exception, args);
+        private static Dictionary<String, String> getPayload(Event event) {
+            Dictionary<String, String> payload = new Hashtable<String, String>();
+            for (String propertyName : event.getPropertyNames()) {
+                payload.put(propertyName, event.getProperty(propertyName).toString());
+            }
+            return payload;
         }
     }
 
@@ -325,10 +262,10 @@ public class Activator extends Dependenc
      */
     static class InternalLogService implements LogService {
 
-        private final InternalLogger m_logger;
+        private final LoggingHandler m_logger;
         private final String m_identifier;
 
-        public InternalLogService(InternalLogger logger, String identifier) {
+        public InternalLogService(LoggingHandler logger, String identifier) {
             m_logger = logger;
             m_identifier = identifier;
         }
@@ -381,4 +318,5 @@ public class Activator extends Dependenc
             return thread;
         }
     }
+
 }

Added: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/DependencyTrackerImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/DependencyTrackerImpl.java?rev=1517469&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/DependencyTrackerImpl.java
(added)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/DependencyTrackerImpl.java
Mon Aug 26 08:58:30 2013
@@ -0,0 +1,291 @@
+/*
+ * 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.ace.agent.impl;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+/**
+ * Simple service dependency tracker that tracks a number of required dependencies and provides
life-cycle.
+ */
+public class DependencyTrackerImpl {
+
+    interface LifecycleCallbacks {
+        void started();
+
+        void stopped();
+    }
+
+    interface DependencyCallback {
+        void updated(Object service);
+    }
+
+    private final Set<ServiceDependency> m_dependencies = new HashSet<ServiceDependency>();
+    private final BundleContext m_bundleContext;
+    private final LifecycleCallbacks m_callbacks;
+    private volatile boolean m_tracking = false;
+    private volatile boolean m_started = false;
+
+    public DependencyTrackerImpl(BundleContext bundleContext, LifecycleCallbacks callbacks)
{
+        m_bundleContext = bundleContext;
+        m_callbacks = callbacks;
+    }
+
+    public BundleContext getBundleContext() {
+        return m_bundleContext;
+    }
+
+    public void addDependency(Class<?> iface, String extraFilter, DependencyCallback
inject) throws Exception {
+        synchronized (this) {
+            if (m_tracking) {
+                throw new IllegalStateException("Can not add dependecies while tracking");
+            }
+        }
+        Filter filter = null;
+        if (extraFilter != null) {
+            filter = FrameworkUtil.createFilter("(&(" + Constants.OBJECTCLASS + "=" +
iface.getName() + ")" + extraFilter + ")");
+        }
+        else {
+            filter = FrameworkUtil.createFilter("(" + Constants.OBJECTCLASS + "=" + iface.getName()
+ ")");
+        }
+        ServiceDependency dependency = new ServiceDependency(this, filter, inject);
+        m_dependencies.add(dependency);
+    }
+
+    public void startTracking() throws Exception {
+        synchronized (this) {
+            if (m_tracking) {
+                throw new IllegalStateException("Allready started tracking");
+            }
+            m_tracking = true;
+        }
+        for (ServiceDependency dependency : m_dependencies) {
+            dependency.startTracking();
+        }
+    }
+
+    public void stopTracking() {
+        synchronized (this) {
+            if (!m_tracking) {
+                throw new IllegalStateException("Did not start tracking yet");
+            }
+            m_tracking = false;
+        }
+        for (ServiceDependency dependency : m_dependencies) {
+            dependency.stopTracking();
+        }
+    }
+
+    private void update() {
+        // As this is a simple internal implementation we assume we can safely invoke
+        // callbacks while holding locks.
+        synchronized (this) {
+            if (!m_tracking) {
+                return;
+            }
+            if (dependenciesAvailable()) {
+                if (m_started) {
+                    stopCallback();
+                }
+                serviceCallbacks();
+                startCallback();
+            }
+            else {
+                stopCallback();
+                serviceCallbacks();
+            }
+        }
+    }
+
+    private boolean dependenciesAvailable() {
+        boolean available = true;
+        for (ServiceDependency dependency : m_dependencies) {
+            if (dependency.getService() == null) {
+                available = false;
+                break;
+            }
+        }
+        return available;
+    }
+
+    private void startCallback() {
+        try {
+            m_callbacks.started();
+            m_started = true;
+        }
+        catch (Exception e) {
+            // really must not happen
+            e.printStackTrace();
+        }
+    }
+
+    private void stopCallback() {
+        try {
+            m_callbacks.stopped();
+            m_started = false;
+        }
+        catch (Exception e) {
+            // really must not happen
+            e.printStackTrace();
+        }
+    }
+
+    private void serviceCallbacks() {
+        for (ServiceDependency dependency : m_dependencies) {
+            try {
+                dependency.invokeCallback();
+            }
+            catch (Exception e) {
+                // really must not happen
+                e.printStackTrace();
+            }
+        }
+    }
+
+    private static class ServiceDependency {
+
+        private final DependencyTrackerImpl m_manager;
+        private final Filter m_filter;
+        private final DependencyCallback m_calback;
+        private final ServiceTracker m_tracker;
+        private volatile Object m_service;
+
+        public ServiceDependency(DependencyTrackerImpl manager, Filter filter, DependencyCallback
callback) throws Exception {
+            m_manager = manager;
+            m_filter = filter;
+            m_calback = callback;
+            m_tracker = new ServiceDependencyTracker(this);
+        }
+
+        public BundleContext getBundleContext() {
+            return m_manager.getBundleContext();
+        }
+
+        public Filter getFilter() {
+            return m_filter;
+        }
+
+        public Object getService() {
+            return m_service;
+        }
+
+        public void startTracking() {
+            if (m_tracker == null) {
+            }
+            m_tracker.open();
+        }
+
+        public void stopTracking() {
+            m_tracker.close();
+        }
+
+        void invokeCallback() {
+            if (m_calback != null) {
+                m_calback.updated(m_service);
+            }
+        }
+
+        void changed(Object service) {
+            // Sync on manager to ensure all dependency updates happen in order
+            synchronized (m_manager) {
+                m_service = service;
+                m_manager.update();
+            }
+        }
+    }
+
+    /**
+     * Custom service tracker to simply construction.
+     * 
+     */
+    private static class ServiceDependencyTracker extends ServiceTracker {
+
+        public ServiceDependencyTracker(ServiceDependency dependency) {
+            super(dependency.getBundleContext(), dependency.getFilter(), new ServiceDependencyTrackerCustomizer(dependency));
+
+        }
+    }
+
+    /**
+     * Tracker customizer that calls AgentContextDependency#changed with the highest matching
service whenever something
+     * changes.
+     */
+    private static class ServiceDependencyTrackerCustomizer implements ServiceTrackerCustomizer
{
+
+        private final Map<ServiceReference, Object> m_trackedServices = new HashMap<ServiceReference,
Object>();
+        private final ServiceDependency m_dependency;
+        private volatile Object m_service;
+
+        public ServiceDependencyTrackerCustomizer(ServiceDependency dependency) {
+            m_dependency = dependency;
+        }
+
+        @Override
+        public Object addingService(ServiceReference reference) {
+            Object service = m_dependency.getBundleContext().getService(reference);
+            synchronized (m_trackedServices) {
+                m_trackedServices.put(reference, service);
+                checkForUpdate();
+                return service;
+            }
+        }
+
+        @Override
+        public void modifiedService(ServiceReference reference, Object service) {
+            synchronized (m_trackedServices) {
+                m_trackedServices.put(reference, service);
+                checkForUpdate();
+            }
+        }
+
+        @Override
+        public void removedService(ServiceReference reference, Object service) {
+            synchronized (m_trackedServices) {
+                m_trackedServices.remove(reference);
+                checkForUpdate();
+            }
+        }
+
+        private void checkForUpdate() {
+            ServiceReference highestReference = null;
+            if (!m_trackedServices.isEmpty()) {
+                for (ServiceReference reference : m_trackedServices.keySet()) {
+                    if (highestReference == null || highestReference.compareTo(reference)
< 1) {
+                        highestReference = reference;
+                    }
+                }
+            }
+            Object service = highestReference == null ? null : m_trackedServices.get(highestReference);
+            if (m_service == null || m_service != service) {
+                m_service = service;
+                m_dependency.changed(service);
+            }
+        }
+    }
+}

Modified: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/EventLoggerImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/EventLoggerImpl.java?rev=1517469&r1=1517468&r2=1517469&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/EventLoggerImpl.java (original)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/EventLoggerImpl.java Mon
Aug 26 08:58:30 2013
@@ -118,8 +118,7 @@ public class EventLoggerImpl implements 
             }
             eventType = AuditEvent.DEPLOYMENTADMIN_COMPLETE;
             props.put(AuditEvent.KEY_NAME, deplPackName);
-            Boolean success = (Boolean) event.getProperty("successful");
-            props.put(AuditEvent.KEY_SUCCESS, success.toString());
+            props.put(AuditEvent.KEY_SUCCESS, (String) event.getProperty("successful"));
         }
         writeEvent(eventType, props);
     }

Added: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/EventsHandler.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/EventsHandler.java?rev=1517469&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/EventsHandler.java (added)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/EventsHandler.java Mon Aug
26 08:58:30 2013
@@ -0,0 +1,32 @@
+/*
+ * 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.ace.agent.impl;
+
+import java.util.Dictionary;
+
+import org.apache.ace.agent.AgentContext;
+
+/**
+ * Agent context delegate interface that is responsible for handling events. This is an internal
interface as event
+ * methods are exposed on the {@link AgentContext} directly.
+ */
+public interface EventsHandler {
+
+    void postEvent(String topic, Dictionary<String, String> payload);
+}

Added: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/EventsHandlerImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/EventsHandlerImpl.java?rev=1517469&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/EventsHandlerImpl.java (added)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/EventsHandlerImpl.java Mon
Aug 26 08:58:30 2013
@@ -0,0 +1,77 @@
+/*
+ * 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.ace.agent.impl;
+
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventHandler;
+
+/**
+ * InternalEvents that posts events to internal handlers and external admins.
+ */
+public class EventsHandlerImpl implements EventsHandler {
+
+    private final Map<EventHandler, String[]> m_eventHandlers = new HashMap<EventHandler,
String[]>();
+
+    public void postEvent(String topic, Dictionary<String, String> payload) {
+        Event event = new Event(topic, payload);
+        postEvent(event);
+    }
+
+    public void postEvent(Event event) {
+        sendInternal(event);
+        sendExternal(event);
+    }
+
+    void registerHandler(EventHandler eventHandler, String[] topics) {
+        synchronized (m_eventHandlers) {
+            m_eventHandlers.put(eventHandler, topics);
+        }
+    }
+
+    void unregisterHandler(EventHandler eventHandler) {
+        synchronized (m_eventHandlers) {
+            m_eventHandlers.remove(eventHandler);
+        }
+    }
+
+    private void sendInternal(Event event) {
+        String topic = event.getTopic();
+        synchronized (m_eventHandlers) {
+            for (Entry<EventHandler, String[]> entry : m_eventHandlers.entrySet())
{
+                for (String interest : entry.getValue()) {
+                    if ((interest.endsWith("*") && topic.startsWith(interest.substring(0,
interest.length() - 1))
+                    || topic.equals(interest))) {
+                        entry.getKey().handleEvent(event);
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    private void sendExternal(Event event) {
+        // TODO this requires looking for all service references and invoking any found admins
using reflection
+    }
+
+}

Added: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/LoggingHandler.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/LoggingHandler.java?rev=1517469&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/LoggingHandler.java (added)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/LoggingHandler.java Mon Aug
26 08:58:30 2013
@@ -0,0 +1,74 @@
+/*
+ * 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.ace.agent.impl;
+
+import java.util.Formatter;
+
+import org.apache.ace.agent.AgentContext;
+
+/**
+ * Agent context delegate interface that is responsible for logging. This is an internal
interface as log methods are
+ * exposed on the {@link AgentContext} directly.
+ */
+public interface LoggingHandler {
+
+    /**
+     * Log an debug message. If <code>args</code> are provided the message will
be processed as a format using the
+     * standard {@link Formatter}.
+     * 
+     * @param component The component identifier, not <code>null</code>
+     * @param message The log message or format, not <code>null</code>
+     * @param cause The cause, may be <code>null</code>
+     * @param args The optional formatter arguments
+     */
+    void logDebug(String component, String message, Throwable exception, Object... args);
+
+    /**
+     * Log an info message. If <code>args</code> are provided the message will
be processed as a format using the
+     * standard {@link Formatter}.
+     * 
+     * @param component The component identifier, not <code>null</code>
+     * @param message The log message or format, not <code>null</code>
+     * @param cause The cause, may be <code>null</code>
+     * @param args The optional formatter arguments
+     */
+    void logInfo(String component, String message, Throwable exception, Object... args);
+
+    /**
+     * Log an warning message. If <code>args</code> are provided the message
will be processed as a format using the
+     * standard {@link Formatter}.
+     * 
+     * @param component The component identifier, not <code>null</code>
+     * @param message The log message or format, not <code>null</code>
+     * @param cause The cause, may be <code>null</code>
+     * @param args The optional formatter arguments
+     */
+    void logWarning(String component, String message, Throwable exception, Object... args);
+
+    /**
+     * Log an error message. If <code>args</code> are provided the message will
be processed as a format using the
+     * standard {@link Formatter}.
+     * 
+     * @param component The component identifier, not <code>null</code>
+     * @param message The log message or format, not <code>null</code>
+     * @param cause The cause, may be <code>null</code>
+     * @param args The optional formatter arguments
+     */
+    void logError(String component, String message, Throwable exception, Object... args);
+}

Added: ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/LoggingHandlerImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/LoggingHandlerImpl.java?rev=1517469&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/LoggingHandlerImpl.java (added)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/LoggingHandlerImpl.java Mon
Aug 26 08:58:30 2013
@@ -0,0 +1,71 @@
+/*
+ * 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.ace.agent.impl;
+
+import java.util.Date;
+
+import org.osgi.service.log.LogService;
+
+/**
+ * Internal logger that writes to system out for now. It minimizes work until it is determined
the loglevel is loggable.
+ */
+public class LoggingHandlerImpl implements LoggingHandler {
+
+    private final int m_level;
+
+    public LoggingHandlerImpl(int level) {
+        m_level = level;
+    }
+
+    private void log(String level, String component, String message, Throwable exception,
Object... args) {
+        if (args.length > 0)
+            message = String.format(message, args);
+        String line = String.format("[%s] %TT (%s) %s", level, new Date(), component, message);
+        System.out.println(line);
+        if (exception != null)
+            exception.printStackTrace(System.out);
+    }
+
+    @Override
+    public void logDebug(String component, String message, Throwable exception, Object...
args) {
+        if (m_level < LogService.LOG_DEBUG)
+            return;
+        log("DEBUG", component, message, exception, args);
+    }
+
+    @Override
+    public void logInfo(String component, String message, Throwable exception, Object...
args) {
+        if (m_level < LogService.LOG_INFO)
+            return;
+        log("INFO", component, message, exception, args);
+    }
+
+    @Override
+    public void logWarning(String component, String message, Throwable exception, Object...
args) {
+        if (m_level < LogService.LOG_WARNING)
+            return;
+        log("WARNING", component, message, exception, args);
+    }
+
+    @Override
+    public void logError(String component, String message, Throwable exception, Object...
args) {
+        log("ERROR", component, message, exception, args);
+    }
+
+}



Mime
View raw message