Skip to content

Commit

Permalink
Merge branch 'origin/review/idFinder-base' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
EnricoCestaro committed Mar 4, 2020
2 parents abf2193 + 6bad1d3 commit 2c62879
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,17 @@
* @author Edoardo Raimondi (added the check cicle to verify if the target node is 'alive')
*/
public class IdFinderHandler {
private static final int ATTEMPTS = 7;
private static int maxAttempts = 10;
private static final String ID_TO_FIND_NULL = "The idToFind cannot be null";
private static final String SEARCHER_NULL = "The searcher cannot be null";
private static final String NODES_LIST_NULL = "The nodeList cannot be null";
private static final String NODES_LIST_EMPTY = "The nodeList cannot be empty";
private static final String INSUFFICIENT_ATTEMPTS = "The attemptsNumber must be higher then zero";

/**
* Searches for a specific Id, which needs to be closer to a given resource Id.
* The list of possible nodes is formed by the closest nodes, and it always contains the local node
* (if it doesn't, the node is automatically added)
* The list of possible nodes is formed by the closest nodes, and it always contains the local
* node (if it doesn't, the node is automatically added)
*
* @param idToFind The ID to find in the network
* @param searcher The Peer which is searching for the ID
Expand All @@ -59,8 +60,13 @@ public static void searchId(@NonNull KademliaId idToFind, @NonNull SMSPeer searc
//Obtain the local RoutingTable
SMSKademliaRoutingTable table = KademliaJoinableNetwork.getInstance().getLocalRoutingTable();
//Create a list containing the closest nodes (five is more than enough)
List<SMSKademliaNode> nodeList = table.findClosest(idToFind, ATTEMPTS);

List<SMSKademliaNode> nodeList = table.findClosest(idToFind, maxAttempts);
//Local node, inserted in the list if not already present
SMSKademliaNode local = KademliaJoinableNetwork.getInstance().getLocalNode();
if (!nodeList.contains(local)) {
//inserted in the last position, must be the last node to be checked
nodeList.add(local);
}
searchIdList(idToFind, searcher, nodeList);
}

Expand All @@ -72,16 +78,10 @@ public static void searchId(@NonNull KademliaId idToFind, @NonNull SMSPeer searc
* @param searcher The peer which is searching for the ID
* @param nodeList
*/
public static void searchIdList(@NonNull KademliaId idToFind, @NonNull SMSPeer searcher, @NonNull List<SMSKademliaNode> nodeList) {
public static void searchIdList(@NonNull KademliaId idToFind, @NonNull SMSPeer searcher,
@NonNull List<SMSKademliaNode> nodeList) {
if (nodeList.isEmpty()) throw new IllegalArgumentException(NODES_LIST_EMPTY);
if (nodeList == null) throw new NullPointerException(NODES_LIST_NULL);

//Local node, inserted in the list if not already present
SMSKademliaNode local = KademliaJoinableNetwork.getInstance().getLocalNode();
if (!nodeList.contains(local)) {
//inserted in the last position, must be the last node to be checked
nodeList.add(local);
}
//Get the node with the node ID closest to the idToFind
//The first node in the nodeList is the one with the node Id closest to the idToFind
SMSKademliaNode closestNode = nodeList.get(0);
Expand Down Expand Up @@ -113,7 +113,8 @@ private static void sendResult(KademliaId idToFind, SMSPeer targetPeer) {
.buildMessage();
if (targetPeer.equals(KademliaJoinableNetwork.getInstance().getLocalNode().getPeer())) {
//If I'm searching the id for myself, then I have a pending request I can directly fulfill
KademliaJoinableNetwork.getInstance().getRequestsHandler().completeFindIdRequest(idToFind, targetPeer);
KademliaJoinableNetwork.getInstance().getRequestsHandler().
completeFindIdRequest(idToFind, targetPeer);
return;
}
SMSManager.getInstance().sendMessage(searchResult);
Expand Down Expand Up @@ -151,7 +152,8 @@ private static void keepLooking(KademliaId idToFind, SMSPeer searcherNode, SMSPe
* anymore, it is removed from the RoutingTable, and the research is started
* again
*/
private static void retryIfDead(KademliaId idToFind, SMSPeer searcherNode, SMSPeer nodeToCheck, List<SMSKademliaNode> nodeList) {
private static void retryIfDead(KademliaId idToFind, SMSPeer searcherNode, SMSPeer nodeToCheck,
List<SMSKademliaNode> nodeList) {
if (!KademliaJoinableNetwork.getInstance().isAlive(nodeToCheck)) {
//The first node is the one tested, if I'm here it failed.
//I remove it and restart the process
Expand All @@ -160,4 +162,21 @@ private static void retryIfDead(KademliaId idToFind, SMSPeer searcherNode, SMSPe
searchIdList(idToFind, searcherNode, nodeList);
}
}

/**
* The number of maximum attempts for the research of the node in the RoutingTable is by default
* set to 10; the reason for the existence of this value is to assure that, if the node can't
* reach a large number of nodes, it can still insert the resource inside of the Network; the
* resource will be then relocated during the refresh, IF the unresponsive node returns to live.
* If it doesn't, then the node chosen as closest one remains the closest one.
* It must also be considered the time that each attempts takes (10s)
* Warning: when the application is closed the number of attempts is reset
*
* @param attemptsNumber The maximum number of attempts before saving the resource in the local
* dictionary
*/
public static void setAttemptsNumber(int attemptsNumber) {
if (attemptsNumber < 1) throw new IllegalArgumentException(INSUFFICIENT_ATTEMPTS);
maxAttempts = attemptsNumber;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,18 @@
@RunWith(PowerMockRunner.class)
@PrepareForTest({KademliaNetwork.class, SMSManager.class, KademliaJoinableNetwork.class})
public class IdFinderHandlerTest {
//SEARCHER
private SMSPeer SEARCHER_PEER;
private KademliaId SEARCHER_ID;
private SMSKademliaNode SEARCHER;
//searcher
private SMSPeer searcherPeer;
private KademliaId searcherId;
private SMSKademliaNode searcher;
//NODE1
private SMSPeer VALID_PEER1;
private KademliaId VALID_NODE1_ID;
private SMSKademliaNode VALID_NODE1;
private SMSPeer validPeer1;
private KademliaId validNodeId1;
private SMSKademliaNode validNode1;
//NODE2
private SMSPeer VALID_PEER2;
private KademliaId VALID_NODE2_ID;
private SMSKademliaNode VALID_NODE2;
private SMSPeer validPeer2;
private KademliaId validNodeId2;
private SMSKademliaNode validNode2;

private KademliaJoinableNetwork networkMock;
private SMSManager smsManagerMock;
Expand All @@ -51,19 +51,19 @@ public class IdFinderHandlerTest {
@Before
public void setup() {
//Searcher
SEARCHER_PEER = new SMSPeer("+393423541601");
SEARCHER_ID = new KademliaId(SEARCHER_PEER);
SEARCHER = new SMSKademliaNode(SEARCHER_PEER);
searcherPeer = new SMSPeer("+393423541601");
searcherId = new KademliaId(searcherPeer);
searcher = new SMSKademliaNode(searcherPeer);
//Node1
VALID_PEER1 = new SMSPeer("+393335552121");
VALID_NODE1_ID = new KademliaId(VALID_PEER1);
VALID_NODE1 = new SMSKademliaNode(VALID_PEER1);
validPeer1 = new SMSPeer("+393335552121");
validNodeId1 = new KademliaId(validPeer1);
validNode1 = new SMSKademliaNode(validPeer1);
//Node2
VALID_PEER2 = new SMSPeer("+393423541602");
VALID_NODE2_ID = new KademliaId(VALID_PEER2);
VALID_NODE2 = new SMSKademliaNode(VALID_PEER2);
validPeer2 = new SMSPeer("+393423541602");
validNodeId2 = new KademliaId(validPeer2);
validNode2 = new SMSKademliaNode(validPeer2);
//RoutingTable
routingTable = new SMSKademliaRoutingTable(SEARCHER, new DefaultConfiguration());
routingTable = new SMSKademliaRoutingTable(searcher, new DefaultConfiguration());

//MOCK
networkMock = mock(KademliaJoinableNetwork.class);
Expand All @@ -75,48 +75,45 @@ public void setup() {
PowerMockito.mockStatic(KademliaJoinableNetwork.class);
PowerMockito.when(KademliaJoinableNetwork.getInstance()).thenReturn(networkMock);

when(networkMock.getLocalNode()).thenReturn(SEARCHER);
when(networkMock.getLocalNode()).thenReturn(searcher);
when(networkMock.getLocalRoutingTable()).thenReturn(routingTable);

when(networkMock.isAlive(SEARCHER_PEER)).thenReturn(true);
when(networkMock.isAlive(VALID_PEER1)).thenReturn(true);
when(networkMock.isAlive(VALID_PEER2)).thenReturn(false);

when(networkMock.isAlive(searcherPeer)).thenReturn(true);
when(networkMock.isAlive(validPeer1)).thenReturn(true);
when(networkMock.isAlive(validPeer2)).thenReturn(false);

when(networkMock.getRequestsHandler()).thenReturn(requestsHandler);

//when(networkMock.isNodeInNetwork(VALID_NODE2)).thenReturn(true);

}

@Test(expected = NullPointerException.class)
public void nullId_throws() {
IdFinderHandler.searchId(null, SEARCHER_PEER);
IdFinderHandler.searchId(null, searcherPeer);
}

@Test(expected = NullPointerException.class)
public void nullSearcher_throws() {
IdFinderHandler.searchId(VALID_NODE1_ID, null);
IdFinderHandler.searchId(validNodeId1, null);
}

/**
* This test starts a searchId operation, that should end with the calling Request being closed,
* but the Request doesn't exist; as it is written, the code simply ignore the situation after
* having started the research
* but the Request doesn't exist; in the way it is written, the code should simply ignore the
* situation after having started the research (no Exceptions)
*/
@Test
public void nullRequest_throws() {
IdFinderHandler.searchId(VALID_NODE1_ID, SEARCHER_PEER);
public void closingUnexistingRequest_noExcpetionThrow() {
IdFinderHandler.searchId(validNodeId1, searcherPeer);
}

/**
* In case the searched Id corresponds to my Id, there is no research made by SMS messages
*/
@Test
public void findMyId() {
IdFinderHandler.searchId(SEARCHER_ID, SEARCHER_PEER);
String expectedTextMessage = RequestTypes.Ping.ordinal() + " " + SEARCHER_ID + " / / /";
SMSMessage expectedMessage = new SMSMessage(SEARCHER_PEER, expectedTextMessage);
IdFinderHandler.searchId(searcherId, searcherPeer);
String expectedTextMessage = RequestTypes.Ping.ordinal() + " " + searcherId + " / / /";
SMSMessage expectedMessage = new SMSMessage(searcherPeer, expectedTextMessage);
verify(smsManagerMock, times(0)).sendMessage(expectedMessage);
}

Expand All @@ -127,8 +124,8 @@ public void findMyId() {
*/
@Test
public void findNotMyId_inserted() {
routingTable.insert(VALID_NODE1);
IdFinderHandler.searchId(VALID_NODE1_ID, SEARCHER_PEER);
routingTable.insert(validNode1);
IdFinderHandler.searchId(validNodeId1, searcherPeer);
verify(smsManagerMock, times(1)).sendMessage(any(SMSMessage.class));
}

Expand All @@ -139,8 +136,8 @@ public void findNotMyId_inserted() {
*/
@Test
public void findNotMyId_inserted_DEAD() {
routingTable.insert(VALID_NODE2);
IdFinderHandler.searchId(VALID_NODE2_ID, SEARCHER_PEER);
routingTable.insert(validNode2);
IdFinderHandler.searchId(validNodeId2, searcherPeer);
verify(smsManagerMock, times(1)).sendMessage(any(SMSMessage.class));
}

Expand All @@ -150,16 +147,16 @@ public void findNotMyId_inserted_DEAD() {
*/
@Test
public void findNotMyId_notInserted() {
IdFinderHandler.searchId(VALID_NODE1_ID, SEARCHER_PEER);
IdFinderHandler.searchId(validNodeId1, searcherPeer);
verify(smsManagerMock, times(0)).sendMessage(any(SMSMessage.class));
}


@Test
public void findIdInTable_notSearchedByMe() {
IdFinderHandler.searchId(SEARCHER_ID, VALID_PEER1);
String expectedTextMessage = RequestTypes.FindIdSearchResult.ordinal() + " " + SEARCHER + " / / /";
SMSMessage expectedMessage = new SMSMessage(VALID_PEER1, expectedTextMessage);
IdFinderHandler.searchId(searcherId, validPeer1);
String expectedTextMessage = RequestTypes.FindIdSearchResult.ordinal() + " " + searcher + " / / /";
SMSMessage expectedMessage = new SMSMessage(validPeer1, expectedTextMessage);
verify(smsManagerMock, times(1)).sendMessage(expectedMessage);
}

Expand All @@ -168,20 +165,20 @@ public void findIdInTable_notSearchedByMe() {
*/
@Test
public void findIdInTable_notSearchedByMe_DEAD() {
IdFinderHandler.searchId(SEARCHER_ID, VALID_PEER2);
String expectedTextMessage = RequestTypes.FindIdSearchResult.ordinal() + " " + SEARCHER + " / / /";
SMSMessage expectedMessage = new SMSMessage(VALID_PEER2, expectedTextMessage);
IdFinderHandler.searchId(searcherId, validPeer2);
String expectedTextMessage = RequestTypes.FindIdSearchResult.ordinal() + " " + searcher + " / / /";
SMSMessage expectedMessage = new SMSMessage(validPeer2, expectedTextMessage);
verify(smsManagerMock, times(1)).sendMessage(expectedMessage);
}

@Test
public void forwardRequest() {
routingTable.insert(VALID_NODE1);
IdFinderHandler.searchId(VALID_NODE1_ID, SEARCHER_PEER);
routingTable.insert(validNode1);
IdFinderHandler.searchId(validNodeId1, searcherPeer);
String expectedTextMessage =
RequestTypes.FindId.ordinal() + " " +
VALID_NODE1_ID + " " + SEARCHER_PEER + " / /";
SMSMessage expectedMessage = new SMSMessage(VALID_PEER1, expectedTextMessage);
validNodeId1 + " " + searcherPeer + " / /";
SMSMessage expectedMessage = new SMSMessage(validPeer1, expectedTextMessage);
verify(smsManagerMock, times(1)).sendMessage(expectedMessage);
}

Expand All @@ -196,9 +193,9 @@ public void forwardRequest() {
@Test
public void noLocalNode_localNodeSearched() {
List<SMSKademliaNode> nodes = routingTable.getAllNodes();
nodes.add(VALID_NODE1);
nodes.remove(SEARCHER);
IdFinderHandler.searchIdList(SEARCHER_ID, SEARCHER_PEER, nodes);
nodes.add(validNode1);
nodes.remove(searcher);
IdFinderHandler.searchIdList(searcherId, searcherPeer, nodes);
verify(smsManagerMock, times(1)).sendMessage(any(SMSMessage.class));
}

Expand All @@ -208,10 +205,10 @@ public void noLocalNode_localNodeSearched() {
@Test
public void noLocalNode_notLocalNodeSearched() {
List<SMSKademliaNode> nodes = routingTable.getAllNodes();
nodes.add(VALID_NODE1);
nodes.remove(SEARCHER);
IdFinderHandler.searchIdList(VALID_NODE1_ID, SEARCHER_PEER, nodes);
//A message is sent to the VALID_NODE1
nodes.add(validNode1);
nodes.remove(searcher);
IdFinderHandler.searchIdList(validNodeId1, searcherPeer, nodes);
//A message is sent to the validNode1
verify(smsManagerMock, times(1)).sendMessage(any(SMSMessage.class));
}
}

0 comments on commit 2c62879

Please sign in to comment.