Added support for multi-router registration
authorerickson <erickson@9efc2488-bf62-4759-914b-345cdb29e865>
Wed, 5 Mar 2008 22:36:59 +0000 (22:36 +0000)
committererickson <erickson@9efc2488-bf62-4759-914b-345cdb29e865>
Wed, 5 Mar 2008 22:36:59 +0000 (22:36 +0000)
replaced unnecessary <domains><domain/></domains> with a single <domain> element in opensrf_core.xml
wrapped the top-level <router> element in a <routers> container element in opensrf_core.xml to
    support additional router configuration
Updated the python, C, and Perl to match the above changes
Gave the router the ability to launch more than one router process, based on the config
Added a transport_error flag to C session to indicate a communcation error, which will prevent
    client sessions from hanging when making bad requests

git-svn-id: svn://svn.open-ils.org/OpenSRF/trunk@1253 9efc2488-bf62-4759-914b-345cdb29e865

19 files changed:
bin/osrf_ctl.sh
examples/opensrf_core.xml.example
include/opensrf/osrfConfig.h
include/opensrf/osrf_app_session.h
src/libopensrf/osrfConfig.c
src/libopensrf/osrf_app_session.c
src/libopensrf/osrf_prefork.c
src/libopensrf/osrf_stack.c
src/libopensrf/osrf_system.c
src/perlmods/OpenSRF/AppSession.pm
src/perlmods/OpenSRF/Transport/SlimJabber/Inbound.pm
src/perlmods/OpenSRF/Transport/SlimJabber/PeerConnection.pm
src/perlmods/OpenSRF/Utils/Config.pm
src/python/osrf/http_translator.py
src/python/osrf/ses.py
src/python/osrf/stack.py
src/python/osrf/system.py
src/router/osrf_router_main.c
src/srfsh/srfsh.c

