Author: jawi
Date: Thu Nov 28 10:27:26 2013
New Revision: 1546335
URL: http://svn.apache.org/r1546335
Log:
ACE-433 - preparing agent for custom controller handling:
- the default controller is a component that is handled like all other
components. While this works, the controller is actually a 'special'
beast for the agent: it controls everything for the agent. Hence,
it should have a more explicit place in the (internal) API of the
agent;
- when using a custom controller, the old controller needs to be
disabled, but still was created and invoked albeit for a short time.
This while a custom controller still needs to be packaged along with
the rest of the agent (for all kinds of reasons), so it makes much
more sense to load this custom controller at startup instead of the
default one. For this, we've added a new property that allows one to
specify the FQCN of the custom controller. In case this property is
omitted, the default controller is loaded and used;
- fixed a small issue where system properties were always used instead
of framework properties.
Modified:
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/AgentConstants.java
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/AgentContextImpl.java
Modified:
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/AgentConstants.java
URL:
http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/AgentConstants.java?rev=1546335&r1=1546334&r2=1546335&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/AgentConstants.java
(original)
+++ ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/AgentConstants.java
Thu Nov 28 10:27:26 2013
@@ -85,12 +85,25 @@ public interface AgentConstants {
String CONFIG_DISCOVERY_CHECKING = CONFIG_KEY_NAMESPACE +
".discovery.checking";
/**
+ * Configuration option to override the default controller with another
implementation. This custom implementation
+ * is expected to be in the same bundle as the agent. Should be a fully
qualified class name, and if omitted, the
+ * default controller will be used.
+ * <p>
+ * Note that this property is expected to be set as system or environment
setting!
+ * </p>
+ */
+ String CONFIG_CONTROLLER_CLASS = CONFIG_KEY_NAMESPACE +
".controller.class";
+
+ /**
* Configuration option to disable the default controller. When set to
true some other bundle control the agent's
* behavior. Should be <code>{true,false}</code>, default is
<code>false</code>.
* <p>
* Note that this property is expected to be set as system or environment
setting!
* </p>
+ *
+ * @deprecated use {@link #CONFIG_CONTROLLER_CLASS} instead!
*/
+ @Deprecated
String CONFIG_CONTROLLER_DISABLED = CONFIG_KEY_NAMESPACE +
".controller.disabled";
/**
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=1546335&r1=1546334&r2=1546335&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
Thu Nov 28 10:27:26 2013
@@ -52,6 +52,7 @@ public class Activator implements Bundle
private volatile ScheduledExecutorService m_executorService;
private volatile ServiceRegistration m_agentControlRegistration;
private volatile DependencyTrackerImpl m_dependencyTracker;
+ private volatile Object m_controller;
// injected services
private volatile PackageAdmin m_packageAdmin;
@@ -73,18 +74,21 @@ public class Activator implements Bundle
addPackageAdminDependency(m_dependencyTracker);
- if (Boolean.getBoolean(AgentConstants.CONFIG_IDENTIFICATION_DISABLED))
{
+ if (getBoolean(bundleContext,
AgentConstants.CONFIG_IDENTIFICATION_DISABLED)) {
addIdentificationHandlerDependency(m_dependencyTracker);
}
- if (Boolean.getBoolean(AgentConstants.CONFIG_DISCOVERY_DISABLED)) {
+ if (getBoolean(bundleContext,
AgentConstants.CONFIG_DISCOVERY_DISABLED)) {
addDiscoveryHandlerDependency(m_dependencyTracker);
}
- if (Boolean.getBoolean(AgentConstants.CONFIG_CONNECTION_DISABLED)) {
+ if (getBoolean(bundleContext,
AgentConstants.CONFIG_CONNECTION_DISABLED)) {
addConnectionHandlerDependency(m_dependencyTracker);
}
+ // Create the controller in this method will ensure that if this
fails, this bundle is *not* started...
+ m_controller = createAgentController(bundleContext);
+
m_dependencyTracker.startTracking();
}
@@ -128,9 +132,11 @@ public class Activator implements Bundle
ConnectionHandler connectionHandler = (m_connectionHandler != null) ?
m_connectionHandler : new ConnectionHandlerImpl();
m_agentContext.setHandler(ConnectionHandler.class, connectionHandler);
- m_agentContext.addComponent(new DefaultController());
m_agentContext.addComponent(new EventLoggerImpl(context));
+ // Lastly, inject the (custom) controller for this agent...
+ m_agentContext.setController(m_controller);
+
m_agentContext.start();
m_agentControlRegistration =
context.registerService(AgentControl.class.getName(), new
AgentControlImpl(m_agentContext), null);
@@ -194,6 +200,43 @@ public class Activator implements Bundle
}
/**
+ * Factory method for creating the agent controller.
+ *
+ * @param context
+ * the bundle context to use, cannot be <code>null</code>.
+ * @return a controller instance, never <code>null</code>.
+ * @throws ClassNotFoundException
+ * in case a custom controller class was defined, but this
class could not be loaded;
+ * @throws IllegalAccessException
+ * in case a custom controller class was defined, but did not
have a public default constructor;
+ * @throws InstantiationException
+ * in case a custom controller class was defined, but
instantiation lead to an exception.
+ */
+ private Object createAgentController(BundleContext context) throws
ClassNotFoundException, InstantiationException, IllegalAccessException {
+ String controllerName =
context.getProperty(AgentConstants.CONFIG_CONTROLLER_CLASS);
+ if (controllerName != null) {
+ Class<?> controllerClass =
context.getBundle().loadClass(controllerName);
+ return controllerClass.newInstance();
+ }
+ return new DefaultController();
+ }
+
+ /**
+ * Retrieves the bundle (or system) property with the given name and
returns <code>true</code> iff the value of that
+ * property is "true" (case insensitive).
+ *
+ * @param bundleContext
+ * the bundle context to use;
+ * @param propertyName
+ * the name of the boolean property to retrieve.
+ * @return <code>true</code> iff the value of the property was "true"
(case insenstive), <code>false</code>
+ * otherwise.
+ */
+ private static boolean getBoolean(BundleContext bundleContext, String
propertyName) {
+ return Boolean.parseBoolean(bundleContext.getProperty(propertyName));
+ }
+
+ /**
* Internal thread factory that assigns recognizable names to the threads
it creates and sets them in daemon mode.
*/
public static class InternalThreadFactory implements ThreadFactory {
@@ -202,14 +245,7 @@ public class Activator implements Bundle
@Override
public Thread newThread(Runnable r) {
- Thread thread = new Thread(r, String.format(NAME_TPL,
m_count.incrementAndGet()));
- // TODO JaWi: is this really what we want? This means that these
threads can be
- // shutdown without any means to cleanup (can cause I/O errors,
file corruption,
- // a new world order, ...)
- thread.setDaemon(true);
- // TODO JaWi: shouldn't we set the uncaught exception handler for
these kind of
- // threads? It would allow us to explicitly log something when
things go wrong...
- return thread;
+ return new Thread(r, String.format(NAME_TPL,
m_count.incrementAndGet()));
}
}
}
Modified:
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/AgentContextImpl.java
URL:
http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/AgentContextImpl.java?rev=1546335&r1=1546334&r2=1546335&view=diff
==============================================================================
---
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/AgentContextImpl.java
(original)
+++
ace/trunk/org.apache.ace.agent/src/org/apache/ace/agent/impl/AgentContextImpl.java
Thu Nov 28 10:27:26 2013
@@ -94,6 +94,8 @@ public class AgentContextImpl implements
for (Object component : m_components) {
startAgentContextAware(component);
}
+
+ // TODO correctly handle custom controller components!
}
/**
@@ -137,15 +139,26 @@ public class AgentContextImpl implements
}
/**
- * Add a component on the context.
+ * Adds a component to this context.
*
* @param component
- * The component
+ * The component to add, cannot be <code>null</code>.
*/
- public void addComponent(AgentContextAware component) {
+ public void addComponent(Object component) {
m_components.add(component);
}
+ /**
+ * Sets the controller to use for the agent.
+ *
+ * @param controller
+ * the controller to use, cannot be <code>null</code>.
+ */
+ public void setController(Object controller) {
+ // For now this ensures the same behaviour as we had. This will change
in the near future!
+ addComponent(controller);
+ }
+
private void initAgentContextAware(Object object) throws Exception {
if (object instanceof AgentContextAware) {
try {