--- /dev/null
+package org.opensrf;
+import java.util.Date;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Random;
+
+import org.opensrf.util.*;
+
+
+/**
+ * Models an OpenSRF client session.
+ */
+public class ClientSession extends Session {
+
+ /** The remote service to communicate with */
+ private String service;
+ private String domain;
+ private String router;
+ private String origRemoteNode;
+ private int nextId;
+ private List<Request> requests;
+
+ /**
+ * @param service The remove service to communicate with
+ */
+ public ClientSession(String service) throws ConfigException {
+ this.service = service;
+ domain = (String) Config.getFirst("/domain/domains");
+ router = (String) Config.getString("/router_name");
+ setRemoteNode(router + "@" + domain + "/" + service);
+ origRemoteNode = getRemoteNode();
+ requests = new ArrayList<Request>();
+ nextId = 0;
+ long time = new Date().getTime();
+ Random rand = new Random(time);
+ thread = rand.nextInt()+""+rand.nextInt()+""+time;
+ cacheSession();
+ }
+}
+
--- /dev/null
+package org.opensrf;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.List;
+import org.opensrf.net.xmpp.XMPPException;
+
+public class Request {
+
+ private ClientSession session;
+ private Method method;
+ private int id;
+ private Queue<Result> resultQueue;
+ private boolean resetTimeout;
+ private boolean complete;
+
+ public Request(ClientSession ses, int id, Method method) {
+ this.session = ses;
+ this.id = id;
+ this.method = method;
+ resultQueue = new ConcurrentLinkedQueue<Result>();
+ complete = false;
+ resetTimeout = false;
+ }
+
+ public Request(ClientSession ses, int id, String methodName, List<Object> params) {
+ this(ses, id, new Method(methodName, params));
+ }
+
+ public void send() throws XMPPException {
+ session.send(new Message(id, Message.Type.REQUEST, method));
+ }
+}
--- /dev/null
+package org.opensrf;
+
+/**
+ * Models an OpenSRF server session.
+ */
+public class ServerSession extends Session {
+}
+
* In other words, each session has a unique thread, and all messages
* in that session will carry this thread around as an indicator.
*/
- private String thread;
+ protected String thread;
public Session() {
connectState = ConnectState.DISCONNECTED;
public static Session findCachedSession(String thread) {
return sessionCache.get(thread);
}
+
+ protected void cacheSession() {
+ sessionCache.put(thread, this);
+ }
+
+ public void setRemoteNode(String nodeName) {
+ remoteNode = nodeName;
+ }
+ public String getRemoteNode() {
+ return remoteNode;
+ }
}
--- /dev/null
+package org.opensrf;
+import org.opensrf.net.xmpp.XMPPMessage;
+import org.opensrf.util.*;
+import java.util.Date;
+import java.util.List;
+import java.util.Iterator;
+
+
+public class Stack {
+
+ public static void processXMPPMessage(XMPPMessage msg) {
+
+ Session ses = Session.findCachedSession(msg.getThread());
+
+ if(ses == null) {
+ /** inbound client request, create a new server session */
+ return;
+ }
+
+ /** parse the JSON message body, which should result in a list of OpenSRF messages */
+ List msgList;
+
+ try {
+ msgList = new JSONReader(msg.getBody()).readArray();
+ } catch(JSONException e) {
+ /** XXX LOG error */
+ return;
+ }
+
+ Iterator itr = msgList.iterator();
+
+ OSRFObject obj = null;
+ long start = new Date().getTime();
+
+ while(itr.hasNext()) {
+ /** Construct a Message object from the generic OSRFObject returned from parsing */
+ obj = (OSRFObject) itr.next();
+ processOSRFMessage(ses,
+ new Message(
+ ((Integer) obj.get("threadTrace")).intValue(),
+ (Message.Type) obj.get("type"),
+ obj.get("payload")));
+ }
+
+ /** LOG the duration */
+ }
+
+ public static void processOSRFMessage(Session ses, Message msg) {
+ if( ses instanceof ClientSession )
+ processServerResponse((ClientSession) ses, msg);
+ else
+ processClientRequest((ServerSession) ses, msg);
+ }
+
+ public static void processServerResponse(ClientSession session, Message msg) {
+ }
+
+ public static void processClientRequest(ServerSession session, Message msg) {
+ }
+}
--- /dev/null
+package org.opensrf.test;
+import org.opensrf.*;
+import org.opensrf.util.*;
+
+public class TestConfig {
+ public static void main(String args[]) throws Exception {
+ Config config = new Config("");
+ config.parse(args[0]);
+ Config.setConfig(config);
+ System.out.println(config);
+ System.out.println("");
+
+ for(int i = 1; i < args.length; i++)
+ System.out.println("Found config value: " + args[i] + ": " + Config.get(args[i]));
+ }
+}
--- /dev/null
+package org.opensrf.util;
+
+import org.json.*;
+import java.util.Map;
+import java.util.List;
+
+
+/**
+ * Config reader and accesor module. This module reads an XML config file,
+ * then loads the file into an internal config, whose values may be accessed
+ * by xpath-style lookup paths.
+ */
+public class Config {
+
+ /** The globl config instance */
+ private static Config config;
+ /** The object form of the parsed config */
+ private Map configObject;
+ private String context;
+
+ public Config(String context) {
+ this.context = context;
+ }
+
+ /**
+ * Sets the global config object.
+ * @param c The config object to use.
+ */
+ public static void setConfig(Config c) {
+ config = c;
+ }
+
+ /**
+ * Parses an XML config file.
+ * @param filename The path to the file to parse.
+ */
+ public void parse(String filename) throws Exception {
+ String xml = Utils.fileToString(filename);
+ JSONObject jobj = XML.toJSONObject(xml);
+ configObject = (Map) new JSONReader(jobj.toString()).readObject();
+ }
+
+ /**
+ * Returns the configuration value found at the requested path.
+ * @see org.opensrf.util.Utils.findPath for path description.
+ * @param path The search path
+ * @return The config value, or null if no value exists at the given path.
+ * @throws ConfigException thrown if nothing is found at the path
+ */
+ public static String getString(String path) throws ConfigException {
+ try {
+ return (String) get(path);
+ } catch(Exception e) {
+ throw new
+ ConfigException("No config string found at " + path);
+ }
+ }
+
+ /**
+ * Returns the configuration object found at the requested path.
+ * @see org.opensrf.util.Utils.findPath for path description.
+ * @param path The search path
+ * @return The config value
+ * @throws ConfigException thrown if nothing is found at the path
+ */
+ public static Object get(String path) throws ConfigException {
+ try {
+ Object obj = Utils.findPath(config.configObject, config.context + path);
+ if(obj == null)
+ throw new ConfigException("");
+ return obj;
+ } catch(Exception e) {
+ e.printStackTrace();
+ throw new ConfigException("No config object found at " + path);
+ }
+ }
+
+ public static Object getFirst(String path) throws ConfigException {
+ Object obj = get(path);
+ if(obj instanceof List)
+ return ((List) obj).get(0);
+ return obj;
+ }
+
+
+ /**
+ * Returns the config as a JSON string
+ */
+ public String toString() {
+ return new JSONWriter(configObject).write();
+ }
+}
+
--- /dev/null
+package org.opensrf.util;
+
+/**
+ * Thrown by the Config module when a user requests a configuration
+ * item that does not exist
+ */
+public class ConfigException extends Exception {
+ public ConfigException(String info) {
+ super(info);
+ }
+}
--- /dev/null
+package org.opensrf.util;
+public class JSONException extends Exception {
+ public JSONException(String s) {
+ super(s);
+ }
+}
}
}
}
+
+
+ /**
+ * Descends into the map along the given XPATH-style path
+ * and returns the object found there.
+ * @param path The XPATH-style path to search. Path
+ * components are separated by '/' characters.
+ * Example: /opensrf/loglevel
+ * @return The found object.
+ */
+
+ public static Object findPath(Map map, String path) {
+ String keys[] = path.split("/", -1);
+ int i = 0;
+ if(path.charAt(0) == '/') i++;
+ for(; i < keys.length - 1; i++ )
+ map = (Map) map.get(keys[i]);
+
+ return map.get(keys[i]);
+ }
}