Package org.apache.karaf.eik.workbench.internal

Source Code of org.apache.karaf.eik.workbench.internal.KarafRuntimeDataProvider

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.karaf.eik.workbench.internal;

import org.apache.karaf.eik.workbench.KarafWorkbenchActivator;
import org.apache.karaf.eik.workbench.MBeanProvider;
import org.apache.karaf.eik.workbench.provider.AbstractRuntimeDataProvider;
import org.apache.karaf.eik.workbench.provider.BundleItem;
import org.apache.karaf.eik.workbench.provider.RuntimeDataProvider;
import org.apache.karaf.eik.workbench.provider.RuntimeDataProviderListener;
import org.apache.karaf.eik.workbench.provider.ServiceItem;

import java.io.IOException;
import java.util.EnumSet;

import javax.management.ObjectName;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.TabularData;

import org.apache.aries.jmx.codec.ServiceData;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.swt.graphics.Image;
import org.osgi.jmx.framework.BundleStateMBean;
import org.osgi.jmx.framework.ServiceStateMBean;

public class KarafRuntimeDataProvider extends AbstractRuntimeDataProvider {

    private static final ObjectName BUNDLE_STATE;

    @SuppressWarnings("unused")
    private static final ObjectName CM_SERVICE;

    @SuppressWarnings("unused")
    private static final ObjectName PACKAGE_STATE;

    private static final ObjectName SERVICE_STATE;

    /*
     * If this throws an exception we're in trouble because it means that the
     * constants are invalid
     */
    static {
        try {
            BUNDLE_STATE = new ObjectName("osgi.core:type=bundleState,version=1.5");
            CM_SERVICE = new ObjectName("osgi.core:type=cm,version=1.3");
            PACKAGE_STATE = new ObjectName("osgi.core:type=packageState,version=1.5");
            SERVICE_STATE = new ObjectName("osgi.core:type=serviceState,version=1.5");
        } catch (final Exception e) {
            throw new IllegalStateException("The OSGi JMX implementation references an invalid ObjectName", e);
        }
    }

    private final String name;

    private final MBeanProvider mbeanProvider;

    /**
     * Updates the runtime data referenced by the {@link BundleStateMBean} and
     * {@link ServiceStateMBean}
     */
    private final Job updateDataJob;

    /**
     * A {@link RuntimeDataProvider} implementation specific to Karaf instances
     * being run/debugged in Eclipse.
     *
     * @param name
     *            the human readable name of this provider
     * @param provider
     *            the {@link MBeanProvider} for the running Karaf instance
     */
    public KarafRuntimeDataProvider(final String name, final MBeanProvider provider) {
        super();

        this.name = name;
        this.mbeanProvider = provider;

        this.updateDataJob = new Job("Populating OSGi Runtime view data for: " + name) {

            private volatile boolean cancel = false;

            @Override
            public IStatus run(IProgressMonitor monitor) {
                if (monitor == null) {
                    monitor = new NullProgressMonitor();
                }

                if (   !KarafRuntimeDataProvider.this.mbeanProvider.isOpen()
                    && !cancel)
                {
                    this.schedule(25000);
                }

                monitor.beginTask("Populating view data set", IProgressMonitor.UNKNOWN);

                IStatus status = loadBundleData(monitor);
                if (!status.isOK()) {
                    // Do something?
                }

                if (monitor.isCanceled()) {
                    return Status.OK_STATUS;
                }

                status = loadServiceData(monitor);
                if (!status.isOK()) {
                    // Do something?
                }

                monitor.done();

                if (monitor.isCanceled()) {
                    return Status.OK_STATUS;
                }

                if (!cancel) {
                    /*
                     * Poll every 25 seconds because the MBeans are not notification
                     * enabled
                     */
                    this.schedule(25000);
                }

                fireProviderChangeEvent(EnumSet.of(RuntimeDataProviderListener.EventType.CHANGE));

                return Status.OK_STATUS;
            }

            @Override
            protected void canceling() {
                cancel = true;
            }
        };

        this.updateDataJob.setSystem(true);
        this.updateDataJob.setPriority(Job.LONG);
    }

    @Override
    public Object getAdapter(@SuppressWarnings("rawtypes") final Class adapter) {
        if (MBeanProvider.class.equals(adapter)) {
            return mbeanProvider;
        } else {
            return super.getAdapter(adapter);
        }
    }

