Example #1
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();
  }
  /**
   * This method depends on addLiveContactInfo(...) and does two things. It either forwards or
   * removes a DHTValue it from the local Database. For details see Kademlia spec!
   */
  private void forwardOrRemoveValues(Contact node, Contact existing, DHTMessage message) {

    List<DHTValueEntity> valuesToForward = new ArrayList<DHTValueEntity>();

    Database database = context.getDatabase();
    synchronized (database) {
      for (KUID primaryKey : database.keySet()) {

        Operation op = getOperation(node, existing, primaryKey);

        if (LOG.isDebugEnabled())
          LOG.debug("node: " + node + "existing: " + existing + "operation: " + op);

        if (op.equals(Operation.FORWARD)) {
          Map<KUID, DHTValueEntity> bag = database.get(primaryKey);
          valuesToForward.addAll(bag.values());
          databaseStats.STORE_FORWARD_COUNT.incrementStat();

        } else if (op.equals(Operation.DELETE)
            && DatabaseSettings.DELETE_VALUE_IF_FURTHEST_NODE.getValue()) {
          Map<KUID, DHTValueEntity> bag = database.get(primaryKey);
          for (DHTValueEntity entity : bag.values()) {
            // System.out.println("REMOVING: " + entity + "\n");
            database.remove(entity.getPrimaryKey(), entity.getSecondaryKey());
          }
          databaseStats.STORE_FORWARD_REMOVALS.incrementStat();
        }
      }
    }

    if (!valuesToForward.isEmpty()) {
      SecurityToken securityToken = null;
      if (message instanceof SecurityTokenProvider) {
        securityToken = ((SecurityTokenProvider) message).getSecurityToken();

        if (securityToken == null && StoreSettings.STORE_REQUIRES_SECURITY_TOKEN.getValue()) {
          if (LOG.isInfoEnabled()) {
            LOG.info(node + " sent us a null SecurityToken");
          }
          return;
        }
      }

      context.store(node, securityToken, valuesToForward);
    }
  }
  /**
   * Reads a DHTValueEntity from the InputStream.
   *
   * @param sender the Contact that send us the DHTValue
   */
  public DHTValueEntity readDHTValueEntity(Contact sender, DHTValueFactoryManager factoryManager)
      throws IOException {
    Contact creator = readContact();
    KUID primaryKey = readKUID();
    DHTValue value = readDHTValue(factoryManager);

    // if the creator has the same KUID as the sender, use the sender as we have its external addr.
    if (creator.getNodeID().equals(sender.getNodeID())) creator = sender;
    return DHTValueEntity.createFromRemote(creator, sender, primaryKey, value);
  }