Bureaucracy review updates and hello world test

* Fleshed out client-side Agent class, made abstract
* Delegate the creation of the bureau director to subclasses of BureauClient
* Moved BureauDirector's BureauReceiver and Subscriber implementations to 
  anonymous classes that delegate to protected methods.
* Use SafeSubscriber
* Added new service method for notiyfing the server when the creation of an
  agent fails so that the registry is not perpetually waiting
* Made BureauCredentials more conformant
* Made BureauRegistry respond properly to client logging off
* Got rid of superfluous uses of safeToString
* Changed Launcher to CommandGenerator and now use ProcessBuilder and 
  copyMergedOutput
* Changed bureau process parameters to server name and port instead of URL


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@5030 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Jamie Doornbos
2008-04-29 18:34:51 +00:00
parent 938d7f5994
commit f41233c5ac
12 changed files with 558 additions and 128 deletions
+20
View File
@@ -179,4 +179,24 @@
</batchtest>
</junit>
</target>
<target name="bureau-runserver" depends="compile"
description="Run the bureau test server.">
<java fork="true" classname="com.threerings.bureau.server.TestServer">
<classpath refid="classpath"/>
</java>
</target>
<!-- NOTE: this target is launched by the bureau-runserver target, modelling the way bureaus -->
<!-- work. As such it is not currently useful on its own -->
<target name="bureau-runclient" depends="compile"
description="Run the bureau test client.">
<java fork="true" classname="com.threerings.bureau.client.TestClient">
<classpath refid="classpath"/>
<sysproperty key="serverName" value="${serverName}"/>
<sysproperty key="serverPort" value="${serverPort}"/>
<sysproperty key="token" value="${token}"/>
<sysproperty key="bureauId" value="${bureauId}"/>
</java>
</target>
</project>
@@ -0,0 +1,132 @@
//
// $Id$
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.bureau.client;
import com.samskivert.util.OneLineLogFormatter;
import com.threerings.bureau.Log;
import com.samskivert.util.Queue;
import com.samskivert.util.StringUtil;
import com.threerings.bureau.client.BureauDirector;
import com.threerings.bureau.data.AgentObject;
import com.samskivert.util.RunQueue;
/**
* Extends bureau client minimally and provides a static main function to create a client and
* connect to a server given by system properties.
*/
public class TestClient extends BureauClient
{
public static void main (String args[])
throws java.net.MalformedURLException
{
// make log pretty
OneLineLogFormatter.configureDefaultHandler();
// create the client and log on
TestClient client = new TestClient(
System.getProperty("token"),
System.getProperty("bureauId"));
client.setServer(
System.getProperty("serverName"),
new int[] {Integer.parseInt(System.getProperty("serverPort"))});
client.logon();
// run it
client.run();
}
/**
* Implements most basic run queue. Required to instantate a client.
*/
static protected class SimpleRunQueue implements RunQueue
{
public void postRunnable (Runnable r)
{
_queue.append(r);
}
public boolean isDispatchThread ()
{
return _main == Thread.currentThread();
}
public void run ()
{
_main = Thread.currentThread();
while (true) {
Runnable r = _queue.get();
r.run();
}
}
protected Thread _main;
protected Queue<Runnable> _queue = new Queue<Runnable>();
}
/**
* The agent class used by our director. Does not actually load any code, just logs the
* start/stop requests.
*/
static protected class TestAgent extends Agent
{
public void start ()
{
Log.info("Starting agent " + StringUtil.toString(_agentObj));
}
public void stop ()
{
Log.info("Stopping agent " + StringUtil.toString(_agentObj));
}
}
/**
* Constructs a new test client.
*/
protected TestClient (String token, String bureauId)
{
super(token, bureauId, new SimpleRunQueue());
}
/**
* Runs the event loop.
*/
protected void run ()
{
((SimpleRunQueue)_runQueue).run();
}
// overridden - creates a simple director
protected BureauDirector createDirector ()
{
// just use our test agent exclusively - in the real world, the agent created would depend
// on the object's type and/or properties
return new BureauDirector(_ctx) {
public Agent createAgent (AgentObject agentObj) {
return new TestAgent();
}
};
}
}
@@ -0,0 +1,107 @@
//
// $Id$
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.bureau.server;
import com.threerings.bureau.Log;
import com.threerings.bureau.data.AgentObject;
import com.threerings.presents.server.PresentsServer;
import com.samskivert.util.OneLineLogFormatter;
import com.samskivert.util.StringUtil;
import java.io.File;
/**
* Extends a presents server to include a bureau registry.
*/
public class TestServer extends PresentsServer
{
/**
* The bureau registry for the server. Will be null until <code>init</code> is called.
*/
public static BureauRegistry breg;
/**
* Creates a new server and runs it.
*/
public static void main (String[] args)
{
// make log pretty
OneLineLogFormatter.configureDefaultHandler();
final TestServer server = new TestServer();
try {
server.init();
// request a new agent
// TODO: more tests here - create a thread that posts different kinds of requests
// and somehow monitors results from client
server.omgr.postRunnable(new Runnable() {
public void run () {
server.createTestAgent();
}
});
server.run();
} catch (Exception e) {
Log.warning("Unable to initialize server.");
Log.logStackTrace(e);
}
}
// inherit documentation - from PresentsServer
public void init ()
throws Exception
{
super.init();
breg = new BureauRegistry("localhost:47624", invmgr, omgr);
breg.setCommandGenerator("test", new BureauRegistry.CommandGenerator() {
public String[] createCommand (
String serverNameAndPort,
String bureauId,
String token) {
int colon = serverNameAndPort.indexOf(':');
String [] cmd = {"ant",
"-DserverName=" + serverNameAndPort.substring(0, colon),
"-DserverPort=" + serverNameAndPort.substring(colon + 1),
"-DbureauId=" + bureauId,
"-Dtoken=" + token,
"bureau-runclient"};
return cmd;
}
});
}
/**
* Requests that the bureau client create an agent.
*/
protected void createTestAgent ()
{
AgentObject obj = new AgentObject();
obj.bureauType = "test";
obj.bureauId = "test";
breg.startAgent(obj);
}
}