Package org.rioproject.cybernode.service

Source Code of org.rioproject.cybernode.service.ServiceBeanContainerImpl

/*
* Copyright to the original author or authors.
*
* Licensed 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.rioproject.cybernode.service;

import net.jini.config.Configuration;
import net.jini.id.Uuid;
import net.jini.id.UuidFactory;
import org.rioproject.impl.container.ServiceBeanContainer;
import org.rioproject.impl.container.ServiceBeanContainerListener;
import org.rioproject.impl.container.ServiceBeanDelegate;
import org.rioproject.impl.container.ServiceLogUtil;
import org.rioproject.deploy.ServiceBeanInstance;
import org.rioproject.deploy.ServiceBeanInstantiationException;
import org.rioproject.deploy.ServiceRecord;
import org.rioproject.event.EventHandler;
import org.rioproject.opstring.OperationalStringManager;
import org.rioproject.opstring.ServiceElement;
import org.rioproject.impl.system.ComputeResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

/**
* The ServiceBeanContainerImpl implements support for a ServiceBeanContainer
*
* @author Dennis Reedy
*/
public class ServiceBeanContainerImpl implements ServiceBeanContainer {
    /** identifier token */
    private final AtomicInteger token = new AtomicInteger(0);
    /** Whether or not we are in a shutdown mode */
    private final AtomicBoolean shutdownSequence = new AtomicBoolean(false);
    /** The ComputeResource attribute associated to this ServiceBeanContainer */
    private ComputeResource computeResource;
    /** Collection of ServiceBeanDelegates */
    private final Map<Object, ServiceBeanDelegate> controllerMap = new HashMap<Object, ServiceBeanDelegate>();
    /**
     * Count of activations that have registered with controllerMap but activate
     * routine has not finished.
     */
    private AtomicInteger activationInProcessCount = new AtomicInteger(0);
    /** Uuid for the container */
    private Uuid uuid;
    /** Collection of ServiceBeanContainerListeners */
    private final List<ServiceBeanContainerListener> listeners =
        Collections.synchronizedList(new ArrayList<ServiceBeanContainerListener>());
    /** Configuration object, which is also used as the shared configuration */
    private Configuration config;
    /** Logger */
    private static final Logger logger = LoggerFactory.getLogger("org.rioproject.cybernode");

    /**
     * Create a new ServiceBeanContainer
     *
     * @param config The Configuration to use
     */
    public ServiceBeanContainerImpl(Configuration config) {
        this.config = config;
    }

    /**
     * @see org.rioproject.impl.container.ServiceBeanContainer#getSharedConfiguration()
     */
    public Configuration getSharedConfiguration() {
        return (config);
    }

    /**
     * Set the computeResource property.
     *
     * @param computeResource The ComputeResource to use
     */
    public void setComputeResource(ComputeResource computeResource) {
        this.computeResource = computeResource;
    }

    /**
     * @see org.rioproject.impl.container.ServiceBeanContainer#getComputeResource()
     */
    public ComputeResource getComputeResource() {
        return (computeResource);
    }

    /**
     * Terminate the ServiceBeanContainer
     */
    public void terminate() {
        shutdownSequence.set(true);
        terminateServices();
    }
   
    /**
     * Terminate the ServiceBeanContainer
     */
    public void terminateServices() {
        ServiceBeanDelegate[] delegates;
        synchronized(controllerMap) {
            Collection<ServiceBeanDelegate> controllers = controllerMap.values();
            delegates = controllers.toArray(new ServiceBeanDelegate[controllers.size()]);
        }
        for (ServiceBeanDelegate delegate : delegates) {
            delegate.terminate();
        }
        synchronized(controllerMap) {
            controllerMap.clear();
        }
    }

    /**
     * @see org.rioproject.impl.container.ServiceBeanContainer#getServiceRecords
     */
    public ServiceRecord[] getServiceRecords() {
        List<ServiceRecord> list = new ArrayList<ServiceRecord>();
        ServiceBeanDelegate[] delegates;
        synchronized(controllerMap) {
            Collection<ServiceBeanDelegate> controllers = controllerMap.values();
            delegates = controllers.toArray(new ServiceBeanDelegate[controllers.size()]);
        }
        for (ServiceBeanDelegate delegate : delegates) {
            ServiceRecord record = delegate.getServiceRecord();
            if (record != null) {
                list.add(record);
            }
        }
        return (list.toArray(new ServiceRecord[list.size()]));
    }

