Package org.apache.ace.agent.impl

Source Code of org.apache.ace.agent.impl.Activator

/*
* 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.io.File;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.ace.agent.AgentConstants;
import org.apache.ace.agent.AgentControl;
import org.apache.ace.agent.AgentUpdateHandler;
import org.apache.ace.agent.ConfigurationHandler;
import org.apache.ace.agent.ConnectionHandler;
import org.apache.ace.agent.DeploymentHandler;
import org.apache.ace.agent.DiscoveryHandler;
import org.apache.ace.agent.DownloadHandler;
import org.apache.ace.agent.EventsHandler;
import org.apache.ace.agent.FeedbackHandler;
import org.apache.ace.agent.IdentificationHandler;
import org.apache.ace.agent.LoggingHandler;
import org.apache.ace.agent.impl.DependencyTrackerImpl.DependencyCallback;
import org.apache.ace.agent.impl.DependencyTrackerImpl.LifecycleCallback;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.packageadmin.PackageAdmin;

/**
* Bundle activator for ACE management agent.
*/
public class Activator implements BundleActivator, LifecycleCallback {
    // managed state
    private volatile AgentContextImpl m_agentContext;
    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;
    private volatile IdentificationHandler m_identificationHandler;
    private volatile DiscoveryHandler m_discoveryHandler;
    private volatile ConnectionHandler m_connectionHandler;

    /**
     * Called by OSGi framework when starting this bundle. It will start a bare dependency manager for tracking several
     * of the (configurable) services. Once all dependencies are satisfied, {@link #componentStarted(BundleContext)}
     * will be called.
     */
    @Override
    public void start(BundleContext bundleContext) throws Exception {
        // Essentially a two-threaded executor with scheduling support, one thread is "reserved" for the controller...
        m_executorService = new ScheduledThreadPoolExecutor(2 /* core pool size */, new InternalThreadFactory());

        m_dependencyTracker = new DependencyTrackerImpl(bundleContext, this);

        addPackageAdminDependency(m_dependencyTracker);

        if (getBoolean(bundleContext, AgentConstants.CONFIG_IDENTIFICATION_DISABLED)) {
            addIdentificationHandlerDependency(m_dependencyTracker);
        }

        if (getBoolean(bundleContext, AgentConstants.CONFIG_DISCOVERY_DISABLED)) {
            addDiscoveryHandlerDependency(m_dependencyTracker);
        }

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

    /**
     * Called by OSGi framework when stopping this bundle.
     */
    @Override
    public void stop(BundleContext context) throws Exception {
        try {
            m_dependencyTracker.stopTracking();
        }
        finally {
            m_executorService.shutdownNow();
            m_executorService = null;
        }
    }

    /**
     * Called by our {@link DependencyTrackerImpl} when all dependencies are satisfied.
     */
    public void componentStarted(BundleContext context) throws Exception {
        final File bundleDataArea = context.getDataFile("");

        m_agentContext = new AgentContextImpl(bundleDataArea);

        m_agentContext.setHandler(LoggingHandler.class, new LoggingHandlerImpl(context));
        m_agentContext.setHandler(ConfigurationHandler.class, new ConfigurationHandlerImpl(context));
        m_agentContext.setHandler(EventsHandler.class, new EventsHandlerImpl(context));
        m_agentContext.setHandler(ScheduledExecutorService.class, m_executorService);
        m_agentContext.setHandler(DownloadHandler.class, new DownloadHandlerImpl(bundleDataArea));
        m_agentContext.setHandler(DeploymentHandler.class, new DeploymentHandlerImpl(context, m_packageAdmin));
        m_agentContext.setHandler(AgentUpdateHandler.class, new AgentUpdateHandlerImpl(context));
        m_agentContext.setHandler(FeedbackHandler.class, new FeedbackHandlerImpl());

        IdentificationHandler identificationHandler = (m_identificationHandler != null) ? m_identificationHandler : new IdentificationHandlerImpl();
        m_agentContext.setHandler(IdentificationHandler.class, identificationHandler);

        DiscoveryHandler discoveryHandler = (m_discoveryHandler != null) ? m_discoveryHandler : new DiscoveryHandlerImpl();
        m_agentContext.setHandler(DiscoveryHandler.class, discoveryHandler);

        ConnectionHandler connectionHandler = (m_connectionHandler != null) ? m_connectionHandler : new ConnectionHandlerImpl();
        m_agentContext.setHandler(ConnectionHandler.class, connectionHandler);

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

    /**
     * Called by our {@link DependencyTrackerImpl} when one or more dependencies are no longer satisfied.
     */
    public void componentStopped(BundleContext context) throws Exception {
        try {
            if (m_agentControlRegistration != null) {
                m_agentControlRegistration.unregister();
            }
        }
        finally {
            m_agentControlRegistration = null;

            try {
                m_agentContext.stop();
            }
            finally {
                m_agentContext = null;
            }
        }
    }

    private void addConnectionHandlerDependency(DependencyTrackerImpl tracker) throws Exception {
        tracker.addDependency(ConnectionHandler.class, null, new DependencyCallback() {
            @Override
            public void updated(Object service) {
                m_connectionHandler = (ConnectionHandler) service;
            }
        });
    }

    private void addDiscoveryHandlerDependency(DependencyTrackerImpl tracker) throws Exception {
        tracker.addDependency(DiscoveryHandler.class, null, new DependencyCallback() {
            @Override
            public void updated(Object service) {
                m_discoveryHandler = (DiscoveryHandler) service;
            }
        });
    }

    private void addIdentificationHandlerDependency(DependencyTrackerImpl tracker) throws Exception {
        tracker.addDependency(IdentificationHandler.class, null, new DependencyCallback() {
            @Override
            public void updated(Object service) {
                m_identificationHandler = (IdentificationHandler) service;
            }
        });
    }

    private void addPackageAdminDependency(DependencyTrackerImpl tracker) throws Exception {
        tracker.addDependency(PackageAdmin.class, null, new DependencyCallback() {
            @Override
            public void updated(Object service) {
                m_packageAdmin = (PackageAdmin) service;
            }
        });
    }

    /**
     * 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 {
        private static final String NAME_TPL = "ACE Agent Worker %s";
        private final AtomicInteger m_count = new AtomicInteger();

        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r, String.format(NAME_TPL, m_count.incrementAndGet()));
        }
    }
}
TOP

Related Classes of org.apache.ace.agent.impl.Activator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.