Author: xor
Date: 2008-11-10 03:58:08 +0000 (Mon, 10 Nov 2008)
New Revision: 23466
Modified:
trunk/plugins/WoT/introduction/IntroductionPuzzle.java
trunk/plugins/WoT/introduction/IntroductionServer.java
Log:
Implement some more of the identity introduction stuff.
Modified: trunk/plugins/WoT/introduction/IntroductionPuzzle.java
===================================================================
--- trunk/plugins/WoT/introduction/IntroductionPuzzle.java 2008-11-10
03:22:59 UTC (rev 23465)
+++ trunk/plugins/WoT/introduction/IntroductionPuzzle.java 2008-11-10
03:58:08 UTC (rev 23466)
@@ -5,6 +5,10 @@
*/
package plugins.WoT.introduction;
+import com.db4o.ObjectContainer;
+import com.db4o.ObjectSet;
+import com.db4o.query.Query;
+
import plugins.WoT.Identity;
public class IntroductionPuzzle {
@@ -16,22 +20,39 @@
private final PuzzleType mType;
+ private final String mMimeType;
+
+ private final String mFilename;
+
private final byte[] mData;
private final String mSolution;
private final Identity mInserter;
+ private final long mValidUntilTime;
+
+ /* FIXME: wire this in */
/**
+ * Get a list of fields which the database should create an index on.
+ */
+ public static String[] getIndexedFields() {
+ return new String[] {"mInserter"};
+ }
+
+ /**
* For construction from a received puzzle.
* @param newType
* @param newData
*/
- public IntroductionPuzzle(Identity newInserter, PuzzleType newType,
byte[] newData) {
+ public IntroductionPuzzle(Identity newInserter, PuzzleType newType,
String newMimeType, String newFilename, byte[] newData, long newValidUntilTime)
{
mInserter = newInserter;
mType = newType;
+ mMimeType = newMimeType;
+ mFilename = newFilename;
mData = newData;
- mSolution = null;
+ mSolution = null;
+ mValidUntilTime = newValidUntilTime;
}
/**
@@ -39,17 +60,29 @@
* @param newType
* @param newData
*/
- public IntroductionPuzzle(Identity newInserter, PuzzleType newType,
byte[] newData, String newSolution) {
+ public IntroductionPuzzle(Identity newInserter, PuzzleType newType,
String newMimeType, String newFilename, byte[] newData, String newSolution) {
mInserter = newInserter;
mType = newType;
+ mMimeType = newMimeType;
+ mFilename = newFilename;
mData = newData;
- mSolution = newSolution;
+ mSolution = newSolution;
+ mValidUntilTime = System.currentTimeMillis() +
IntroductionServer.PUZZLE_INVALID_AFTER_DAYS * 24 * 60 * 60 * 1000;
}
public PuzzleType getPuzzleType() {
return mType;
}
+ public String getMimeType() {
+ return mMimeType;
+ }
+
+ public String getFilename() {
+ /* FIXME: include date etc. */
+ return mFilename;
+ }
+
public byte[] getPuzzle() {
return mData;
}
@@ -65,4 +98,26 @@
public Identity getInserter() {
return mInserter;
}
+
+ public long getValidUntilTime() {
+ return mValidUntilTime;
+ }
+
+
+ public void store(ObjectContainer db) {
+ db.store(this);
+ db.commit();
+ }
+
+ public static void deleteOldPuzzles(ObjectContainer db) {
+ Query q = db.query();
+ q.constrain(IntroductionPuzzle.class);
+
q.descend("mValidUntilTime").constrain(System.currentTimeMillis()).smaller();
+ ObjectSet<IntroductionPuzzle> result = q.execute();
+
+ for(IntroductionPuzzle p : result)
+ db.delete(p);
+
+ db.commit();
+ }
}
Modified: trunk/plugins/WoT/introduction/IntroductionServer.java
===================================================================
--- trunk/plugins/WoT/introduction/IntroductionServer.java 2008-11-10
03:22:59 UTC (rev 23465)
+++ trunk/plugins/WoT/introduction/IntroductionServer.java 2008-11-10
03:58:08 UTC (rev 23466)
@@ -5,15 +5,31 @@
*/
package plugins.WoT.introduction;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.OutputStream;
import java.util.Date;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+
import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
+import com.db4o.ext.DatabaseClosedException;
+import com.db4o.ext.Db4oIOException;
+import com.db4o.query.Query;
+import freenet.client.ClientMetadata;
import freenet.client.HighLevelSimpleClient;
+import freenet.client.InsertBlock;
+import freenet.client.InsertException;
+import freenet.keys.FreenetURI;
import freenet.support.Logger;
+import freenet.support.api.Bucket;
import freenet.support.io.TempBucketFactory;
import plugins.WoT.OwnIdentity;
+import plugins.WoT.exceptions.InvalidParameterException;
/**
* This class provides identity announcement for new identities; It uploads
puzzles in certain time intervals and checks whether they were solved.
@@ -22,22 +38,27 @@
*/
public class IntroductionServer implements Runnable {
- private static long THREAD_PERIOD = 30 * 60 * 1000;
- private static short PUZZLES_PER_DAY = 1;
- private static long PUZZLE_INVALID_AFTER_DAYS = 3;
+ private static final long THREAD_PERIOD = 30 * 60 * 1000;
+ private static final short PUZZLES_COUNT = 5;
+ public static final long PUZZLE_INVALID_AFTER_DAYS = 3;
+ private static final String INTRODUCTION_CONTEXT = "introduction";
+ private Thread mThread;
+
+ /** Used to tell the introduction server thread if it should stop */
+ private boolean isRunning;
+
/** A reference to the database */
- ObjectContainer db;
+ private ObjectContainer db;
/** A reference the HighLevelSimpleClient used to perform inserts */
- HighLevelSimpleClient client;
+ private HighLevelSimpleClient mClient;
/** The TempBucketFactory used to create buckets from puzzles before
insert */
- final TempBucketFactory tBF;
-
- /** Used to tell the introduction server thread if it should stop */
- boolean isRunning;
+ private final TempBucketFactory mTBF;
+ private final IntroductionPuzzleFactory[] mPuzzleFactories = new
IntroductionPuzzleFactory[] { new CaptchaFactory1() };
+
/**
* Creates an IntroductionServer
*
@@ -49,33 +70,32 @@
* @param tbf
* Needed to create buckets from Identities before insert
*/
- public IntroductionServer(ObjectContainer db, HighLevelSimpleClient
client, TempBucketFactory tbf) {
- this.db = db;
- this.client = client;
+ public IntroductionServer(ObjectContainer myDB, HighLevelSimpleClient
myClient, TempBucketFactory myTBF) {
isRunning = true;
- tBF = tbf;
+ db = myDB;
+ mClient = myClient;
+ mTBF = myTBF;
}
public void run() {
+ mThread = Thread.currentThread();
try {
- Thread.sleep((long) (3*60*1000 * (0.5f +
Math.random()))); // Let the node start up
+ Thread.sleep((long) (1*60*1000 * (0.5f +
Math.random()))); // Let the node start up
}
catch (InterruptedException e) {}
while(isRunning) {
ObjectSet<OwnIdentity> identities =
OwnIdentity.getAllOwnIdentities(db);
+ IntroductionPuzzle.deleteOldPuzzles(db);
+
while(identities.hasNext()) {
OwnIdentity identity = identities.next();
- synchronized(identity) {
- if(identity.hasContext("introduction"))
{
- try {
- insertPuzzles(identity);
- //
identity.setLastInsert(new Date());
- // db.store(identity);
- } catch (Exception e) {
- Logger.error(this,
"Puzzle insert failed: " + e.getMessage(), e);
- }
+ if(identity.hasContext("introduction")) {
+ try {
+ managePuzzles(identity);
+ } catch (Exception e) {
+ Logger.error(this, "Puzzle
insert failed: " + e.getMessage(), e);
}
}
}
@@ -84,13 +104,61 @@
try {
Thread.sleep((long) (THREAD_PERIOD * (0.5f +
Math.random())));
}
- catch (InterruptedException e){}
+ catch (InterruptedException e)
+ {
+ mThread.interrupt();
+ }
}
}
- private void insertPuzzles(OwnIdentity identity) {
+ public void terminate() {
+ Logger.debug(this, "Stopping the introduction server...");
+ isRunning = false;
+ mThread.interrupt();
+ try {
+ mThread.join();
+ }
+ catch(InterruptedException e)
+ {
+ Thread.currentThread().interrupt();
+ }
+ Logger.debug(this, "Stopped the introduction server.");
+ }
+
+ private void managePuzzles(OwnIdentity identity) {
+ Query q = db.query();
+ q.constrain(IntroductionPuzzle.class);
+ q.descend("mInserter").constrain(identity);
+ ObjectSet<IntroductionPuzzle> puzzles = q.execute();
}
+
+ private void insertNewPuzzle(OwnIdentity identity) throws IOException,
InsertException {
+ Bucket tempB = mTBF.makeBucket(10 * 1024);
+ OutputStream os = tempB.getOutputStream();
+
+ try {
+ IntroductionPuzzle p =
mPuzzleFactories[(int)(Math.random() * 100) %
mPuzzleFactories.length].generatePuzzle();
+ os.write(p.getPuzzle());
+ os.close();
+ tempB.setReadOnly();
+
+ ClientMetadata cmd = new
ClientMetadata(p.getMimeType());
+ FreenetURI uri = new FreenetURI("KSK", p.getFilename());
+ InsertBlock ib = new InsertBlock(tempB, cmd, uri);
+ Logger.debug(this, "Started insert puzzle from '" +
identity.getNickName() + "'");
+
+ /* FIXME: use nonblocking insert */
+ mClient.insert(ib, true, p.getFilename());
+
+ db.store(p);
+ db.commit();
+ } finally {
+ tempB.free();
+ }
+
+ Logger.debug(this, "Successful insert of puzzle for '" +
identity.getNickName() + "'");
+ }
}