org.drasyl.peer.PeersManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of drasyl-core Show documentation
Show all versions of drasyl-core Show documentation
This packages contains the building blocks required to create the drasyl overlay network.
/*
* Copyright (c) 2020-2021 Heiko Bornholdt and Kevin Röbert
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
* OR OTHER DEALINGS IN THE SOFTWARE.
*/
package org.drasyl.peer;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.SetMultimap;
import org.drasyl.event.Event;
import org.drasyl.event.Node;
import org.drasyl.event.NodeOfflineEvent;
import org.drasyl.event.NodeOnlineEvent;
import org.drasyl.event.Peer;
import org.drasyl.event.PeerDirectEvent;
import org.drasyl.event.PeerRelayEvent;
import org.drasyl.identity.IdentityPublicKey;
import org.drasyl.identity.Identity;
import org.drasyl.util.SetUtil;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Consumer;
import static java.util.Objects.requireNonNull;
/**
* This class contains information about other peers. This includes the public keys, available
* interfaces, connections or relations (e.g. direct/relayed connection, super peer, child). Before
* a relation is set for a peer, it must be ensured that its information is available. Likewise, the
* information may not be removed from a peer if the peer still has a relation
*
*
* This class is optimized for concurrent access and is thread-safe.
*
*/
public class PeersManager {
private final ReadWriteLock lock;
private final SetMultimap paths;
private final Set children;
private final Consumer eventConsumer;
private final Identity identity;
private final Set superPeers;
public PeersManager(final Consumer eventConsumer, final Identity identity) {
this(new ReentrantReadWriteLock(true), HashMultimap.create(), new HashSet<>(), new HashSet<>(), eventConsumer, identity);
}
@SuppressWarnings("java:S2384")
PeersManager(final ReadWriteLock lock,
final SetMultimap paths,
final Set children,
final Set superPeers,
final Consumer eventConsumer,
final Identity identity) {
this.lock = lock;
this.paths = paths;
this.children = children;
this.superPeers = superPeers;
this.eventConsumer = eventConsumer;
this.identity = identity;
}
@Override
public String toString() {
try {
lock.readLock().lock();
return "PeersManager{" +
", paths=" + paths +
", children=" + children +
", eventConsumer=" + eventConsumer +
", superPeers=" + superPeers +
'}';
}
finally {
lock.readLock().unlock();
}
}
public Set getPeers() {
try {
lock.readLock().lock();
return SetUtil.merge(paths.keySet(), SetUtil.merge(superPeers, children));
}
finally {
lock.readLock().unlock();
}
}
public Set getChildren() {
try {
lock.readLock().lock();
// It is necessary to create a new HashMap because otherwise, this can raise a
// ConcurrentModificationException.
// See: https://git.informatik.uni-hamburg.de/sane-public/drasyl/-/issues/77
return Set.copyOf(children);
}
finally {
lock.readLock().unlock();
}
}
public Set getSuperPeers() {
try {
lock.readLock().lock();
// It is necessary to create a new HashMap because otherwise, this can raise a
// ConcurrentModificationException.
// See: https://git.informatik.uni-hamburg.de/sane-public/drasyl/-/issues/77
return Set.copyOf(superPeers);
}
finally {
lock.readLock().unlock();
}
}
public Set