    /**
     * @see org.rioproject.impl.container.ServiceBeanContainer#getServiceCounter()
     */
    public synchronized int getServiceCounter() {
        int size;
        synchronized(controllerMap) {
            size = controllerMap.size();
        }
        return (size);
    }

    /**
     * @see org.rioproject.impl.container.ServiceBeanContainer#getActivationInProcessCount()
     */
    public int getActivationInProcessCount() {
        return activationInProcessCount.get();
    }
   
    /**
     * @see org.rioproject.impl.container.ServiceBeanContainer#activate
     */
    public ServiceBeanInstance activate(ServiceElement sElem,
                                        OperationalStringManager opStringMgr,
                                        EventHandler slaEventHandler)
    throws ServiceBeanInstantiationException {
        Uuid serviceID = UuidFactory.generate();
        Integer identifier = token.incrementAndGet();

        ServiceBeanDelegateImpl delegate = new ServiceBeanDelegateImpl(identifier, serviceID, this);
        delegate.setOperationalStringManager(opStringMgr);
        delegate.setServiceElement(sElem);
        delegate.setEventHandler(slaEventHandler);
        synchronized(controllerMap) {
            controllerMap.put(identifier, delegate);
            activationInProcessCount.incrementAndGet();
        }
        boolean started = false;
        ServiceBeanInstance loadedInstance = null;
        try {
            loadedInstance = delegate.load();
            started = true;
            /* notification to shutdown may have come in the middle of
             * service creation, if it did, terminate */
            if(shutdownSequence.get()) {
                delegate.terminate();
                throw new ServiceBeanInstantiationException("Resource unavailable, shutting down");
            }
            if(sElem.getAutoAdvertise()) {
                delegate.advertise();
            }

        } catch(ServiceBeanInstantiationException e) {
            if(started) {
                discarded(identifier);
                delegate.terminate();
            }
            /* rethrow ServiceBeanInstantiationException */
            throw e;
        } catch(Throwable t) {
            if(started) {
                discarded(identifier);
                delegate.terminate();
            }
            logger.error("Could not activate service {}", ServiceLogUtil.logName(sElem), t);
            throw new ServiceBeanInstantiationException(String.format("Service %s load failed", ServiceLogUtil.logName(sElem)),
                                                        t, true);
        } finally {
            activationInProcessCount.decrementAndGet();
        }
        return (loadedInstance);
    }
   
    /**
     * @see org.rioproject.impl.container.ServiceBeanContainer#update
     */
    public void update(ServiceElement[] elements,  OperationalStringManager opStringMgr) {
        if(elements==null) {
            throw new IllegalArgumentException("elements is null");
        }
        if(opStringMgr==null) {
            throw new IllegalArgumentException("opStringMgr is null");
        }

        for (ServiceElement element : elements) {
            ServiceBeanDelegate[] delegates = getDelegates(element);
            for (ServiceBeanDelegate delegate : delegates) {
                //if(delegate.getServiceRecord().getDiscardedDate()!=null) {
                if(delegate.isActive()) {
                    delegate.update(element, opStringMgr);
                } else {
                    logger.warn(String.format("Service %s has been discarded, do not update",
                                              ServiceLogUtil.logName(element)));
                }
            }
        }
    }

    /**
     * @see org.rioproject.impl.container.ServiceBeanContainer#getServiceBeanInstances
     */
    public ServiceBeanInstance[] getServiceBeanInstances(ServiceElement element) {
        List<ServiceBeanInstance> list = new ArrayList<ServiceBeanInstance>();
        ServiceBeanDelegate[] delegates = getDelegates(element);
        for (ServiceBeanDelegate delegate : delegates) {
            ServiceBeanInstance instance = delegate.getServiceBeanInstance();
            if (instance != null) {
                list.add(instance);
            }
        }
        return (list.toArray(new ServiceBeanInstance[list.size()]));
    }

    public void setUuid(Uuid uuid) {
        this.uuid = uuid;
    }

