Package net.tomp2p.p2p.builder

Source Code of net.tomp2p.p2p.builder.BootstrapBuilder

/*
* Copyright 2012 Thomas Bocek
*
* 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 net.tomp2p.p2p.builder;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Collection;

import net.tomp2p.connection.Ports;
import net.tomp2p.futures.BaseFutureAdapter;
import net.tomp2p.futures.FutureBootstrap;
import net.tomp2p.futures.FutureChannelCreator;
import net.tomp2p.futures.FutureDone;
import net.tomp2p.futures.FuturePing;
import net.tomp2p.futures.FutureRouting;
import net.tomp2p.futures.FutureWrappedBootstrap;
import net.tomp2p.p2p.Peer;
import net.tomp2p.p2p.RoutingConfiguration;
import net.tomp2p.peers.Number160;
import net.tomp2p.peers.PeerAddress;
import net.tomp2p.utils.Pair;
import net.tomp2p.utils.Utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Boostraps to a known peer. First channels are reserved, then #discover(PeerAddress) is called to verify this Internet
* connection settings using the argument peerAddress. Then the routing is initiated to the peers specified in
* bootstrapTo. Please be aware that in order to boostrap you need to know the peer ID of all peers in the collection
* bootstrapTo. Passing Number160.ZERO does *not* work.
*
* @param discoveryPeerAddress
*            The peer address to use for discovery
* @param bootstrapTo
*            The peers used to bootstrap
* @param config
*            The configuration
* @return The future bootstrap
*/

public class BootstrapBuilder {
    private static final Logger logger = LoggerFactory.getLogger(BootstrapBuilder.class);

    private static final FutureBootstrap FUTURE_BOOTSTRAP_SHUTDOWN = new FutureWrappedBootstrap<FutureBootstrap>()
            .failed0("Peer is shutting down");

    private static final FutureBootstrap FUTURE_BOOTSTRAP_NO_ADDRESS = new FutureWrappedBootstrap<FutureBootstrap>()
            .failed0("You did not provide information where to bootstrap to. "
                    + "This could be also caused if you provided a peer address with a peer ID set to zero.");

    private final Peer peer;

    private Collection<PeerAddress> bootstrapTo;

    private PeerAddress peerAddress;

    private InetAddress inetAddress;

    private int portUDP = Ports.DEFAULT_PORT;

    private int portTCP = Ports.DEFAULT_PORT;

    private RoutingConfiguration routingConfiguration;

    private boolean forceRoutingOnlyToSelf = false;

    private boolean broadcast = false;

    public BootstrapBuilder(Peer peer) {
        this.peer = peer;
    }
   
    public PeerAddress peerAddress() {
        return peerAddress;
    }

    public Collection<PeerAddress> bootstrapTo() {
        return bootstrapTo;
    }

    public BootstrapBuilder bootstrapTo(Collection<PeerAddress> bootstrapTo) {
        this.bootstrapTo = bootstrapTo;
        return this;
    }

    /**
     * Set the peer address to bootstrap to. Please note that the peer address needs to know the peerID of the bootstrap
     * peer. If this is not known, use {@link #inetAddress(InetAddress)} instead.
     *
     * @param peerAddress
     *            The full address of the peer to bootstrap to (including the peerID of the bootstrap peer).
     * @return this instance
     */
    public BootstrapBuilder peerAddress(final PeerAddress peerAddress) {
        if (peerAddress != null && peerAddress.peerId().equals(Number160.ZERO)) {
            logger.warn("You provided a peer address with peerID zero. "
                    + "You won't be able to bootstrap since no peer can have a peerID set to zero");
            return this;
        }
        this.peerAddress = peerAddress;
        return this;
    }

    public InetAddress inetAddress() {
        return inetAddress;
    }

    public BootstrapBuilder inetAddress(InetAddress inetAddress) {
        this.inetAddress = inetAddress;
        return this;
    }
   
    public BootstrapBuilder inetSocketAddress(InetSocketAddress socket) {
      this.inetAddress = socket.getAddress();
      this.portTCP = socket.getPort();
      this.portUDP = socket.getPort();
      return this;
    }

    public int portUDP() {
        return portUDP;
    }

    public BootstrapBuilder portUDP(int portUDP) {
        this.portUDP = portUDP;
        return this;
    }

    public int portTCP() {
        return portTCP;
    }

    public BootstrapBuilder portTCP(int portTCP) {
        this.portTCP = portTCP;
        return this;
    }

    public BootstrapBuilder ports(int port) {
        this.portTCP = port;
        this.portUDP = port;
        return this;
    }

    public RoutingConfiguration routingConfiguration() {
        return routingConfiguration;
    }

    public BootstrapBuilder routingConfiguration(RoutingConfiguration routingConfiguration) {
        this.routingConfiguration = routingConfiguration;
        return this;
    }

    public boolean isForceRoutingOnlyToSelf() {
        return forceRoutingOnlyToSelf;
    }

    public BootstrapBuilder forceRoutingOnlyToSelf() {
        this.forceRoutingOnlyToSelf = true;
        return this;
    }

    public BootstrapBuilder forceRoutingOnlyToSelf(boolean forceRoutingOnlyToSelf) {
        this.forceRoutingOnlyToSelf = forceRoutingOnlyToSelf;
        return this;
    }

