Package fr.imag.adele.apam.distriman.discovery

Source Code of fr.imag.adele.apam.distriman.discovery.ApamDiscoveryImpl

/**
* Copyright 2011-2012 Universite Joseph Fourier, LIG, ADELE team
*   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 fr.imag.adele.apam.distriman.discovery;

import java.io.IOException;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.jmdns.JmDNS;
import javax.jmdns.NetworkTopologyDiscovery;
import javax.jmdns.ServiceEvent;
import javax.jmdns.ServiceInfo;

import org.apache.felix.ipojo.annotations.Component;
import org.apache.felix.ipojo.annotations.Instantiate;
import org.apache.felix.ipojo.annotations.Invalidate;
import org.apache.felix.ipojo.annotations.Property;
import org.apache.felix.ipojo.annotations.Provides;
import org.apache.felix.ipojo.annotations.Requires;
import org.apache.felix.ipojo.annotations.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import fr.imag.adele.apam.distriman.provider.LocalMachine;

/**
* <p>
* The MachineDiscovery component allows for the discovery of other machines
* (Apam/Distriman) over the network, thanks to the mdns protocol.
* </p>
*
* A RemoteMachine instance is created for each machine discovered.
*
*
* User: barjo / jander Date: 04/12/12 Time: 14:48
*/
@Component(name = "Apam::Distriman::Discovery")
@Instantiate
@Provides
public class ApamDiscoveryImpl implements ApamDiscovery,
  NetworkTopologyDiscovery.Factory.ClassDelegate {

    private static Logger logger = LoggerFactory
      .getLogger(ApamDiscoveryImpl.class);

    @Property(name = "inet.host", value = "127.0.0.1", mandatory = true)
    private String HOST;

    private LocalMachine local;

    /**
     * JmDNS, Java Multicast DNS, use to announce and discovered Apam/Distriman
     * machine over the network.
     */
    private Map<JmDNS, String> jmDNSMachines;// ArrayList<JmDNS>();

    /**
     * Compute a default name for that machine, TODO compute a more relevant
     * name.
     */
    private String name = UUID.randomUUID().toString();

    @Requires
    private ApamMachineFactory machineFactory;

    public ApamDiscoveryImpl() {
  super();
  NetworkTopologyDiscovery.Factory.setClassDelegate(this);
    }

    private boolean isItLocal(ServiceEvent serviceEvent) {
  for (Map.Entry<JmDNS, String> entry : jmDNSMachines.entrySet()) {

      JmDNS jmDNS = entry.getKey();
      try {
    if (jmDNS
      .getInterface()
      .getHostAddress()
      .equals(serviceEvent.getDNS().getInterface()
        .getHostAddress())
      && serviceEvent.getInfo().getPort() == this.local
        .getPort()) {
        return true;
    }
      } catch (IOException e) {
    // consider as not local in case of problem (conservative
    // approach
      }

  }

  return false;
    }

    /**
     * Factory that determines the euristics to choose/filter the network cards
     * to be considered
     */
    @Override
    public NetworkTopologyDiscovery newNetworkTopologyDiscovery() {
  return new NetworkTopology();
    }

    @Override
    public void publishLocalMachine(LocalMachine local) throws IOException {

  this.local = local;

  for (Map.Entry<JmDNS, String> entry : jmDNSMachines.entrySet()) {

      JmDNS jmDNS = entry.getKey();
      String urlaux = entry.getValue();

      String url = String.format("http://%s:%d", urlaux, local.getPort());

      // Register a local machine
      logger.info("publishing machine {} on the mdns bus", url);

      jmDNS.registerService(ServiceInfo.create(local.getType(),
        local.getName(), local.getPort(), url));

  }

    }

    @Override
    public void serviceAdded(ServiceEvent serviceEvent) {
  // Ignore, only handle resolved
  logger.info("service added {}", serviceEvent.getInfo()
    .getNiceTextString());
    }

    /**
     * @param serviceEvent
     *            The mdns event triggered by a remote machine that is no longer
     *            available.
     */
    @Override
    public void serviceRemoved(ServiceEvent serviceEvent) {

  String id = String.format("%s.%s", serviceEvent.getName(),
    serviceEvent.getType());

  logger.info("service removing {} with id {}", serviceEvent.getInfo()
    .getNiceTextString(), id);

  if (serviceEvent.getName().equalsIgnoreCase(name)) {
      return; // ignore my message
  }

  ServiceInfo info = serviceEvent.getInfo();
  String url = info.getNiceTextString();

  machineFactory.destroyRemoteMachine(url, id);
    }

    @Override
    public void serviceResolved(ServiceEvent serviceEvent) {

  String id = String.format("%s.%s", serviceEvent.getName(),
    serviceEvent.getType());

  logger.info("service resolved {} subtype {}", serviceEvent.getInfo()
    .getNiceTextString(), id);

  boolean isLocalhost = isItLocal(serviceEvent);

  if (serviceEvent.getName().equalsIgnoreCase(name)) {
      return; // ignore this machine message
  }

  ServiceInfo info = serviceEvent.getDNS().getServiceInfo(MDNS_TYPE,
    serviceEvent.getName());
  String url = info.getNiceTextString();

  machineFactory.newRemoteMachine(url, id, isLocalhost);
    }

    @Validate
    public void start() {

  logger.info("Starting mdns...");

  if (jmDNSMachines != null) {
      throw new RuntimeException(
        "Trying to start machine discovery twice.");
  }

  jmDNSMachines = new HashMap<JmDNS, String>();// new
                 // CopyOnWriteArrayList<JmDNS>();

  logger.info("Iteratings interfaces..");

  // Create the jmdns server
  for (InetAddress address : NetworkTopologyDiscovery.Factory
    .getInstance().getInetAddresses()) {

      try {

    JmDNS current = JmDNS.create(address);

    current.registerServiceType(MDNS_TYPE);

    jmDNSMachines.put(current, address.getHostAddress());

    for (ServiceInfo sinfo : current.list(MDNS_TYPE)) {
        if (sinfo.getName().equalsIgnoreCase(name)) {
      continue; // ignore my services..
        }

        // Create and Add the machine
        String url = sinfo.getNiceTextString();

        logger.info("mDNS detected the url {} subtype {}", url,
          sinfo.getTypeWithSubtype());

        String id = String.format("%s.%s", sinfo.getName(),
          sinfo.getType());

        machineFactory.newRemoteMachine(url, id, false);
    }

    current.addServiceListener(MDNS_TYPE, this);

      } catch (IOException e) {
    e.printStackTrace();
    throw new RuntimeException(e);
      }

  }

  logger.info("/Iteratings interfaces..");

  logger.info("mdns started.");

    }

    @Override
    @Invalidate
    public void stop() {

  for (Map.Entry<JmDNS, String> entry : jmDNSMachines.entrySet()) {

      JmDNS jmDNS = entry.getKey();

      jmDNS.unregisterAllServices();

      // unregister the listener
      jmDNS.removeServiceListener(MDNS_TYPE, this);

      try {
    jmDNS.close();
      } catch (IOException e) {

      }

  }
    }
}
TOP

Related Classes of fr.imag.adele.apam.distriman.discovery.ApamDiscoveryImpl

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.