Package org.apache.geronimo.farm.discovery.wadi

Source Code of org.apache.geronimo.farm.discovery.wadi.WADIDiscoveryAgent$NodeServiceHandlerThread

/**
* 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.geronimo.farm.discovery.wadi;

import java.io.IOException;
import java.net.URI;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicBoolean;

import org.apache.geronimo.clustering.wadi.BasicWADISessionManager;
import org.apache.geronimo.clustering.wadi.BasicWADISessionManagerHolder;
import org.apache.geronimo.farm.discovery.DiscoveryAgent;
import org.apache.geronimo.farm.discovery.DiscoveryListener;
import org.apache.geronimo.farm.service.NodeServiceTracker;
import org.apache.geronimo.farm.service.NodeServiceTrackerListener;
import org.apache.geronimo.farm.service.NodeServiceVitals;
import org.apache.geronimo.gbean.GBeanInfoBuilder;
import org.apache.geronimo.gbean.GBeanLifecycle;
import org.apache.geronimo.gbean.annotation.GBean;
import org.apache.geronimo.gbean.annotation.ParamAttribute;
import org.apache.geronimo.gbean.annotation.ParamReference;
import org.codehaus.wadi.servicespace.InvocationMetaData;
import org.codehaus.wadi.servicespace.ServiceProxy;
import org.codehaus.wadi.servicespace.ServiceProxyFactory;
import org.codehaus.wadi.servicespace.ServiceRegistry;
import org.codehaus.wadi.servicespace.ServiceSpace;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* @version $Rev$ $Date$
*/
@GBean(name = "WADIDiscoveryAgent", j2eeType = GBeanInfoBuilder.DEFAULT_J2EE_TYPE)
public class WADIDiscoveryAgent implements DiscoveryAgent, GBeanLifecycle {

    static final Logger log = LoggerFactory.getLogger(WADIDiscoveryAgent.class);

    private final BasicWADISessionManager WADISessionManager;
    private NodeServiceTracker localTracker;
    private NodeServiceTracker clusterNodeServiceTrackerProxy;

    private AtomicBoolean started = new AtomicBoolean(false);

    private int maxMissedHeartbeats = 10;
    private long heartRate = 500;

    private final NodeServiceHandlerThread listener;

    private final String localNodeName;

    public WADIDiscoveryAgent(
            @ParamReference(name = "BasicWADISessionManagerHolder") BasicWADISessionManagerHolder WADISessionManagerHolder,
            @ParamAttribute(name = "heartRate") long heartRate,
            @ParamAttribute(name = "maxMissedHeartbeats") int maxMissedHeartbeats) {

        this.WADISessionManager = WADISessionManagerHolder.getBasicWADISessionManager();
        this.heartRate = heartRate;
        this.maxMissedHeartbeats = maxMissedHeartbeats;
        this.localNodeName = WADISessionManager.getNode().getName();
        listener = new NodeServiceHandlerThread();
    }

    public String getName() {
        return "WADI disovery Agent";
    }

    /* start of discoveryAgent interface implementation *************** */
    public void setDiscoveryListener(final DiscoveryListener listener) {
        // this.listener.setDiscoveryListener(listener);

        localTracker.addNodeServiceTrackerListener(new NodeServiceTrackerListener() {

            public void serviceAdded(URI service) {
                listener.serviceAdded(service);

            }

            public void serviceRemoved(URI service) {
                listener.serviceRemoved(service);

            }

        });
    }

    public void registerService(URI serviceUri) throws IOException {

        localTracker.registerLocalNodeService(serviceUri);

        // register local service to remote peers
        clusterNodeServiceTrackerProxy.registerNodeService(localNodeName, serviceUri);
    }

    public void unregisterService(URI serviceUri) throws IOException {

        localTracker.unregisterNodeService(localNodeName, serviceUri);

        clusterNodeServiceTrackerProxy.unregisterNodeService(localNodeName, serviceUri);
    }

    public void reportFailed(URI serviceUri) throws IOException {
        Map<String, NodeServiceVitals> localServices = localTracker.getLocalNodeServices();
        NodeServiceVitals vitals = localServices.get(serviceUri);

        if (vitals != null && !vitals.isDead()) {
            localServices.remove(vitals.getService().getUriString());
        }
    }

    /* end of discoveryAgent interface implementation ************** */

