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);
+ }
+
+}