index cc04f9d..c96f5b8 100755 (executable)
@@ -135,7 +135,7 @@ function do_action {
 
 function start_router {
        do_action "start" $PID_ROUTER "OpenSRF Router";
-       opensrf_router $OPT_CONFIG router
+       opensrf_router $OPT_CONFIG routers
        pid=$(ps ax | grep "OpenSRF Router" | grep -v grep | awk '{print $1}')
        echo $pid > $PID_ROUTER;
        return 0;
index a46df77..b450a09 100644 (file)
       <router>localhost</router>
 
     </routers>
-    <domains>
 
-      <!-- Our jabber domain, currently only one domain is supported -->
-      <domain>localhost</domain>
+    <!-- Our jabber domain, currently only one domain is supported -->
+    <domain>localhost</domain>
 
-    </domains>
     <username>client</username>
     <passwd>mypass</passwd>
     <port>5222</port>
 
   <!-- ======================================================================================== -->
 
-  <router>
-
-    <!-- do not change -->
-    <component>0</component>
-
-    <trusted_domains>
-
-      <!-- Trusted servers are allowed to register apps with the router -->
-      <server>localhost</server>
-
-      <!-- Trusted clients are allowed to send packets through the router -->
-      <client>localhost</client>
-
-    </trusted_domains>
-
-    <transport>
-
-      <!-- jabber server are we connecting to -->
-      <server>localhost</server>
-      <port>5222</port>
-
-      <!-- if this is changed, all "router_name" settings 
-                will need to be updated to match this setting -->
-      <username>router</username>
-      <password>mypassword</password>
-
-      <!-- router's jabber resource -->
-      <!-- do not change this -->
-      <resource>router</resource>
-      <connect_timeout>10</connect_timeout>
-      <max_reconnect_attempts>5</max_reconnect_attempts>
-
-    </transport>
-    <logfile>/openils/var/log/router.log</logfile>
-    <loglevel>3</loglevel>
-
-  </router>
+  <routers>
+    <router>
+
+      <trusted_domains>
+
+        <!-- servers on trunsted domains are allowed to register apps with the router -->
+        <server>localhost</server>
+  
+        <!-- clients on trusted domains are allowed to send requests to this router -->
+        <client>localhost</client>
+  
+      </trusted_domains>
+  
+      <transport>
+  
+        <!-- jabber server are we connecting to -->
+        <server>localhost</server>
+        <port>5222</port>
+  
+        <!-- if this is changed, all "router_name" settings 
+                  will need to be updated to match this setting -->
+        <username>router</username>
+        <password>mypassword</password>
+  
+        <!-- router's jabber resource -->
+        <!-- do not change this -->
+        <resource>router</resource>
+        <connect_timeout>10</connect_timeout>
+        <max_reconnect_attempts>5</max_reconnect_attempts>
+  
+        </transport>
+      <logfile>/openils/var/log/router.log</logfile>
+      <loglevel>3</loglevel>
+  
+    </router>
+  </routers>
 
   <!-- ======================================================================================== -->
 
 </config>
+
index dbe59ed..90938d5 100644 (file)
@@ -85,6 +85,14 @@ void osrfConfigCleanup();
 */
 char* osrfConfigGetValue(osrfConfig* cfg, char* path, ...);
 
+
+/**
+ *  @see osrfConfigGetValue
+ *  @return jsonObject found at path
+ */
+jsonObject* osrfConfigGetValueObject(osrfConfig* cfg, char* path, ...);
+
+
 /** 
        Puts the list of values found at 'path' into the pre-allocated 
        string array.  
index d5d0b19..85beb96 100644 (file)
@@ -81,6 +81,8 @@ struct osrf_app_session_struct {
        void* userData;
 
        void (*userDataFree) (void*);
+
+    int transport_error;
 };
 typedef struct osrf_app_session_struct osrf_app_session;
 typedef struct osrf_app_session_struct osrfAppSession;
index 40dcee0..a315cc1 100644 (file)
@@ -71,30 +71,38 @@ osrfConfig* osrfConfigInit(char* configFile, char* configContext) {
        return cfg;
 }
 
-char* osrfConfigGetValue(osrfConfig* cfg, char* path, ...) {
 
+char* osrfConfigGetValue(osrfConfig* cfg, char* path, ...) {
        if(!path) return NULL;
        if(!cfg) cfg = osrfConfigDefault;
-       if(!cfg) { osrfLogWarning( OSRF_LOG_MARK, "No Config object in osrfConfigGetValue()"); return NULL; }
+       if(!cfg) { 
+        osrfLogWarning( OSRF_LOG_MARK, "No Config object in osrfConfigGetValue()"); 
+        return NULL; 
+    }
 
        VA_LIST_TO_STRING(path);
-
        jsonObject* obj;
-       char* val = NULL;
 
-       if(cfg->configContext) {
-               obj = jsonObjectFindPath( cfg->config, "//%s%s", cfg->configContext, VA_BUF);
-               if(obj) val = jsonObjectToSimpleString(jsonObjectGetIndex(obj, 0));
-
-       } else {
+       if(cfg->configContext) 
+               obj = jsonObjectGetIndex(
+            jsonObjectFindPath(cfg->config, "//%s%s", cfg->configContext, VA_BUF), 0);
+       else
                obj = jsonObjectFindPath( cfg->config, VA_BUF);
-               if(obj) val = jsonObjectToSimpleString(obj);
-       }
 
-       jsonObjectFree(obj);
-       return val;
+       char* val = jsonObjectToSimpleString(obj);
+    jsonObjectFree(obj);
+    return val;
 }
 
+jsonObject* osrfConfigGetValueObject(osrfConfig* cfg, char* path, ...) {
+       if(!path) return NULL;
+       if(!cfg) cfg = osrfConfigDefault;
+       VA_LIST_TO_STRING(path);
+       if(cfg->configContext) 
+        return jsonObjectFindPath(cfg->config, "//%s%s", cfg->configContext, VA_BUF);
+       else
+               return jsonObjectFindPath(cfg->config, VA_BUF);
+}
 
 int osrfConfigGetValueList(osrfConfig* cfg, osrfStringArray* arr, char* path, ...) {
 
index df9e0b7..c5f68be 100644 (file)
@@ -109,6 +109,10 @@ static osrfMessage* _osrf_app_request_recv( osrfAppRequest* req, int timeout ) {
                osrfLogDebug( OSRF_LOG_MARK,  "In app_request receive with remaining time [%d]", (int) remaining );
 
                osrf_app_session_queue_wait( req->session, 0, NULL );
+        if(req->session->transport_error) {
+            osrfLogError(OSRF_LOG_MARK, "Transport error in recv()");
+            return NULL;
+        }
 
                if( req->result != NULL ) { /* if we received anything */
                        /* pop off the first message in the list */
@@ -129,6 +133,11 @@ static osrfMessage* _osrf_app_request_recv( osrfAppRequest* req, int timeout ) {
 
                osrf_app_session_queue_wait( req->session, (int) remaining, NULL );
 
+        if(req->session->transport_error) {
+            osrfLogError(OSRF_LOG_MARK, "Transport error in recv()");
+            return NULL;
+        }
+
                if( req->result != NULL ) { /* if we received anything */
                        /* pop off the first message in the list */
                        osrfLogDebug( OSRF_LOG_MARK,  "app_request_recv received a message, returning it");
@@ -225,7 +234,7 @@ osrfAppSession* osrf_app_client_session_init( const char* remote_service ) {
        }
 
        osrfStringArray* arr = osrfNewStringArray(8);
-       osrfConfigGetValueList(NULL, arr, "/domains/domain");
+       osrfConfigGetValueList(NULL, arr, "/domain");
        char* domain = osrfStringArrayGetString(arr, 0);
 
        if (!domain) {
@@ -266,6 +275,7 @@ osrfAppSession* osrf_app_client_session_init( const char* remote_service ) {
        session->orig_remote_id = strdup(session->remote_id);
        session->remote_service = strdup(remote_service);
        session->session_locale = NULL;
+    session->transport_error = 0;
 
        #ifdef ASSUME_STATELESS
        session->stateless = 1;
@@ -502,6 +512,10 @@ int osrf_app_session_connect(osrfAppSession* session){
 
        while( session->state != OSRF_SESSION_CONNECTED && remaining >= 0 ) {
                osrf_app_session_queue_wait( session, remaining, NULL );
+        if(session->transport_error) {
+            osrfLogError(OSRF_LOG_MARK, "cannot communicate with %s", session->remote_service);
+            return 0;
+        }
                remaining -= (int) (time(NULL) - start);
        }
 
index 46d9975..850d6df 100644 (file)
@@ -143,34 +143,59 @@ int osrf_prefork_run(const char* appname) {
 
 }
 
-static void osrf_prefork_register_routers( const char* appname ) {
-
-       osrfStringArray* arr = osrfNewStringArray(4);
-
-       int c = osrfConfigGetValueList( NULL, arr, "/routers/router" );
-       char* routerName = osrfConfigGetValue( NULL, "/router_name" );
+/* sends the "register" packet to the specified router */
+static void osrf_prefork_send_router_registration(const char* appname, const char* routerName, const char* routerDomain) {
        transport_client* client = osrfSystemGetTransportClient();
+    char* jid = va_list_to_string( "%s@%s/router", routerName, routerDomain );
+    osrfLogInfo( OSRF_LOG_MARK, "%s registering with router %s", appname, jid );
+    transport_message* msg = message_init("registering", NULL, NULL, jid, NULL );
+    message_set_router_info( msg, NULL, NULL, appname, "register", 0 );
+    client_send_message( client, msg );
+    message_free( msg );
+    free(jid);
+}
 
-       osrfLogInfo( OSRF_LOG_MARK, "router name is %s and we have %d routers to connect to", routerName, c );
+/** parses a single "complex" router configuration chunk */
+static void osrf_prefork_parse_router_chunk(const char* appname, jsonObject* routerChunk) {
+
+    char* routerName = jsonObjectGetString(jsonObjectGetKey(routerChunk, "name"));
+    char* domain = jsonObjectGetString(jsonObjectGetKey(routerChunk, "domain"));
+    jsonObject* services = jsonObjectGetKey(routerChunk, "services");
+    osrfLogDebug(OSRF_LOG_MARK, "found router config with domain %s and name %s", routerName, domain);
+
+    if(services && services->type == JSON_HASH) {
+        osrfLogDebug(OSRF_LOG_MARK, "investigating router information...");
+        services = jsonObjectGetKey(services, "service");
+        int j;
+        for(j = 0; j < services->size; j++ ) {
+            char* service = jsonObjectGetString(jsonObjectGetIndex(services, j));
+            if(!strcmp(appname, service))
+                osrf_prefork_send_router_registration(appname, routerName, domain);
+        }
+    } else {
+        osrf_prefork_send_router_registration(appname, routerName, domain);
+    }
+}
 
-       while( c ) {
-               char* domain = osrfStringArrayGetString(arr, --c);
-               if(domain) {
+static void osrf_prefork_register_routers( const char* appname ) {
 
-                       char* jid = va_list_to_string( "%s@%s/router", routerName, domain );
-                       osrfLogInfo( OSRF_LOG_MARK, "Registering with router %s", jid );
+    jsonObject* routerInfo = osrfConfigGetValueObject(NULL, "/routers/router");
 
-                       transport_message* msg = message_init("registering", NULL, NULL, jid, NULL );
-                       message_set_router_info( msg, NULL, NULL, appname, "register", 0 );
+    int i;
+    for(i = 0; i < routerInfo->size; i++) {
+        jsonObject* routerChunk = jsonObjectGetIndex(routerInfo, i);
 
-                       client_send_message( client, msg );
-                       message_free( msg );
-                       free(jid);
-               }
-       }
+        if(routerChunk->type == JSON_STRING) {
+            /* this accomodates simple router configs */
+            char* routerName = osrfConfigGetValue( NULL, "/router_name" );
+            char* domain = osrfConfigGetValue(NULL, "/routers/router");
+            osrfLogDebug(OSRF_LOG_MARK, "found simple router settings with router name %s", routerName);
+            osrf_prefork_send_router_registration(appname, routerName, domain);
 
-       free(routerName);
-       osrfStringArrayFree(arr);
+        } else {
+            osrf_prefork_parse_router_chunk(appname, routerChunk);
+        }
+    }
 }
 
 static int prefork_child_init_hook(prefork_child* child) {
index cd8cac6..d6afa9a 100644 (file)
@@ -102,8 +102,10 @@ osrfAppSession* osrf_stack_transport_handler( transport_message* msg,
                                arr[i]->status_code = OSRF_STATUS_REDIRECTED;
 
                        } else {
-                               osrfLogWarning( OSRF_LOG_MARK, " * Jabber Error is for top level remote id [%s], no one "
-                                               "to send my message to!!!", session->remote_id );
+                               osrfLogWarning( OSRF_LOG_MARK, " * Jabber Error is for top level remote "
+                    " id [%s], no one to send my message to!  Cutting request short...", session->remote_id );
+                session->transport_error = 1;
+                break;
                        }
                }
 
index 29d5aa6..6437976 100644 (file)
@@ -317,7 +317,7 @@ int osrfSystemBootstrapClientResc( char* config_file, char* contextnode, char* r
 
        char* log_level         = osrfConfigGetValue( NULL, "/loglevel" );
        osrfStringArray* arr    = osrfNewStringArray(8);
-       osrfConfigGetValueList(NULL, arr, "/domains/domain");
+       osrfConfigGetValueList(NULL, arr, "/domain");
 
        char* username          = osrfConfigGetValue( NULL, "/username" );
        char* password          = osrfConfigGetValue( NULL, "/passwd" );
index c9cf0e6..54d465c 100644 (file)
@@ -179,19 +179,15 @@ sub get_app_targets {
 
        my $conf = OpenSRF::Utils::Config->current;
        my $router_name = $conf->bootstrap->router_name || 'router';
-       my $routers = $conf->bootstrap->domains;
+       my $domain = $conf->bootstrap->domain;
+       $logger->error("use of <domains/> is deprecated") if $conf->bootstrap->domains;
 
-       unless($router_name and $routers) {
+       unless($router_name and $domain) {
                throw OpenSRF::EX::Config 
-                       ("Missing router config information 'router_name' and 'routers'");
+                       ("Missing router config information 'router_name' and 'domain'");
        }
 
-       my @targets;
-       for my $router (@$routers) {
-               push @targets, "$router_name\@$router/$app";
-       }
-
-       return @targets;
+    return ("$router_name\@$domain/$app");
 }
 
 sub stateless {
index 32b7e7e..90436fe 100644 (file)
@@ -34,12 +34,13 @@ This service should be loaded at system startup.
                if( ! $instance ) {
 
                        my $conf = OpenSRF::Utils::Config->current;
-                       my $domains = $conf->bootstrap->domains;
+                       my $domain = $conf->bootstrap->domain;
+            $logger->error("use of <domains/> is deprecated") if $conf->bootstrap->domains;
 
                        my $username    = $conf->bootstrap->username;
                        my $password    = $conf->bootstrap->passwd;
                        my $port                        = $conf->bootstrap->port;
-                       my $host                        = $domains->[0]; # XXX for now...
+                       my $host                        = $domain;
                        my $resource    = $app . '_listener_at_' . $conf->env->hostname;
 
                        my $router_name = $conf->bootstrap->router_name;
@@ -75,21 +76,9 @@ This service should be loaded at system startup.
 
 sub DESTROY {
        my $self = shift;
-
-       my $routers = $self->{routers}; #store for destroy
-       my $router_name = $self->{router_name};
-
-       unless($router_name and $routers) {
-               return;
-       }
-
-       my @targets;
-       for my $router (@$routers) {
-               push @targets, "$router_name\@$router/router";
-       }
-
-       for my $router (@targets) {
+       for my $router (@{$self->{routers}}) {
                if($self->tcp_connected()) {
+            $logger->info("disconnecting from router $router");
                        $self->send( to => $router, body => "registering", 
                                router_command => "unregister" , router_class => $self->{app} );
                }
@@ -99,38 +88,35 @@ sub DESTROY {
 sub listen {
        my $self = shift;
        
-       my $routers;
+    $self->{routers} = [];
 
        try {
 
                my $conf = OpenSRF::Utils::Config->current;
-               my $router_name = $conf->bootstrap->router_name;
-               my $routers = $conf->bootstrap->domains;
-
-               $self->{routers} = $routers; #store for destroy
-               $self->{router_name} = $router_name;
-       
-               if($router_name and $routers) {
-       
-                       my @targets;
-                       for my $router (@$routers) {
-                               push @targets, "$router_name\@$router/router";
-                       }
-       
-                       for my $router (@targets) {
-                               $logger->transport( $self->{app} . " connecting to router $router", INFO ); 
-                               $self->send( to => $router, 
-                                               body => "registering", router_command => "register" , router_class => $self->{app} );
-                       }
-                       $logger->transport( $self->{app} . " :routers connected", INFO ); 
-
-               } else {
-
-                       $logger->transport("Bypassing routers...", INFO);
-               }
-
+        my $router_name = $conf->bootstrap->router_name;
+               my $routers = $conf->bootstrap->routers;
+        $logger->info("loading router info $routers");
+
+        for my $router (@$routers) {
+
+            if(ref $router) {
+                if( !$router->{services} || grep { $_ eq $self->{app} } @{$router->{services}->{service}} ) {
+                    my $name = $router->{name};
+                    my $domain = $router->{domain};
+                    my $target = "$name\@$domain/router";
+                    push(@{$self->{routers}}, $target);
+                    $logger->info( $self->{app} . " connecting to router $target");
+                    $self->send( to => $target, body => "registering", router_command => "register" , router_class => $self->{app} );
+                }
+            } else {
+                my $target = "$router_name\@$router/router";
+                push(@{$self->{routers}}, $target);
+                $logger->info( $self->{app} . " connecting to router $target");
+                $self->send( to => $target, body => "registering", router_command => "register" , router_class => $self->{app} );
+            }
+        }
                
-       } catch OpenSRF::EX::Config with {
+       } catch Error with {
                $logger->transport( $self->{app} . ": No routers defined" , WARN ); 
                # no routers defined
        };
index 1273ddc..5c5b959 100644 (file)
@@ -51,14 +51,15 @@ sub new {
        }
 
        my $conf                        = OpenSRF::Utils::Config->current;
-       my $domains = $conf->bootstrap->domains;
+       my $domain = $conf->bootstrap->domain;
        my $h = $conf->env->hostname;
+       OpenSRF::Utils::Logger->error("use of <domains/> is deprecated") if $conf->bootstrap->domains;
 
        my $username    = $conf->bootstrap->username;
        my $password    = $conf->bootstrap->passwd;
        my $port        = $conf->bootstrap->port;
        my $resource    = "${app}_drone_at_$h";
-       my $host        = $domains->[0]; # XXX for now...
+       my $host        = $domain; # XXX for now...
 
        if( $app eq "client" ) { $resource = "client_at_$h"; }
 
index 9b21221..6dfd5e4 100755 (executable)
@@ -343,7 +343,8 @@ sub load_config {
 
                        # If the child node is an element, this element may
                        # have multiple values; therefore, push it into an array
-                       push @{$bootstrap{$node->nodeName()}}, OpenSRF::Utils::Config::extract_text($child_node->textContent);
+            my $content = OpenSRF::Utils::Config::extract_child($child_node);
+                       push(@{$bootstrap{$node->nodeName()}}, $content) if $content;
                        $child_state = 1;
                }
                if (!$child_state) {
@@ -357,6 +358,11 @@ sub load_config {
        $self->$sub_name($section);
 
 }
+sub extract_child {
+    my $node = shift;
+    use OpenSRF::Utils::SettingsParser;
+    return OpenSRF::Utils::SettingsParser::XML2perl($node);
+}
 
 sub extract_text {
        my $self = shift;
index 6bb278d..e932a21 100644 (file)
@@ -71,7 +71,7 @@ def child_init(req):
     osrf.system.System.connect(config_file=conf, config_context=ctxt)
 
     ROUTER_NAME = osrf.conf.get('router_name')
-    OSRF_DOMAIN = osrf.conf.get('domains.domain')
+    OSRF_DOMAIN = osrf.conf.get('domain')
     INIT_COMPLETE = True
 
     servers = osrf.set.get('cache.global.servers.server')
index ddd9009..011b143 100644 (file)
@@ -89,7 +89,7 @@ class ClientSession(Session):
         self.locale = locale
 
         # find the remote service handle <router>@<domain>/<service>
-        domain = osrf.conf.get('domains.domain', 0)
+        domain = osrf.conf.get('domain', 0)
         router = osrf.conf.get('router_name')
         self.remote_id = "%s@%s/%s" % (router, domain, service)
         self.orig_remote_id = self.remote_id
index 1c217cc..6bba0bb 100644 (file)
@@ -66,36 +66,36 @@ def handle_message(session, message):
             osrf.log.log_internal("handle_message(): processing STATUS, "
                 "status_code =  %d" % status_code)
 
-        if status_code == OSRF_STATUS_COMPLETE:
-            # The server has informed us that this request is complete
-            req = session.find_request(message.threadTrace())
-            if req: 
-                osrf.log.log_internal("marking request as complete: %d" % req.rid)
-                req.set_complete()
-            return
-
-        if status_code == OSRF_STATUS_OK:
-            # We have connected successfully
-            osrf.log.log_debug("Successfully connected to " + session.service)
-            session.state = OSRF_APP_SESSION_CONNECTED
-            return
-
-        if status_code == OSRF_STATUS_CONTINUE:
-            # server is telling us to reset our wait timeout and keep waiting for a response
-            session.reset_request_timeout(message.threadTrace())
-            return
-
-        if status_code == OSRF_STATUS_TIMEOUT:
-            osrf.log.log_debug("The server did not receive a request from us in time...")
-            session.state = OSRF_APP_SESSION_DISCONNECTED
-            return
-
-        if status_code == OSRF_STATUS_NOTFOUND:
-            osrf.log.log_error("Requested method was not found on the server: %s" % status_text)
-            session.state = OSRF_APP_SESSION_DISCONNECTED
-            raise osrf.ex.OSRFServiceException(status_text)
-
-        raise osrf.ex.OSRFProtocolException("Unknown message status: %d" % status_code)
+            if status_code == OSRF_STATUS_COMPLETE:
+                # The server has informed us that this request is complete
+                req = session.find_request(message.threadTrace())
+                if req: 
+                    osrf.log.log_internal("marking request as complete: %d" % req.rid)
+                    req.set_complete()
+                return
+
+            if status_code == OSRF_STATUS_OK:
+                # We have connected successfully
+                osrf.log.log_debug("Successfully connected to " + session.service)
+                session.state = OSRF_APP_SESSION_CONNECTED
+                return
+
+            if status_code == OSRF_STATUS_CONTINUE:
+                # server is telling us to reset our wait timeout and keep waiting for a response
+                session.reset_request_timeout(message.threadTrace())
+                return
+
+            if status_code == OSRF_STATUS_TIMEOUT:
+                osrf.log.log_debug("The server did not receive a request from us in time...")
+                session.state = OSRF_APP_SESSION_DISCONNECTED
+                return
+
+            if status_code == OSRF_STATUS_NOTFOUND:
+                osrf.log.log_error("Requested method was not found on the server: %s" % status_text)
+                session.state = OSRF_APP_SESSION_DISCONNECTED
+                raise osrf.ex.OSRFServiceException(status_text)
+
+            raise osrf.ex.OSRFProtocolException("Unknown message status: %d" % status_code)
 
 
 
index 9986d0d..331b76d 100644 (file)
@@ -48,7 +48,7 @@ class System(object):
 
         # connect to the opensrf network
         network = Network(
-            host = osrf.conf.get('domains.domain'),
+            host = osrf.conf.get('domain'),
             port = osrf.conf.get('port'),
             username = osrf.conf.get('username'), 
             password = osrf.conf.get('passwd'),
@@ -74,7 +74,7 @@ class System(object):
         network = System.net_connect(**kwargs)
 
         # load the domain-wide settings file
-        osrf.set.load(osrf.conf.get('domains.domain'))
+        osrf.set.load(osrf.conf.get('domain'))
 
         if kwargs.get('connect_cache'):
             System.connect_cache()
index 706d214..2dec185 100644 (file)
@@ -1,7 +1,8 @@
 #include "osrf_router.h"
-#include "opensrf/osrfConfig.h"
-#include "opensrf/utils.h"
-#include "opensrf/log.h"
+#include <opensrf/osrfConfig.h>
+#include <opensrf/utils.h>
+#include <opensrf/log.h>
+#include <opensrf/osrf_json.h>
 #include <signal.h>
 
 static osrfRouter* router = NULL;
@@ -19,7 +20,7 @@ void routerSignalHandler( int signo ) {
        raise( signo );
 }
 
-static int setupRouter( char* config, char* context );
+static int setupRouter(jsonObject* configChunk);
 
 
 int main( int argc, char* argv[] ) {
@@ -34,27 +35,36 @@ int main( int argc, char* argv[] ) {
        init_proc_title( argc, argv );
        set_proc_title( "OpenSRF Router" );
 
-       int rc = setupRouter( config, context );
+       osrfConfig* cfg = osrfConfigInit(config, context);
+       osrfConfigSetDefaultConfig(cfg);
+    jsonObject* configInfo = osrfConfigGetValueObject(NULL, "/router");
+
+    int i;
+    for(i = 0; i < configInfo->size; i++) {
+        jsonObject* configChunk = jsonObjectGetIndex(configInfo, i);
+        if(fork() == 0) /* create a new child to run this router instance */
+            setupRouter(configChunk);
+    }
+
        free(config);
        free(context);
-       return rc ? EXIT_FAILURE : EXIT_SUCCESS;
+    return EXIT_SUCCESS;
 }
 
-int setupRouter( char* config, char* context ) {
+int setupRouter(jsonObject* configChunk) {
 
-       osrfConfig* cfg = osrfConfigInit( config, context );
-       osrfConfigSetDefaultConfig(cfg);
+    if(!jsonObjectGetKey(configChunk, "transport"))
+        return 0; /* these are not the configs you're looking for */
 
-       char* server                    = osrfConfigGetValue(NULL, "/transport/server");
-       char* port                              = osrfConfigGetValue(NULL, "/transport/port");
-       char* username                  = osrfConfigGetValue(NULL, "/transport/username");
-       char* password                  = osrfConfigGetValue(NULL, "/transport/password");
-       char* resource                  = osrfConfigGetValue(NULL, "/transport/resource");
+       char* server = jsonObjectGetString(jsonObjectFindPath(configChunk, "/transport/server"));
+       char* port = jsonObjectGetString(jsonObjectFindPath(configChunk, "/transport/port"));
+       char* username = jsonObjectGetString(jsonObjectFindPath(configChunk, "/transport/username"));
+       char* password = jsonObjectGetString(jsonObjectFindPath(configChunk, "/transport/password"));
+       char* resource = jsonObjectGetString(jsonObjectFindPath(configChunk, "/transport/resource"));
 
-       /* set up the logger */
-       char* level = osrfConfigGetValue(NULL, "/loglevel");
-       char* log_file = osrfConfigGetValue(NULL, "/logfile");
-       char* facility = osrfConfigGetValue(NULL, "/syslog");
+       char* level = jsonObjectGetString(jsonObjectFindPath(configChunk, "/loglevel"));
+       char* log_file = jsonObjectGetString(jsonObjectFindPath(configChunk, "/logfile"));
+       char* facility = jsonObjectGetString(jsonObjectFindPath(configChunk, "/syslog"));
 
        int llevel = 1;
        if(level) llevel = atoi(level);
@@ -82,15 +92,36 @@ int setupRouter( char* config, char* context ) {
 
        osrfStringArray* tclients = osrfNewStringArray(4);
        osrfStringArray* tservers = osrfNewStringArray(4);
-       osrfConfigGetValueList(NULL, tservers, "/trusted_domains/server" );
-       osrfConfigGetValueList(NULL, tclients, "/trusted_domains/client" );
+
+    jsonObject* tclientsList = jsonObjectFindPath(configChunk, "/trusted_domains/client");
+    jsonObject* tserversList = jsonObjectFindPath(configChunk, "/trusted_domains/server");
 
        int i;
-       for( i = 0; i != tservers->size; i++ ) 
-               osrfLogInfo( OSRF_LOG_MARK,  "Router adding trusted server: %s", osrfStringArrayGetString( tservers, i ) );
 
-       for( i = 0; i != tclients->size; i++ ) 
-               osrfLogInfo( OSRF_LOG_MARK,  "Router adding trusted client: %s", osrfStringArrayGetString( tclients, i ) );
+    if(tserversList->type == JSON_ARRAY) {
+           for( i = 0; i != tserversList->size; i++ ) {
+            char* serverDomain = jsonObjectGetString(jsonObjectGetIndex(tserversList, i));
+                   osrfLogInfo( OSRF_LOG_MARK,  "Router adding trusted server: %s", serverDomain);
+            osrfStringArrayAdd(tservers, serverDomain);
+        }
+    } else {
+        char* serverDomain = jsonObjectGetString(tserversList);
+        osrfLogInfo( OSRF_LOG_MARK,  "Router adding trusted server: %s", serverDomain);
+        osrfStringArrayAdd(tservers, serverDomain);
+    }
+
+    if(tclientsList->type == JSON_ARRAY) {
+           for( i = 0; i != tclientsList->size; i++ ) {
+            char* clientDomain = jsonObjectGetString(jsonObjectGetIndex(tclientsList, i));
+                   osrfLogInfo( OSRF_LOG_MARK,  "Router adding trusted client: %s", clientDomain);
+            osrfStringArrayAdd(tclients, clientDomain);
+        }
+    } else {
+        char* clientDomain = jsonObjectGetString(tclientsList);
+        osrfLogInfo( OSRF_LOG_MARK,  "Router adding trusted client: %s", clientDomain);
+        osrfStringArrayAdd(tclients, clientDomain);
+    }
+
 
        if( tclients->size == 0 || tservers->size == 0 ) {
                osrfLogError( OSRF_LOG_MARK, "We need trusted servers and trusted client to run the router...");
@@ -107,15 +138,11 @@ int setupRouter( char* config, char* context ) {
        signal(SIGTERM,routerSignalHandler);
 
        if( (osrfRouterConnect(router)) != 0 ) {
-               fprintf(stderr, "!!!! Unable to connect router to jabber server %s... exiting", server );
+               fprintf(stderr, "Unable to connect router to jabber server %s... exiting", server );
                osrfRouterFree(router);
                return -1;
        }
 
-       free(server); free(port); 
-       free(username); free(password);
-       free(resource);
-
        daemonize();
        osrfRouterRun( router );
 
index ddf242e..0458af3 100644 (file)
@@ -572,6 +572,7 @@ int send_request( char* server,
        osrfAppSession* session = osrfAppSessionClientInit(server);
 
        if(!osrf_app_session_connect(session)) {
+               fprintf(stderr, "Unable to communicate with service %s\n", server);
                osrfLogWarning( OSRF_LOG_MARK,  "Unable to connect to remote service %s\n", server );
                jsonObjectFree(params);
                return 1;