    /**
     * start the discovery agent
     *
     * @throws Exception
     *             on error
     */
    public void doStart() throws Exception {

        clusterNodeServiceTrackerProxy = getClusterNodeServiceTrackerProxy();
        localTracker = getLocalNodeServiceTracker();

        NodeServiceHandlerThread nodeServiceHandlerThread = new NodeServiceHandlerThread();
        Timer timer = new Timer("WADIDiscoveryAgent: checkRemoteService", true);

        timer.scheduleAtFixedRate(nodeServiceHandlerThread, 0, heartRate);

        if (started.compareAndSet(false, true)) {

            Thread listenerThread = new Thread(listener);
            listenerThread.setName("WADIDiscoveryAgent: ListenerThread");
            listenerThread.setDaemon(true);
            listenerThread.start();
        }
    }

    /**
     * stop the channel
     *
     * @throws Exception
     *             pm error
     */
    public void doStop() throws Exception {
        if (started.compareAndSet(true, false)) {
            // multicast.close();
        }
    }

    /**
     * Fails the GBean. This informs the GBean that it is about to transition to the failed state.
     */
    public void doFail() {
        try {
            doStop();
        } catch (Exception e) {
            // ignore
        }
    }

    class NodeServiceHandlerThread extends TimerTask {

        public void run() {

            checkRemoteServices();
            broadCastLocalServicesToRemotePeers();
        }

        private void checkRemoteServices() {

            Map<String, Map<String, NodeServiceVitals>> remoteServices = localTracker.getAllRemoteNodeServices();

            //logAllRemoteServices(false, remoteServices);

            long expireTime = System.currentTimeMillis() - (heartRate * maxMissedHeartbeats);

            if (remoteServices == null || remoteServices.size() == 0)
                return;

            for (String nodeName : remoteServices.keySet()) {

                Map<String, NodeServiceVitals> services = remoteServices.get(nodeName);

                for (NodeServiceVitals serviceVitals : services.values()) {

                    if (serviceVitals.getLastHeartbeat() < expireTime) {

                        NodeServiceVitals vitals = services.remove(serviceVitals.getService().getUri());

                        if (vitals != null && !vitals.isDead()) {

                            localTracker.unregisterNodeService(nodeName, vitals.getService().getUri());

                        }
                    }
                }

            }

        }

        private void broadCastLocalServicesToRemotePeers() {
            clusterNodeServiceTrackerProxy.registerNodeServices(localNodeName, localTracker.getLocalNodeServices());
        }

    }

    private NodeServiceTracker getClusterNodeServiceTrackerProxy() {

        ServiceSpace serviceSpace = WADISessionManager.getServiceSpace();
        ServiceProxyFactory proxyFactory = serviceSpace.getServiceProxyFactory(NodeServiceTracker.NAME,
                new Class[] { NodeServiceTracker.class });

        InvocationMetaData invocationMetaData = proxyFactory.getInvocationMetaData();
        invocationMetaData.setOneWay(true);

        ServiceProxy proxy = proxyFactory.getProxy();

        return (NodeServiceTracker) proxy;

    }

    private NodeServiceTracker getLocalNodeServiceTracker() {

        ServiceSpace serviceSpace = WADISessionManager.getServiceSpace();
        ServiceRegistry serviceRegistry = serviceSpace.getServiceRegistry();

        try {
            return (NodeServiceTracker) serviceRegistry.getStartedService(NodeServiceTracker.NAME);
        } catch (Exception e) {
            throw new IllegalStateException(e);
        }
    }

    private void logAllRemoteServices(boolean isVerbose, Map<String, Map<String, NodeServiceVitals>> results) {

        log.info("*" + localNodeName + " service registry:");

        Set<String> NodeNameSet = results.keySet();
        Map<String, NodeServiceVitals> services_in_node;
        int i = 0;
        for (String nodeName : NodeNameSet) {

            i++;
            log.info("    No." + i + ": " + nodeName);
            services_in_node = results.get(nodeName);
            Set<String> serviceURIs = services_in_node.keySet();

            for (String serviceURI : serviceURIs) {
                log.info("");
                log.info("        Service:" + serviceURI);

                if (isVerbose) {

                    log.info("        " + services_in_node.get(serviceURI));

                }
            }

        }

        log.info("");
        log.info("");

    }

}
TOP

Related Classes of org.apache.geronimo.farm.discovery.wadi.WADIDiscoveryAgent$NodeServiceHandlerThread

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.