Example #1
0
  @Test
  public void testStorables() throws Exception {
    Context dht = (Context) MojitoFactory.createDHT("bootstrap");
    dht.getStorableModelManager().addStorableModel(DHTValueType.TEXT, new Dht.Model());
    dht.bind(new InetSocketAddress("localhost", 8080));
    dht.start();

    Context node = (Context) MojitoFactory.createDHT("node");
    node.getStorableModelManager().addStorableModel(DHTValueType.TEXT, new Dht.Model());
    node.bind(new InetSocketAddress("localhost", 8081));
    node.start();
    node.bootstrap(new InetSocketAddress("localhost", 8080)).get();
    assertTrue(node.isBootstrapped());

    DHTValueImpl value =
        new DHTValueImpl(DHTValueType.TEXT, Version.ZERO, "hello world".getBytes());

    node.put(Keys.of("key"), value).get();

    FindValueResult result =
        node.get(EntityKey.createEntityKey(Keys.of("key"), DHTValueType.TEXT)).get();

    assertTrue(result.isSuccess());
    assertEquals(1, result.getEntities().size());
    assertEquals(
        "hello world", new String(result.getEntities().iterator().next().getValue().getValue()));

    node.close();
    dht.close();
  }
Example #2
0
  @Test
  public void testCreatorAddressIsCorrect() throws Exception {
    Context root = (Context) MojitoFactory.createDHT("bootstrap");
    root.bind(new InetSocketAddress("localhost", 8081));
    root.start();

    Context dht = (Context) MojitoFactory.createDHT("dht");
    dht.bind(new InetSocketAddress("localhost", 8080));
    dht.start();
    dht.bootstrap(new InetSocketAddress("localhost", 8081)).get();
    assertTrue(dht.isBootstrapped());

    DHTValueImpl value =
        new DHTValueImpl(DHTValueType.TEXT, Version.ZERO, "hello world".getBytes());

    StoreResult store = dht.put(Keys.of("key"), value).get();

    assertEquals(2, store.getLocations().size());

    FindValueResult result =
        dht.get(EntityKey.createEntityKey(Keys.of("key"), DHTValueType.TEXT)).get();

    assertTrue(result.isSuccess());
    assertEquals(1, result.getEntities().size());
    DHTValueEntity entity = result.getEntities().iterator().next();
    assertEquals(
        InetSocketAddress.createUnresolved("localhost", 8080),
        entity.getCreator().getContactAddress());
    assertEquals(
        InetSocketAddress.createUnresolved("localhost", 8081),
        entity.getSender().getContactAddress());

    root.close();
    dht.close();
  }
  /**
   * Adds the given <code>Contact</code> or updates it if it's already in our <code>RouteTable
   * </code>
   */
  private synchronized void addLiveContactInfo(Contact node, DHTMessage message) {

    RouteTable routeTable = context.getRouteTable();

    // If the Node is going to shutdown then don't bother
    // further than this.
    if (node.isShutdown()) {
      if (LOG.isInfoEnabled()) {
        LOG.info(node + " is going to shut down");
      }

      synchronized (routeTable) {
        // Make sure there's an existing Contact in the RouteTable.
        // Otherwise don't bother!
        Contact existing = routeTable.get(node.getNodeID());
        if (node.equals(existing)) {

          // Update the new Contact in the RouteTable and
          // mark it as shutdown
          // mark the existing contact as shutdown if its alive or
          // it will not be removed.
          if (existing.isAlive()) existing.shutdown(true);
          routeTable.add(node);
          node.shutdown(true);
        }
      }
      return;
    }

    // Ignore firewalled Nodes
    if (node.isFirewalled()) {
      if (LOG.isInfoEnabled()) {
        LOG.info(node + " is firewalled");
      }
      return;
    }

    if (ContactUtils.isPrivateAddress(node)) {
      if (LOG.isInfoEnabled()) {
        LOG.info(node + " has a private address");
      }
      return;
    }

    KUID nodeId = node.getNodeID();
    if (context.isLocalNodeID(nodeId)) {

      // This is expected if there's a Node ID collision
      assert (message instanceof PingResponse)
          : "Expected a PingResponse but got a "
              + message.getClass()
              + " from "
              + message.getContact();

      if (LOG.isInfoEnabled()) {
        LOG.info("Looks like our NodeID collides with " + node);
      }

      return;
    }

    if (StoreSettings.STORE_FORWARD_ENABLED.getValue()) {
      // Only do store forward if it is a new node in our routing table
      // (we are (re)connecting to the network) or a node that is reconnecting
      Contact existing = routeTable.get(nodeId);

      if (existing == null
          || existing.isDead()
          || existing.getInstanceID() != node.getInstanceID()) {

        // Store forward only if we're bootstrapped
        if (context.isBootstrapped()) {
          int k = KademliaSettings.REPLICATION_PARAMETER.getValue();
          // we select the 2*k closest nodes in order to also check those values
          // where the local node is part of the k closest to the value but not part
          // of the k closest to the new joining node.
          Collection<Contact> nodes = routeTable.select(nodeId, 2 * k, SelectMode.ALL);

          // Are we one of the K nearest Nodes to the contact?
          if (containsNodeID(nodes, context.getLocalNodeID())) {
            if (LOG.isTraceEnabled()) {
              LOG.trace(
                  "Node "
                      + node
                      + " is new or has changed his instanceID, will check for store forward!");
            }

            forwardOrRemoveValues(node, existing, message);
          }
        }
      }
    }

    // Add the Node to our RouteTable or if it's
    // already there update its timeStamp and whatsoever
    routeTable.add(node);
  }