use of i2p.bote.packet.dht.IndexPacket in project i2p.i2p-bote by i2p.
the class IndexPacketFolder method storeAndCreateDeleteRequest.
@Override
public DeleteRequest storeAndCreateDeleteRequest(DhtStorablePacket packetToStore) {
if (!(packetToStore instanceof IndexPacket))
throw new IllegalArgumentException("Invalid packet type: " + packetToStore.getClass().getSimpleName() + "; this folder only stores packets of type " + IndexPacket.class.getSimpleName() + ".");
IndexPacket indexPacketToStore = (IndexPacket) packetToStore;
// set the time stamps before merging so existing ones don't change
setTimeStamps(indexPacketToStore);
// use super.retrieve() because we don't want to delete time stamps here
DhtStorablePacket existingPacket = super.retrieve(packetToStore.getDhtKey());
// make a Delete Request that contains any known-to-be-deleted DHT keys from the store request
String delFileName = getDeletionFileName(packetToStore.getDhtKey());
DeletionInfoPacket delInfo = createDelInfoPacket(delFileName);
IndexPacketDeleteRequest delRequest = null;
if (delInfo != null) {
delRequest = null;
for (IndexPacketEntry entry : indexPacketToStore) {
DeletionRecord delRecord = delInfo.getEntry(entry.emailPacketKey);
if (delRecord != null) {
// leave delRequest null until a DeletionRecord is found
if (delRequest == null)
delRequest = new IndexPacketDeleteRequest(indexPacketToStore.getDhtKey());
delRequest.put(delRecord.dhtKey, delRecord.delAuthorization);
}
}
}
// remove deleted entries from indexPacketToStore so they are not re-stored
if (delInfo != null && !delInfo.isEmpty())
for (DeletionRecord delRecord : delInfo) indexPacketToStore.remove(delRecord.dhtKey);
// The resulting packet may be too big for a datagram but we don't split it until a peer asks for it.
if (existingPacket instanceof IndexPacket)
indexPacketToStore = new IndexPacket(indexPacketToStore, (IndexPacket) existingPacket);
else if (existingPacket != null)
log.error("Packet of type " + existingPacket.getClass().getSimpleName() + " found in IndexPacketFolder.");
// don't merge, but overwrite
super.store(indexPacketToStore);
return delRequest;
}
use of i2p.bote.packet.dht.IndexPacket in project i2p.i2p-bote by i2p.
the class CheckEmailTask method getIndexPackets.
/**
* Returns all Index Packets in a <code>Collection</code> of {@link DhtStorablePacket}s.
* @param dhtPackets Should only contain index packets; other packets are ignored
* @return An <code>IndexPacket</code> containing all entries from the packets in the <code>Collection</code>
*/
private Collection<IndexPacket> getIndexPackets(Collection<DhtStorablePacket> dhtPackets) {
Collection<IndexPacket> indexPackets = new ArrayList<IndexPacket>();
for (DhtStorablePacket packet : dhtPackets) if (packet instanceof IndexPacket)
indexPackets.add((IndexPacket) packet);
else
log.error("DHT returned packet of class " + packet.getClass().getSimpleName() + ", expected IndexPacket.");
return indexPackets;
}
use of i2p.bote.packet.dht.IndexPacket in project i2p.i2p-bote by i2p.
the class CheckEmailTask method call.
/**
* Returns <code>true</code> if a new email was created in the inbox as a result
* of receiving an email packet.
*/
@Override
public Boolean call() throws InterruptedException, ExecutionException, TimeoutException, GeneralSecurityException {
log.debug("Querying the DHT for index packets with key " + identity.getHash());
// Use findAll rather than findOne because some peers might have an incomplete set of
// Email Packet keys, and because we want to send IndexPacketDeleteRequests to all of them.
DhtResults indexPacketResults = dht.findAll(identity.getHash(), IndexPacket.class);
if (indexPacketResults.isEmpty())
return false;
Collection<IndexPacket> indexPackets = getIndexPackets(indexPacketResults.getPackets());
IndexPacket mergedPacket = new IndexPacket(indexPackets);
log.debug("Found " + mergedPacket.getNumEntries() + " Email Packet keys in " + indexPacketResults.getNumResults() + " Index Packets.");
newEmail = false;
indexPacketDeleteRequest = new IndexPacketDeleteRequest(identity.getHash());
Collection<Future<?>> futureResults = new ArrayList<Future<?>>();
ExecutorService executor = Executors.newFixedThreadPool(MAX_THREADS, EMAIL_PACKET_TASK_THREAD_FACTORY);
for (IndexPacketEntry entry : mergedPacket) {
Runnable task = new EmailPacketTask(entry.emailPacketKey);
futureResults.add(executor.submit(task));
}
// end all EmailPacketTask threads when tasks are finished
executor.shutdown();
// wait until all EmailPacketTasks are done
try {
for (Future<?> result : futureResults) result.get(1, TimeUnit.HOURS);
} catch (InterruptedException e) {
executor.shutdownNow();
Thread.currentThread().interrupt();
throw new InterruptedException("EmailPacketTask interrupted");
}
// delete index packets if all EmailPacketTasks finished without throwing an exception
Set<Destination> indexPacketPeers = indexPacketResults.getPeers();
if (indexPacketDeleteRequest.getNumEntries() > 0)
send(indexPacketDeleteRequest, indexPacketPeers);
return newEmail;
}
use of i2p.bote.packet.dht.IndexPacket in project i2p.i2p-bote by i2p.
the class IndexPacketFolder method process.
/**
* Deletes index packet entries.
* @param delRequest An instance of {@link IndexPacketDeleteRequest}
*/
@Override
public synchronized void process(DeleteRequest delRequest) {
log.debug("Processing delete request: " + delRequest);
if (!(delRequest instanceof IndexPacketDeleteRequest))
log.error("Invalid type of delete request for IndexPacketFolder: " + delRequest.getClass());
IndexPacketDeleteRequest indexPacketDelRequest = (IndexPacketDeleteRequest) delRequest;
Hash destHash = indexPacketDelRequest.getEmailDestHash();
DhtStorablePacket storedPacket = retrieve(destHash);
if (storedPacket instanceof IndexPacket) {
IndexPacket indexPacket = (IndexPacket) storedPacket;
Collection<Hash> keysToDelete = indexPacketDelRequest.getDhtKeys();
for (Hash keyToDelete : keysToDelete) {
// verify
Hash verificationHash = indexPacket.getDeleteVerificationHash(keyToDelete);
if (verificationHash == null)
log.debug("Email packet key " + keyToDelete + " from IndexPacketDeleteRequest not found in index packet for destination " + destHash);
else {
UniqueId delAuthorization = indexPacketDelRequest.getDeleteAuthorization(keyToDelete);
boolean valid = Util.isDeleteAuthorizationValid(verificationHash, delAuthorization);
if (valid)
remove(indexPacket, keyToDelete, delAuthorization);
else
log.debug("Invalid delete verification hash in IndexPacketDeleteRequest. Should be: <" + verificationHash.toBase64() + ">");
}
}
} else if (storedPacket != null)
log.debug("IndexPacket expected for DHT key <" + destHash + ">, found " + storedPacket.getClass().getSimpleName());
}
use of i2p.bote.packet.dht.IndexPacket in project i2p.i2p-bote by i2p.
the class IndexPacketFolderTest method testIndividualPackets.
@Test
public void testIndividualPackets() {
IndexPacket indexPacket1 = new IndexPacket(destination1);
indexPacket1.put(emailPacket1);
IndexPacket indexPacket2 = new IndexPacket(destination2);
IndexPacket indexPacket3 = new IndexPacket(destination3);
indexPacket2.put(emailPacket1);
indexPacket2.put(emailPacket2);
folder.store(indexPacket1);
folder.store(indexPacket2);
folder.store(indexPacket3);
Iterator<IndexPacket> iterator = folder.individualPackets();
int numIndivEntries = 0;
while (iterator.hasNext()) {
iterator.next();
numIndivEntries++;
}
assertEquals(3, numIndivEntries);
}
Aggregations