    @Override
    public Image getIcon() {
        return KarafWorkbenchActivator.getDefault().getImageRegistry().get(KarafWorkbenchActivator.LOGO_16X16_IMG);
    }

    @Override
    public String getName() {
        return name;
    }

    /**
     * Starts the {@link RuntimeDataProvider} which will collect the OSGi
     * runtime information from the running Karaf instance.
     */
    @Override
    public void start() {
        fireStartEvent();

        updateDataJob.schedule();
    }

    @Override
    public void stop() {
        updateDataJob.cancel();

        synchronized (bundleSet) {
            bundleSet.clear();
            idToBundleMap.clear();
        }

        synchronized (serviceSet) {
            serviceSet.clear();
            idToServiceMap.clear();
        }

        fireStopEvent();
    }

    private IStatus loadBundleData(final IProgressMonitor monitor) {
        monitor.subTask("OSGi Bundles");

        if (monitor.isCanceled()) {
            return Status.OK_STATUS;
        }

        if (!mbeanProvider.isOpen()) {
            return new Status(IStatus.WARNING, KarafWorkbenchActivator.PLUGIN_ID, "Connection to MBean server has been closed");
        }

        try {
            final TabularData rawBundleData = mbeanProvider.getMBean(BUNDLE_STATE, BundleStateMBean.class).listBundles();

            synchronized (bundleSet) {
                bundleSet.clear();
                idToBundleMap.clear();
            }

            for (final Object o : rawBundleData.values()) {
                final CompositeData composite = (CompositeData) o;
                final BundleItem bundle = new BundleItem(composite);

                synchronized (bundleSet) {
                    bundleSet.add(bundle);
                    idToBundleMap.put(bundle.getIdentifier(), bundle);
                }

                monitor.worked(1);

                if (monitor.isCanceled()) {
                    break;
                }

            }

        } catch (final IOException e) {
            return new Status(IStatus.ERROR, KarafWorkbenchActivator.PLUGIN_ID, "Unable to connect to MBeanServer", e);
        } catch (final Exception e) {
            KarafWorkbenchActivator.getLogger().warn("Unable to update OSGi Bundles", e);
        }

        return Status.OK_STATUS;
    }

    private IStatus loadServiceData(final IProgressMonitor monitor) {
        monitor.subTask("OSGi Services");

        if (monitor.isCanceled()) {
            return Status.OK_STATUS;
        }

        if (!mbeanProvider.isOpen()) {
            return new Status(IStatus.WARNING, KarafWorkbenchActivator.PLUGIN_ID, "Connection to MBean server has been closed");
        }

        try {
            final TabularData rawServiceData = mbeanProvider.getMBean(SERVICE_STATE, ServiceStateMBean.class).listServices();

            synchronized (serviceSet) {
                serviceSet.clear();
                idToServiceMap.clear();
            }

            for (final Object o : rawServiceData.values()) {
                final CompositeData composite = (CompositeData) o;
                final ServiceData service = ServiceData.from(composite);

                /*
                 * Get the service's properties from the JMX enabled runtime
                 */
                if (!mbeanProvider.isOpen()) {
                    return new Status(IStatus.WARNING, KarafWorkbenchActivator.PLUGIN_ID, "Connection to MBean server has been closed");
                }

                final ServiceItem serviceWrapper = new MBeanServiceItem(composite, mbeanProvider, idToBundleMap);

                synchronized (serviceSet) {
                    serviceSet.add(serviceWrapper);
                    idToServiceMap.put(service.getServiceId(), serviceWrapper);
                }

                monitor.worked(1);

                if (monitor.isCanceled()) {
                    break;
                }

            }
        } catch (final IOException e) {
          if (monitor.isCanceled()) {
            return new Status(IStatus.CANCEL, KarafWorkbenchActivator.PLUGIN_ID, "Unable to connect to MBeanServer", e);
          } else {
            return new Status(IStatus.ERROR, KarafWorkbenchActivator.PLUGIN_ID, "Unable to connect to MBeanServer", e);
          }
        } catch (final Exception e) {
            KarafWorkbenchActivator.getLogger().warn("Unable to update OSGi Services", e);
        }

        return Status.OK_STATUS;
    }

}
TOP

Related Classes of org.apache.karaf.eik.workbench.internal.KarafRuntimeDataProvider

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.