    public Uuid getUuid() {
        return uuid;
    }

    /*
    * Get all ServiceBeanDelegate instances for a ServiceElement
    */
    public ServiceBeanDelegate[] getDelegates(ServiceElement element) {
        ServiceBeanDelegate[] delegates = getDelegates();
        if(element!=null) {
            ArrayList<ServiceBeanDelegate> list = new ArrayList<ServiceBeanDelegate>();
            for (ServiceBeanDelegate delegate : delegates) {
                if (delegate.getServiceElement().equals(element)) {
                    list.add(delegate);
                }
            }
            delegates = list.toArray(new ServiceBeanDelegate[list.size()]);
        }
        return(delegates);
    }

    /**
     * @see org.rioproject.impl.container.ServiceBeanContainer#started(Object)
     */
    public void started(Object identifier) {
        ServiceBeanDelegate delegate;
        synchronized(controllerMap) {
            delegate = controllerMap.get(identifier);
        }
        if(delegate == null) {
            return;
        }
        ServiceRecord record = delegate.getServiceRecord();
        if(record==null) {
            logger.warn("ServiceRecord for [{}] is null, no way to notify container of instantiation",
                           delegate.getServiceElement().getName());
            return;
        }
        notifyOnInstantiation(delegate.getServiceRecord());
    }

    /**
     * @see org.rioproject.impl.container.ServiceBeanContainer#discarded(Object)
     */
    public void discarded(Object identifier) {
        ServiceBeanDelegate delegate;
        synchronized(controllerMap) {
            delegate = controllerMap.get(identifier);
        }
        if(delegate == null)
            return;
        notifyOnDiscard(delegate.getServiceRecord());
    }

    /**
     * @see org.rioproject.impl.container.ServiceBeanContainer#remove(Object)
     */
    public void remove(Object identifier) {
        if(shutdownSequence.get())
            return;
        synchronized(controllerMap) {
            controllerMap.remove(identifier);
        }
    }

    /**
     * @see org.rioproject.impl.container.ServiceBeanContainer#addListener
     */
    public synchronized void addListener(ServiceBeanContainerListener l) {
        if(!listeners.contains(l))
            listeners.add(l);
    }

    /**
     * @see org.rioproject.impl.container.ServiceBeanContainer#addListener
     */
    public synchronized void removeListener(ServiceBeanContainerListener l) {
        listeners.remove(l);
    }

    public ServiceBeanDelegate getServiceBeanDelegate(Uuid serviceUuid) {
        ServiceBeanDelegate delegate = null;
        ServiceBeanDelegate[] delegates = getDelegates();
        for(ServiceBeanDelegate d : delegates) {
            if(d.getServiceBeanInstance()!=null &&
               d.getServiceBeanInstance().getServiceBeanID().equals(serviceUuid)) {
                delegate = d;
                break;
            }
        }
        return delegate;
    }

    /*
     * Notify all <code>ServiceBeanContainerListener</code> objects that a
     * ServiceBean has just been instantiated
     */
    void notifyOnInstantiation(ServiceRecord serviceRecord) {
        ServiceBeanContainerListener[] scl;
        synchronized(listeners) {
            scl = listeners.toArray(new ServiceBeanContainerListener[listeners.size()]);
        }
        for(ServiceBeanContainerListener l : scl)
            l.serviceInstantiated(serviceRecord);
    }

    /*
     * Notify all <code>ServiceBeanContainerListener</code> objects that a
     * ServiceBean has just been discarded
     */
    void notifyOnDiscard(ServiceRecord serviceRecord) {
        Object[] arrLocal = listeners.toArray();
        for(int i = arrLocal.length - 1; i >= 0; i--)
            ((ServiceBeanContainerListener)arrLocal[i]).serviceDiscarded(serviceRecord);
    }

    ServiceBeanDelegate[] getDelegates() {
        ServiceBeanDelegate[] delegates;
        synchronized(controllerMap) {
            Collection<ServiceBeanDelegate> controllers = controllerMap.values();
            delegates = controllers.toArray(new ServiceBeanDelegate[controllers.size()]);
        }
        return delegates;
    }

}
TOP

Related Classes of org.rioproject.cybernode.service.ServiceBeanContainerImpl

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.