    public boolean isBroadcast() {
        return broadcast;
    }

    public BootstrapBuilder broadcast() {
        this.broadcast = true;
        return this;
    }

    public BootstrapBuilder broadcast(boolean broadcast) {
        this.broadcast = broadcast;
        return this;
    }

    public FutureBootstrap start() {
        if (peer.isShutdown()) {
            return FUTURE_BOOTSTRAP_SHUTDOWN;
        }

        if (routingConfiguration == null) {
            routingConfiguration = new RoutingConfiguration(8, 10, 2);
        }
        //
        if (broadcast) {
            return broadcast0();
        }
        if (peerAddress == null && inetAddress != null && bootstrapTo == null) {
            peerAddress = new PeerAddress(Number160.ZERO, inetAddress, portTCP, portUDP);
            return bootstrapPing(peerAddress);

        } else if (peerAddress != null && bootstrapTo == null) {
            bootstrapTo = new ArrayList<PeerAddress>(1);
            bootstrapTo.add(peerAddress);
            return bootstrap();
        } else if (bootstrapTo != null) {
            return bootstrap();
        } else {
            return FUTURE_BOOTSTRAP_NO_ADDRESS;
        }
    }

    private FutureBootstrap bootstrap() {
        final FutureWrappedBootstrap<FutureDone<Pair<FutureRouting,FutureRouting>>> result = new FutureWrappedBootstrap<FutureDone<Pair<FutureRouting,FutureRouting>>>();
        result.bootstrapTo(bootstrapTo);
        int conn = routingConfiguration.parallel();
        FutureChannelCreator fcc = peer.connectionBean().reservation().create(conn, 0);
        Utils.addReleaseListener(fcc, result);
        fcc.addListener(new BaseFutureAdapter<FutureChannelCreator>() {
            @Override
            public void operationComplete(final FutureChannelCreator futureChannelCreator) throws Exception {
                if (futureChannelCreator.isSuccess()) {
                    RoutingBuilder routingBuilder = createBuilder(routingConfiguration, forceRoutingOnlyToSelf);
                    FutureDone<Pair<FutureRouting,FutureRouting>> futureBootstrap = peer.distributedRouting().bootstrap(
                            bootstrapTo, routingBuilder, futureChannelCreator.channelCreator());
                    result.waitFor(futureBootstrap);
                } else {
                    result.failed(futureChannelCreator);
                }
            }
        });
        return result;
    }

    static RoutingBuilder createBuilder(RoutingConfiguration routingConfiguration, boolean forceRoutingOnlyToSelf) {
        RoutingBuilder routingBuilder = new RoutingBuilder();
        routingBuilder.parallel(routingConfiguration.parallel());
        routingBuilder.setMaxNoNewInfo(routingConfiguration.maxNoNewInfoDiff());
        routingBuilder.maxDirectHits(Integer.MAX_VALUE);
        routingBuilder.maxFailures(routingConfiguration.maxFailures());
        routingBuilder.maxSuccess(routingConfiguration.maxSuccess());
        routingBuilder.forceRoutingOnlyToSelf(forceRoutingOnlyToSelf);
        return routingBuilder;
    }

    private FutureWrappedBootstrap<FutureBootstrap> bootstrapPing(PeerAddress address) {
        final FutureWrappedBootstrap<FutureBootstrap> result = new FutureWrappedBootstrap<FutureBootstrap>();
        final FuturePing futurePing = peer.ping().peerAddress(address).tcpPing().start();
        futurePing.addListener(new BaseFutureAdapter<FuturePing>() {
            @Override
            public void operationComplete(final FuturePing future) throws Exception {
                if (future.isSuccess()) {
                    peerAddress = future.remotePeer();
                    bootstrapTo = new ArrayList<PeerAddress>(1);
                    bootstrapTo.add(peerAddress);
                    result.bootstrapTo(bootstrapTo);
                    result.waitFor(bootstrap());
                } else {
                    result.failed("could not reach anyone with bootstrap");
                }
            }
        });
        return result;
    }

    private FutureWrappedBootstrap<FutureBootstrap> broadcast0() {
        final FutureWrappedBootstrap<FutureBootstrap> result = new FutureWrappedBootstrap<FutureBootstrap>();
        final FuturePing futurePing = peer.ping().broadcast().port(portUDP).start();
        futurePing.addListener(new BaseFutureAdapter<FuturePing>() {
            @Override
            public void operationComplete(final FuturePing future) throws Exception {
                if (future.isSuccess()) {
                    if (bootstrapTo != null && bootstrapTo.size() > 0) {
                        logger.info("you added peers to bootstrapTo. However with broadcast we found our own peers.");
                    }
                    peerAddress = future.remotePeer();
                    bootstrapTo = new ArrayList<PeerAddress>(1);
                    bootstrapTo.add(peerAddress);
                    result.bootstrapTo(bootstrapTo);
                    result.waitFor(bootstrap());
                } else {
                    result.failed("could not reach anyone with the broadcast", future);
                }
            }
        });
        return result;
    }

 

}
TOP

Related Classes of net.tomp2p.p2p.builder.BootstrapBuilder

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.