All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.fabric3.binding.zeromq.runtime.federation.FederatedAddressCache Maven / Gradle / Ivy

The newest version!
/*
 * Fabric3 Copyright (c) 2009-2013 Metaform Systems
 * 
 * Fabric3 is free software: you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version, with the following exception:
 * 
 * Linking this software statically or dynamically with other modules is making
 * a combined work based on this software. Thus, the terms and conditions of the
 * GNU General Public License cover the whole combination.
 * 
 * As a special exception, the copyright holders of this software give you
 * permission to link this software with independent modules to produce an
 * executable, regardless of the license terms of these independent modules, and
 * to copy and distribute the resulting executable under terms of your choice,
 * provided that you also meet, for each linked independent module, the terms
 * and conditions of the license of that module. An independent module is a
 * module which is not derived from or based on this software. If you modify
 * this software, you may extend this exception to your version of the software,
 * but you are not obligated to do so. If you do not wish to do so, delete this
 * exception statement from your version.
 * 
 * Fabric3 is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * Fabric3. If not, see .
 */
package org.fabric3.binding.zeromq.runtime.federation;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.oasisopen.sca.annotation.Destroy;
import org.oasisopen.sca.annotation.EagerInit;
import org.oasisopen.sca.annotation.Init;
import org.oasisopen.sca.annotation.Reference;
import org.oasisopen.sca.annotation.Service;

import org.fabric3.binding.zeromq.runtime.SocketAddress;
import org.fabric3.host.runtime.HostInfo;
import org.fabric3.spi.federation.MessageException;
import org.fabric3.spi.federation.MessageReceiver;
import org.fabric3.spi.federation.TopologyListener;
import org.fabric3.spi.federation.ZoneChannelException;
import org.fabric3.spi.federation.ZoneTopologyService;

/**
 * An implementation which propagates socket information throughout a distributed domain using the runtime federation API.
 */
@EagerInit
@Service(AddressCache.class)
public class FederatedAddressCache extends LocalAddressCache implements TopologyListener, MessageReceiver {
    private static final String ZEROMQ_CHANNEL = "ZeroMQChannel";
    private ZoneTopologyService topologyService;
    private HostInfo info;
    private String qualifiedChannelName;

    public FederatedAddressCache(@Reference ZoneTopologyService topologyService, @Reference HostInfo info) {
        this.topologyService = topologyService;
        this.info = info;
        this.qualifiedChannelName = ZEROMQ_CHANNEL + "." + info.getDomain().getAuthority();
    }

    @Init
    public void init() throws MessageException {
        topologyService.register(this);
        topologyService.openChannel(qualifiedChannelName, null, this);
        AddressRequest request = new AddressRequest(info.getRuntimeName());
        topologyService.sendAsynchronous(qualifiedChannelName, request);
    }

    @Destroy
    public void destroy() throws ZoneChannelException {
        topologyService.closeChannel(qualifiedChannelName);
        topologyService.deregister(this);
    }

    @Override
    public void publish(AddressEvent event) {
        if (event instanceof AddressAnnouncement) {
            try {
                topologyService.sendAsynchronous(qualifiedChannelName, event);
                super.publish(event);
            } catch (MessageException e) {
                e.printStackTrace();
                // TODO monitor
            }
        }
    }

    public void onMessage(Object object) {
        if (object instanceof AddressAnnouncement) {
            super.publish((AddressAnnouncement) object);
        } else if (object instanceof AddressUpdate) {
            AddressUpdate update = (AddressUpdate) object;
            for (AddressAnnouncement announcement : update.getAnnouncements()) {
                super.publish(announcement);
            }
        } else if (object instanceof AddressRequest) {
            AddressRequest request = (AddressRequest) object;
            AddressUpdate update = new AddressUpdate();
            for (Map.Entry> entry : addresses.entrySet()) {
                for (SocketAddress address : entry.getValue()) {
                    if (info.getRuntimeName().equals(address.getRuntimeName())) {
                        AddressAnnouncement announcement = new AddressAnnouncement(entry.getKey(), AddressAnnouncement.Type.ACTIVATED, address);
                        update.addAnnouncement(announcement);
                    }
                }
            }
            if (!update.getAnnouncements().isEmpty()) {
                try {
                    topologyService.sendAsynchronous(request.getRuntimeName(), qualifiedChannelName, update);
                } catch (MessageException e) {
                    e.printStackTrace();
                    // TODO monitor
                }
            }
        }
    }

    public void onLeave(String name) {
        for (Map.Entry> entry : addresses.entrySet()) {
            List toDelete = new ArrayList();
            List list = entry.getValue();
            for (SocketAddress address : list) {
                if (name.equals(address.getRuntimeName())) {
                    toDelete.add(address);
                }
            }
            for (SocketAddress address : toDelete) {
                list.remove(address);
            }
            if (list.isEmpty()) {
                addresses.remove(entry.getKey());
            }
            notifyChange(entry.getKey());
        }
    }

    public void onJoin(String name) {
        // no-op
    }

    public void onLeaderElected(String name) {
        // no-op
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy