@Override
  public void dropOutdated() {
    BasicDBObject query = new BasicDBObject();
    query.put("last_seen", new BasicDBObject("$lt", Tools.getUTCTimestamp() - pingTimeout));

    destroyAll(NodeImpl.class, query);
  }
  @Override
  public boolean isAnyMasterPresent() {
    BasicDBObject query = new BasicDBObject();
    query.put("type", NodeImpl.Type.SERVER.toString());
    query.put("last_seen", new BasicDBObject("$gte", Tools.getUTCTimestamp() - pingTimeout));
    query.put("is_master", true);

    return query(NodeImpl.class, query).size() > 0;
  }
 /**
  * Mark this node as alive and probably update some settings that may have changed since last
  * server boot.
  *
  * @param isMaster
  * @param restTransportAddress
  */
 @Override
 public void markAsAlive(Node node, boolean isMaster, String restTransportAddress) {
   node.getFields().put("last_seen", Tools.getUTCTimestamp());
   node.getFields().put("is_master", isMaster);
   node.getFields().put("transport_address", restTransportAddress);
   try {
     save(node);
   } catch (ValidationException e) {
     throw new RuntimeException("Validation failed.", e);
   }
 }
  @Override
  public String registerRadio(String nodeId, String restTransportUri) {
    Map<String, Object> fields = Maps.newHashMap();
    fields.put("last_seen", Tools.getUTCTimestamp());
    fields.put("node_id", nodeId);
    fields.put("type", NodeImpl.Type.RADIO.toString());
    fields.put("transport_address", restTransportUri);

    try {
      return save(new NodeImpl(fields));
    } catch (ValidationException e) {
      throw new RuntimeException("Validation failed.", e);
    }
  }
  public Map<String, Object> getAsDatabaseObject() {
    Map<String, Object> result = Maps.newHashMap();

    Map<String, Map<String, Object>> indexInformation = Maps.newHashMap();
    for (Map.Entry<String, IndexStats> e : indices.entrySet()) {
      indexInformation.put(e.getKey(), getIndexInformation(e.getValue()));
    }

    result.put("server_id", serverId);
    result.put("deflector_target", deflectorTarget);
    result.put("max_messages_per_index", maxMessagesPerIndex);
    result.put("indices", indexInformation);
    result.put("timestamp", Tools.getUTCTimestamp());

    return result;
  }
  @Override
  public Map<String, Node> allActive(NodeImpl.Type type) {
    Map<String, Node> nodes = Maps.newHashMap();

    BasicDBObject query = new BasicDBObject();
    query.put("last_seen", new BasicDBObject("$gte", Tools.getUTCTimestamp() - pingTimeout));
    query.put("type", type.toString());

    for (DBObject obj : query(NodeImpl.class, query)) {
      Node node = new NodeImpl((ObjectId) obj.get("_id"), obj.toMap());
      String nodeId = (String) obj.get("node_id");

      nodes.put(nodeId, node);
    }

    return nodes;
  }