Young C server code added
authorerickson <erickson@9efc2488-bf62-4759-914b-345cdb29e865>
Fri, 2 Sep 2005 19:38:35 +0000 (19:38 +0000)
committererickson <erickson@9efc2488-bf62-4759-914b-345cdb29e865>
Fri, 2 Sep 2005 19:38:35 +0000 (19:38 +0000)
git-svn-id: svn://svn.open-ils.org/OpenSRF/trunk@518 9efc2488-bf62-4759-914b-345cdb29e865

17 files changed:
bin/opensrf_all
src/Makefile
src/libstack/Makefile
src/libstack/opensrf.c [new file with mode: 0644]
src/libstack/osrf_app_session.c
src/libstack/osrf_app_session.h
src/libstack/osrf_application.c [new file with mode: 0644]
src/libstack/osrf_application.h [new file with mode: 0644]
src/libstack/osrf_prefork.c
src/libstack/osrf_prefork.h
src/libstack/osrf_settings.c
src/libstack/osrf_stack.c
src/libstack/osrf_system.c
src/libstack/osrf_system.h
src/libtransport/transport_message.c
src/perlmods/OpenSRF/System.pm
src/utils/socket_bundle.c

index 9014411..f84a747 100755 (executable)
@@ -122,12 +122,12 @@ function stopMe {
 
        echo "Stopping OpenSRF...";
        "$BINDIR/opensrf_ctl" stop;
-       sleep 2;
+       sleep 1;
        
        echo "Stopping The Router...";
        killall router;
        
-       sleep 2;
+       sleep 1;
        
        echo "Stopping Chop Chop...";
        killall jserver-c;
index 5458e25..6ff8ea7 100644 (file)
@@ -25,6 +25,7 @@ OPENSRF_TARGETS = libtransport/transport_session.o \
                                                libstack/osrf_message.o \
                                                libstack/osrf_prefork.o \
                                                libstack/osrf_system.o \
+                                               libstack/osrf_application.o \
                                                libstack/xml_utils.o \
                                                utils/socket_bundle.o \
                                                utils/string_array.o \
@@ -43,6 +44,7 @@ OPENSRF_HEADERS = libtransport/transport_session.h \
                                                libstack/osrf_message.h \
                                                libstack/osrf_prefork.h \
                                                libstack/osrf_system.h \
+                                               libstack/osrf_application.h \
                                                libstack/xml_utils.h \
                                                utils/socket_bundle.h \
                                                utils/string_array.h \
@@ -52,7 +54,7 @@ OPENSRF_HEADERS = libtransport/transport_session.h \
                                                utils/sha.h \
 
 
-all: prep libopensrf.so router srfsh jserver gateway
+all: prep libopensrf.so libstack/opensrf router srfsh jserver gateway
 
 install: install-prep opensrf-install gateway-install  router-install \
                srfsh-install jserver-install perl-install objson-install
@@ -69,12 +71,15 @@ libopensrf.so:      objson/libobjson.so
        make -C libstack
        @echo $@
        $(CC) -shared -W1 $(LDFLAGS) -lobjson $(OPENSRF_TARGETS) -o $(TMPDIR)/$(LIBOPENSRF)
+       @echo apps
+       make -C  c-apps
 
 
 opensrf-install:
        @echo $@
        cp $(TMPDIR)/$(LIBOPENSRF) $(LIBDIR)/$(LIBOPENSRF)
        cp $(OPENSRF_HEADERS) $(INCLUDEDIR)/opensrf/
+       make -C c-apps install
 
 
 objson/libobjson.so: 
@@ -84,6 +89,11 @@ objson/libobjson.so:
 # --------------------------------------------------------------------------------
 # BINARIES
 # --------------------------------------------------------------------------------
+libstack/opensrf.o:    libstack/opensrf.c
+libstack/opensrf:      libstack/opensrf.o
+       $(CC) $(CFLAGS) $(LDFLAGS) -lxml2 -lopensrf -lobjson libstack/opensrf.o -o $@
+       
+
 router: libopensrf.so
        @echo $@
        make -C router 
@@ -162,7 +172,8 @@ clean:
        make -C utils clean
        make -C objson clean
        make -C srfsh clean
+       make -C c-apps clean
        echo "Removing directory [$(TMPDIR)]"
-       /bin/rm -rf $(TMPDIR)
+       /bin/rm -rf $(TMPDIR) *.o
 
 
index 0579807..f8887e5 100644 (file)
@@ -1,11 +1,28 @@
 
-CFLAGS +=  -DASSUME_STATELESS 
-LDLIBS += -lxml2 -lobjson 
+CFLAGS +=  -DASSUME_STATELESS -rdynamic -fno-strict-aliasing
+LDLIBS += -lxml2 -lobjson -ldl
 
-TARGETS = osrf_message.o osrf_app_session.o osrf_stack.o osrf_system.o osrf_settings.o osrf_prefork.o osrfConfig.o xml_utils.o
-HEADERS = osrf_message.h osrf_app_session.h osrf_stack.h osrf_system.h osrf_settings.h osrf_prefork.h osrfConfig.h xml_utils.h
+TARGETS = osrf_message.o \
+                        osrf_app_session.o \
+                        osrf_stack.o \
+                        osrf_system.o \
+                        osrf_settings.o \
+                        osrf_prefork.o \
+                        osrfConfig.o \
+                        osrf_application.o \
+                        xml_utils.o
 
-all: xml_utils.o $(TARGETS) copy
+HEADERS = osrf_message.h \
+                        osrf_app_session.h \
+                        osrf_stack.h \
+                        osrf_system.h \
+                        osrf_settings.h \
+                        osrf_prefork.h \
+                        osrfConfig.h \
+                        osrf_application.h \
+                        xml_utils.h
+
+all: xml_utils.o $(TARGETS) copy 
 
 xml_utils.o:
        cp ../utils/xml_utils.h .
@@ -22,6 +39,7 @@ osrf_system.o:        osrf_system.c osrf_system.h
 osrf_settings.o:       osrf_settings.c osrf_settings.h
 osrf_prefork.o:        osrf_prefork.c osrf_prefork.h
 osrfConfig.o:  osrfConfig.c osrfConfig.h xml_utils.o
+osrf_application.o: osrf_application.c osrf_application.h
 
 clean:
-       /bin/rm -f *.o libopensrf_stack.so test xml_utils.h xml_utils.c
+       /bin/rm -f *.o libopensrf_stack.so xml_utils.h xml_utils.c
diff --git a/src/libstack/opensrf.c b/src/libstack/opensrf.c
new file mode 100644 (file)
index 0000000..6e77ace
--- /dev/null
@@ -0,0 +1,18 @@
+#include "osrf_system.h"
+
+int main( int argc, char* argv[] ) {
+
+       if( argc < 4 ) {
+               fprintf(stderr, "Host, Bootstrap, and context required\n");
+               return 1;
+       }
+
+       fprintf(stderr, "Loading OpenSRF host %s with bootstrap config %s "
+                       "and config context %s\n", argv[1], argv[2], argv[3] );
+
+       osrfSystemBootstrap( argv[1], argv[2], argv[3] );
+
+       return 0;
+}
+
+
index 6080561..60b767f 100644 (file)
@@ -293,10 +293,11 @@ osrf_app_session* osrf_app_client_session_init( char* remote_service ) {
 osrf_app_session* osrf_app_server_session_init( 
                char* session_id, char* our_app, char* remote_id ) {
 
-       osrf_app_session* session = osrf_app_session_find_session( session_id );
-       if(session)
-               return session;
+       info_handler("Initing server session with session id %s, service %s,"
+                       " and remote_id %s", session_id, our_app, remote_id );
 
+       osrf_app_session* session = osrf_app_session_find_session( session_id );
+       if(session) return session;
 
        session = safe_malloc(sizeof(osrf_app_session));        
 
@@ -305,6 +306,7 @@ osrf_app_session* osrf_app_server_session_init(
                warning_handler("No transport client for service '%s'", our_app );
                return NULL;
        }
+
        session->request_queue = NULL;
        session->remote_id = strdup(remote_id);
        session->orig_remote_id = strdup(remote_id);
@@ -317,12 +319,9 @@ osrf_app_session* osrf_app_server_session_init(
        session->stateless = 0;
        #endif
 
-       debug_handler( "Building a new server session [%s] with id [%s]", 
-                       session->remote_service,  session_id );
-
        session->thread_trace = 0;
        session->state = OSRF_SESSION_DISCONNECTED;
-       session->type = OSRF_SESSION_CLIENT;
+       session->type = OSRF_SESSION_SERVER;
        session->next = NULL;
 
        _osrf_app_session_push_session( session );
@@ -683,3 +682,38 @@ osrf_message* osrf_app_session_request_recv(
        return _osrf_app_request_recv( req, timeout );
 }
 
+
+
+int osrfAppRequestRespond( osrfAppSession* ses, int requestId, jsonObject* data ) {
+       if(!ses || ! data ) return -1;
+
+       osrf_message* msg = osrf_message_init( RESULT, requestId, 1 );
+       char* json = jsonObjectToJSON( data );
+       osrf_message_set_result_content( msg, json );
+       _osrf_app_session_send( ses, msg ); 
+
+       free(json);
+       osrf_message_free( msg );
+
+       return 0;
+}
+
+
+
+int osrfAppSessionStatus( osrfAppSession* ses, int type, int reqId, char* message ) {
+
+       if(ses) {
+               osrf_message* msg = osrf_message_init( STATUS, reqId, 1);
+               osrf_message_set_status_info( msg, "Server Error", message, type );
+               _osrf_app_session_send( ses, msg ); 
+               osrf_message_free( msg );
+               return 0;
+       }
+       return -1;
+}
+
+
+
+
+
+
index 50d283a..3b57880 100644 (file)
@@ -2,6 +2,7 @@
 #define _OSRF_APP_SESSION
 
 #include "opensrf/transport_client.h"
+#include "objson/object.h"
 #include "osrf_message.h"
 #include "osrf_system.h"
 #include "opensrf/string_array.h"
@@ -42,6 +43,7 @@ struct osrf_app_request_struct {
        struct osrf_app_request_struct* next;
 };
 typedef struct osrf_app_request_struct osrf_app_request;
+typedef struct osrf_app_request_struct osrfAppRequest;
 
 struct osrf_app_session_struct {
 
@@ -78,6 +80,7 @@ struct osrf_app_session_struct {
 
 };
 typedef struct osrf_app_session_struct osrf_app_session;
+typedef struct osrf_app_session_struct osrfAppSession;
 
 
 
@@ -209,4 +212,9 @@ void _osrf_app_session_remove_request( osrf_app_session*, osrf_app_request* req
 /** Send the given message */
 int _osrf_app_session_send( osrf_app_session*, osrf_message* msg );
 
+int osrfAppRequestRespond( osrfAppSession* ses, int requestId, jsonObject* data ); 
+
+int osrfAppSessionStatus( osrfAppSession* ses, int type, int reqId, char* message );
+
+
 #endif
diff --git a/src/libstack/osrf_application.c b/src/libstack/osrf_application.c
new file mode 100644 (file)
index 0000000..8ede790
--- /dev/null
@@ -0,0 +1,153 @@
+
+#include "osrf_application.h"
+
+osrfApplication* __osrfAppList = NULL; 
+
+
+int osrfAppRegisterApplication( char* appName, char* soFile ) {
+       if(!appName || ! soFile) return -1;
+       char* error;
+
+       info_handler("Registering application %s with file %s", appName, soFile );
+
+       osrfApplication* app = safe_malloc(sizeof(osrfApplication));
+       app->handle = dlopen (soFile, RTLD_NOW);
+
+       if(!app->handle) {
+               warning_handler("Failed to dlopen library file %s: %s", soFile, dlerror() );
+               dlerror(); /* clear the error */
+               free(app);
+               return -1;
+       }
+
+       app->name = strdup(appName);
+
+       /* this has to be done before initting the application */
+       app->next = __osrfAppList;
+       __osrfAppList = app;
+
+
+       /* see if we can run the initialize method */
+       int (*init) (void);
+       *(void **) (&init) = dlsym(app->handle, "initialize");
+
+       if( (error = dlerror()) != NULL ) {
+               warning_handler("! Unable to locate method symbol [initialize] for app %s: %s", appName, error );
+
+       } else {
+
+               /* run the method */
+               int ret;
+               if( (ret = (*init)()) ) {
+                       warning_handler("Application %s returned non-zero value from "
+                                       "'initialize', not registering...", appName );
+                       //free(app->name); /* need a method to remove an application from the list */
+                       //free(app);
+                       return ret;
+               }
+       }
+
+
+       info_handler("Application %s registered successfully", appName );
+
+
+       return 0;
+}
+
+
+int osrfAppRegisterMethod( char* appName, 
+               char* methodName, char* symbolName, char* notes, int argc ) {
+       if( !appName || ! methodName || ! symbolName ) return -1;
+
+       osrfApplication* app = _osrfAppFindApplication(appName);
+       if(!app) return warning_handler("Unable to locate application %s", appName );
+
+       debug_handler("Registering method %s for app %s", appName, methodName );
+
+       osrfMethod* method = safe_malloc(sizeof(osrfMethod));
+       method->name = strdup(methodName);
+       method->symbol = strdup(symbolName);
+       if(notes) method->notes = strdup(notes);
+       method->argc = argc;
+
+       /* plug the method into the list of methods */
+       method->next = app->methods;
+       app->methods = method;
+       return 0;
+}
+
+osrfApplication* _osrfAppFindApplication( char* name ) {
+       if(!name) return NULL;
+       osrfApplication* app = __osrfAppList;
+       while(app) {
+               if(!strcmp(app->name, name))
+                       return app;
+               app = app->next;
+       }
+       return NULL;
+}
+
+osrfMethod* __osrfAppFindMethod( osrfApplication* app, char* methodName ) {
+       if(!app || ! methodName) return NULL;
+       osrfMethod* method = app->methods;
+       while(method) {
+               if(!strcmp(method->name, methodName))
+                       return method;
+               method = method->next;
+       }
+       return NULL;
+}
+
+osrfMethod* _osrfAppFindMethod( char* appName, char* methodName ) {
+       if(!appName || ! methodName) return NULL;
+       return __osrfAppFindMethod( _osrfAppFindApplication(appName), methodName );
+}
+
+
+
+
+int osrfAppRunMethod( char* appName, char* methodName, osrfAppSession* ses, int reqId, jsonObject* params ) {
+       if(!appName || ! methodName || ! ses) return -1;
+       char* error;
+
+       info_handler("Running method [%s] for app [%s] with request id %d and "
+                       "thread trace %s", methodName, appName, reqId, ses->session_id );
+
+       osrfApplication* app = _osrfAppFindApplication(appName);
+       if(!app) return warning_handler( "Application not found: %s", appName );
+
+       osrfMethod* method = __osrfAppFindMethod( app, methodName );
+       if(!method) return warning_handler( "NOT FOUND: app %s / method %s", appName, methodName );
+
+       /* this is the method we're gonna run */
+       int (*meth) (osrfMethodDispatcher*);    
+
+       /* open the method */
+       *(void **) (&meth) = dlsym(app->handle, method->symbol);
+
+       if( (error = dlerror()) != NULL ) {
+               return warning_handler("Unable to locate method symbol [%s] "
+                               "for method %s and app %s", method->symbol, method->name, app->name );
+       }
+
+       osrfMethodDispatcher d;
+       d.session = ses;
+       d.method = method;
+       d.params = params;
+       d.request = reqId;
+
+       /* run the method */
+       int ret = (*meth) (&d);
+
+       debug_handler("method returned %d", ret );
+
+
+       if(ret == -1) {
+               /* return an internal server error ? */
+       }
+
+       return 0;
+}
+
+
+
diff --git a/src/libstack/osrf_application.h b/src/libstack/osrf_application.h
new file mode 100644 (file)
index 0000000..1724f80
--- /dev/null
@@ -0,0 +1,128 @@
+
+#include <stdio.h>
+#include <dlfcn.h>
+#include "opensrf/utils.h"
+#include "opensrf/logging.h"
+#include "objson/object.h"
+#include "osrf_app_session.h"
+
+#define OSRF_METHOD_CHECK_PARAMS(x,y) \
+       if( ! x  || ! y ) return -1; \
+       if(y->type != JSON_ARRAY ) return -1; \
+       char* __j = jsonObjectToJSON(y);\
+       if(__j) { \
+               debug_handler("Service: %s | Params: %s", x->remote_service, __j);free(__j);}
+
+
+/** 
+  This macro verifies methods receive the correct parameters 
+  It also creates local variables "session", "method",
+  "params", and "request" 
+  */
+
+#define OSRF_METHOD_VERIFY_DISPATCHER(__d) \
+       if(!__d) return -1; \
+       \
+       osrfAppSession* session = __d->session; \
+       osrfMethod*     method = __d->method; \
+       jsonObject* params = __d->params; \
+       int request = __d->request; \
+       \
+       if( !(session && method && params) ) return -1; \
+       if( !params->type == JSON_ARRAY ) return -1; \
+       if( !method->name ) return -1; \
+       \
+       char* __j = jsonObjectToJSON(params);\
+       if(__j) { \
+               debug_handler("Service: %s | Params: %s", session->remote_service, __j);free(__j);}
+
+       
+
+       
+
+struct _osrfApplicationStruct {
+       char* name; /* the name of our application */
+       void* handle; /* the lib handle */
+       struct _osrfMethodStruct* methods;      /* list of methods */
+       struct _osrfApplicationStruct* next; /* next application */
+};
+typedef struct _osrfApplicationStruct osrfApplication;
+
+
+struct _osrfMethodStruct {
+       char* name;                             /* the method name */
+       char* symbol;                   /* the symbol name (function) */
+       char* notes;                    /* public method documentation */
+       int argc;                               /* how many args this method expects */
+       void* methodHandle;     /* cached version of the method handle */
+       struct _osrfMethodStruct* next;
+}; 
+typedef struct _osrfMethodStruct osrfMethod;
+
+struct _osrfMethodDispatcherStruct {
+       osrfAppSession* session;
+       osrfMethod* method;
+       jsonObject* params;
+       int request;
+};
+typedef struct _osrfMethodDispatcherStruct osrfMethodDispatcher;
+
+
+/** 
+  Register an application
+  @param appName The name of the application
+  @param soFile The library (.so) file that implements this application
+  @return 0 on success, -1 on error
+  */
+int osrfAppRegisterApplication( char* appName, char* soFile );
+
+/**
+  Register a method
+  @param appName The name of the application that implements the method
+  @param methodName The fully qualified name of the method
+  @param symbolName The symbol name (function) that implements the method
+  @param notes Public documentation for this method.
+  @params argc The number of arguments this method expects 
+  @return 0 on success, -1 on error
+  */
+int osrfAppRegisterMethod( char* appName, 
+               char* methodName, char* symbolName, char* notes, int argc );
+
+/**
+  Finds the given app in the list of apps
+  @param name The name of the application
+  @return The application pointer or NULL if there is no such application
+  */
+osrfApplication* _osrfAppFindApplication( char* name );
+
+/**
+  Finds the given method for the given app
+  @param appName The application
+  @param methodName The method to find
+  @return A method pointer or NULL if no such method 
+  exists for the given application
+  */
+osrfMethod* _osrfAppFindMethod( char* appName, char* methodName );
+
+/**
+  Finds the given method for the given app
+  @param app The application object
+  @param methodName The method to find
+  @return A method pointer or NULL if no such method 
+  exists for the given application
+  */
+osrfMethod* __osrfAppFindMethod( osrfApplication* app, char* methodName );
+
+
+/**
+  Runs the specified method for the specified application.
+  @param appName The name of the application who's method to run
+  @param methodName The name of the method to run
+  @param ses The app session attached to this request
+  @params reqId The request id for this request
+  @param params The method parameters
+  */
+int osrfAppRunMethod( char* appName, char* methodName, 
+               osrfAppSession* ses, int reqId, jsonObject* params );
+
+
index 8e718be..f34f9a5 100644 (file)
@@ -43,7 +43,7 @@ int osrf_prefork_run(char* appname) {
        free(resc);
 
        prefork_simple* forker = prefork_simple_init(
-               osrf_system_get_transport_client(), maxr, minc, maxc);
+               osrfSystemGetTransportClient(), maxr, minc, maxc);
 
        forker->appname = strdup(appname);
 
@@ -51,6 +51,8 @@ int osrf_prefork_run(char* appname) {
                fatal_handler("osrf_prefork_run() failed to create prefork_simple object");
 
        prefork_launch_children(forker);
+
+       osrf_prefork_register_routers(appname);
        
        info_handler("Launching osrf_forker for app %s", appname);
        prefork_run(forker);
@@ -61,8 +63,34 @@ int osrf_prefork_run(char* appname) {
 
 }
 
-void osrf_prefork_register_routers() {
-       //char* router = osrf_config_value("//%s/
+void osrf_prefork_register_routers( char* appname ) {
+
+       osrfStringArray* arr = osrfNewStringArray(4);
+
+       int c = osrfConfigGetValueList( NULL, arr, "/routers/router" );
+       char* routerName = osrfConfigGetValue( NULL, "/router_name" );
+       transport_client* client = osrfSystemGetTransportClient();
+
+       info_handler("router name is %s and we have %d routers to connect to", routerName, c );
+
+       while( c ) {
+               char* domain = osrfStringArrayGetString(arr, --c);
+               if(domain) {
+
+                       char* jid = va_list_to_string( "%s@%s/router", routerName, domain );
+                       info_handler("Registering with router %s", 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);
+               }
+       }
+
+       free(routerName);
+       osrfStringArrayFree(arr);
 }
 
 void prefork_child_init_hook(prefork_child* child) {
@@ -228,10 +256,9 @@ void prefork_run(prefork_simple* forker) {
                }
 
                debug_handler("Forker going into wait for data...");
-               sleep(2);
                cur_msg = client_recv( forker->connection, -1 );
 
-               fprintf(stderr, "Got Data %f\n", get_timestamp_millis() );
+               //fprintf(stderr, "Got Data %f\n", get_timestamp_millis() );
 
                if( cur_msg == NULL ) continue;
                
@@ -260,14 +287,14 @@ void prefork_run(prefork_simple* forker) {
                                        debug_handler( "Writing to child fd %d", cur_child->write_data_fd );
 
                                        int written = 0;
-                                       fprintf(stderr, "Writing Data %f\n", get_timestamp_millis() );
+                                       //fprintf(stderr, "Writing Data %f\n", get_timestamp_millis() );
                                        if( (written = write( cur_child->write_data_fd, data, strlen(data) + 1 )) < 0 ) {
                                                warning_handler("Write returned error %d", errno);
                                                cur_child = cur_child->next;
                                                continue;
                                        }
 
-                                       fprintf(stderr, "Wrote %d bytes to child\n", written);
+                                       //fprintf(stderr, "Wrote %d bytes to child\n", written);
 
                                        forker->first_child = cur_child->next;
                                        honored = 1;
@@ -305,7 +332,7 @@ void prefork_run(prefork_simple* forker) {
                                reap_children(forker);
 
 
-                       fprintf(stderr, "Parent done with request %f\n", get_timestamp_millis() );
+                       //fprintf(stderr, "Parent done with request %f\n", get_timestamp_millis() );
 
                } // honored?
 
@@ -358,7 +385,7 @@ void check_children( prefork_simple* forker ) {
        for( j = 0; j!= forker->current_num_children && num_handled < select_ret ; j++ ) {
 
                if( FD_ISSET( cur_child->read_status_fd, &read_set ) ) {
-                       printf( "Server received status from a child %d\n", cur_child->pid );
+                       //printf( "Server received status from a child %d\n", cur_child->pid );
                        debug_handler( "Server received status from a child %d", cur_child->pid );
 
                        num_handled++;
@@ -394,16 +421,16 @@ void prefork_child_wait( prefork_child* child ) {
                        buffer_add( gbuf, buf );
                        memset( buf, 0, READ_BUFSIZE );
 
-                       fprintf(stderr, "Child read %d bytes\n", n);
+                       //fprintf(stderr, "Child read %d bytes\n", n);
 
                        if( n == READ_BUFSIZE ) { 
-                               fprintf(stderr, "We read READ_BUFSIZE data....\n");
+                               //fprintf(stderr, "We read READ_BUFSIZE data....\n");
                                /* XXX */
                                /* either we have exactly READ_BUFSIZE data, 
                                        or there's more waiting that we need to grab*/
                                /* must set to non-block for reading more */
                        } else {
-                               fprintf(stderr, "Read Data %f\n", get_timestamp_millis() );
+                               //fprintf(stderr, "Read Data %f\n", get_timestamp_millis() );
                                prefork_child_process_request(child, gbuf->buf);
                                buffer_reset( gbuf );
                                break;
index a2dfdb8..22d7742 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "opensrf/utils.h"
 #include "opensrf/transport_message.h"
+#include "opensrf/transport_client.h"
 #include "osrf_stack.h"
 #include "osrf_settings.h"
 #include "osrfConfig.h"
@@ -88,3 +89,6 @@ int prefork_free( prefork_simple* );
 int prefork_child_free( prefork_child* );
 
 
+void osrf_prefork_register_routers( char* appname );
+
+
index 286a1eb..2f2860d 100644 (file)
@@ -21,7 +21,8 @@ int osrf_settings_retrieve(char* hostname) {
        if(!config) {
 
                osrf_app_session* session = osrf_app_client_session_init("opensrf.settings");
-               jsonObject* params = jsonNewObject(hostname);
+               jsonObject* params = jsonNewObject(NULL);
+               jsonObjectPush(params, jsonNewObject(hostname));
                int req_id = osrf_app_session_make_req( 
                        session, params, "opensrf.settings.host_config.get", 1, NULL );
                osrf_message* omsg = osrf_app_session_request_recv( session, req_id, 60 );
index 3f73dbf..e6e1cb0 100644 (file)
@@ -1,4 +1,5 @@
 #include "osrf_stack.h"
+#include "osrf_application.h"
 
 osrf_message* _do_client( osrf_app_session*, osrf_message* );
 osrf_message* _do_server( osrf_app_session*, osrf_message* );
@@ -33,6 +34,8 @@ int osrf_stack_process( transport_client* client, int timeout ) {
 // -----------------------------------------------------------------------------
 int osrf_stack_transport_handler( transport_message* msg, char* my_service ) { 
 
+       if(!msg) return -1;
+
        debug_handler( "Transport handler received new message \nfrom %s "
                        "to %s with body \n\n%s\n", msg->sender, msg->recipient, msg->body );
 
@@ -43,14 +46,11 @@ int osrf_stack_transport_handler( transport_message* msg, char* my_service ) {
 
        osrf_app_session* session = osrf_app_session_find_session( msg->thread );
 
-       if( session == NULL ) {  /* we must be a server, build a new session */
-               info_handler( "Received message for nonexistant session. Dropping..." );
-               //osrf_app_server_session_init( msg->thread, my_service, msg->sender);
-               message_free( msg );
-               return 1;
-       }
+       if( session == NULL ) 
+               session = osrf_app_server_session_init( msg->thread, my_service, msg->sender);
 
-       //debug_handler("Session [%s] found, building message", msg->thread );
+       if(!msg->is_error)
+               debug_handler("Session [%s] found or built", session->session_id );
 
        osrf_app_session_set_remote( session, msg->sender );
        osrf_message* arr[OSRF_MAX_MSGS_PER_PACKET];
@@ -96,14 +96,17 @@ int osrf_stack_message_handler( osrf_app_session* session, osrf_message* msg ) {
                return 0;
 
        osrf_message* ret_msg = NULL;
+
        if( session->type ==  OSRF_SESSION_CLIENT )
                 ret_msg = _do_client( session, msg );
        else
                ret_msg= _do_server( session, msg );
 
-       if(ret_msg)
+       if(ret_msg) {
+               debug_handler("passing message %d / session %s to app handler", 
+                               msg->thread_trace, session->session_id );
                osrf_stack_application_handler( session, ret_msg );
-       else
+       else
                osrf_message_free(msg);
 
        return 1;
@@ -146,7 +149,8 @@ osrf_message* _do_client( osrf_app_session* session, osrf_message* msg ) {
                        case OSRF_STATUS_EXPFAILED: 
                                osrf_app_session_reset_remote( session );
                                session->state = OSRF_SESSION_DISCONNECTED;
-                               osrf_app_session_request_resend( session, msg->thread_trace );
+                               /* set the session to 'stateful' then resend */
+                       //      osrf_app_session_request_resend( session, msg->thread_trace );
                                return NULL;
 
                        case OSRF_STATUS_TIMEOUT:
@@ -183,30 +187,58 @@ osrf_message* _do_client( osrf_app_session* session, osrf_message* msg ) {
   * if we return NULL, we're finished for now...
   */
 osrf_message* _do_server( osrf_app_session* session, osrf_message* msg ) {
-       if(session == NULL || msg == NULL)
-               return NULL;
 
-       if( msg->m_type == STATUS ) { return NULL; }
+       if(session == NULL || msg == NULL) return NULL;
+
+       debug_handler("Server received message of type %d", msg->m_type );
+
+       switch( msg->m_type ) {
+
+               case STATUS:
+                               return NULL;
+
+               case DISCONNECT:
+                               osrf_app_session_destroy(session);      
+                               return NULL;
+
+               case CONNECT:
+                               /* handle connect message */
+                               return NULL;
 
-       warning_handler( "We dont' do servers yet !!" );
+               case REQUEST:
 
-       return msg;
+                               debug_handler("server passing message %d to application handler "
+                                               "for session %s", msg->thread_trace, session->session_id );
+                               return msg;
+
+               default:
+                       warning_handler("Server cannot handle message of type %d", msg->m_type );
+                       return NULL;
+
+       }
 }
 
 
 
 
 int osrf_stack_application_handler( osrf_app_session* session, osrf_message* msg ) {
-       if(session == NULL || msg == NULL)
-               return 0;
 
-       if(msg->m_type == RESULT) {
+       if(session == NULL || msg == NULL) return 0;
+
+       if(msg->m_type == RESULT && session->type == OSRF_SESSION_CLIENT) {
                osrf_app_session_push_queue( session, msg ); 
                return 1;
        }
 
-       warning_handler( "application_handler can't handle whatever you sent, type %d", msg->m_type);
+       if(msg->m_type != REQUEST) return 1;
 
+       char* method = msg->method_name;
+       char* app       = session->remote_service;
+       jsonObject* params = msg->_params;
+
+       osrfAppRunMethod( app, method,  session, msg->thread_trace, params );
+               
        return 1;
 
 }
+
index f8cf8dd..97b2e59 100644 (file)
@@ -1,7 +1,16 @@
 #include "osrf_system.h"
+#include <signal.h>
+#include "osrf_application.h"
+#include "osrf_prefork.h"
+
+void __osrfSystemSignalHandler( int sig );
 
 transport_client* __osrfGlobalTransportClient;
 
+transport_client* osrfSystemGetTransportClient() {
+       return __osrfGlobalTransportClient;
+}
+
 transport_client* osrf_system_get_transport_client() {
        return __osrfGlobalTransportClient;
 }
@@ -10,10 +19,79 @@ int osrf_system_bootstrap_client( char* config_file, char* contextnode ) {
        return osrf_system_bootstrap_client_resc(config_file, contextnode, NULL);
 }
 
+int osrfSystemBootstrapClientResc( char* config_file, char* contextnode, char* resource ) {
+       return osrf_system_bootstrap_client_resc( config_file, contextnode, resource );
+}
+
+
+int osrfSystemBootstrap( char* hostname, char* configfile, char* contextNode ) {
+       if( !(configfile && contextNode) ) return -1;
+
+       /* first we grab the settings */
+       if(!osrfSystemBootstrapClientResc(configfile, contextNode, "settings_grabber" )) {
+               return fatal_handler("Unable to bootstrap");
+       }
+
+       osrf_settings_retrieve(hostname);
+       osrf_system_disconnect_client();
+
+       jsonObject* apps = osrf_settings_host_value_object("/activeapps/appname");
+       osrfStringArray* arr = osrfNewStringArray(8);
+
+       if(apps) {
+               int i = 0;
+
+               if(apps->type == JSON_STRING) {
+                       osrfStringArrayAdd(arr, jsonObjectGetString(apps));
+
+               } else {
+                       jsonObject* app;
+                       while( (app = jsonObjectGetIndex(apps, i++)) ) 
+                               osrfStringArrayAdd(arr, jsonObjectGetString(app));
+               }
+
+               char* appname = NULL;
+               i = 0;
+               while( (appname = osrfStringArrayGetString(arr, i++)) ) {
+
+                       char* libfile = osrf_settings_host_value("/apps/%s/implementation", appname);
+                       info_handler("Launching application %s with implementation %s", appname, libfile);
+       
+                       if(! (appname && libfile) ) {
+                               warning_handler("Missing appname / libfile in settings config");
+                               continue;
+                       }
+       
+                       int pid;
+       
+                       if( (pid = fork()) ) { 
+                               // storage pid in local table for re-launching dead children...
+                               info_handler("Launched application child %d", pid);
+
+                       } else {
+       
+                               osrfAppRegisterApplication( appname, libfile );
+                               osrf_prefork_run(appname);
+                               exit(0);
+                       }
+               }
+       }
+
+       /** daemonize me **/
+
+       /* let our children do their thing */
+       while(1) {
+               signal(SIGCHLD, __osrfSystemSignalHandler);
+               sleep(10000);
+       }
+       
+       return 0;
+}
+
 int osrf_system_bootstrap_client_resc( char* config_file, char* contextnode, char* resource ) {
 
        if( !( config_file && contextnode ) && ! osrfConfigHasDefaultConfig() )
-               fatal_handler("No Config File Specified\n" );
+               return fatal_handler("No Config File Specified\n" );
 
        if( config_file ) {
                osrfConfigCleanup();
@@ -91,3 +169,14 @@ int osrf_system_shutdown() {
 
 
 
+void __osrfSystemSignalHandler( int sig ) {
+
+       pid_t pid;
+       int status;
+
+       while( (pid = waitpid(-1, &status, WNOHANG)) > 0) {
+               warning_handler("We lost child %d", pid);
+       }
+
+       /** relaunch the server **/
+}
index 414b7d3..7200e14 100644 (file)
 int osrf_system_bootstrap_client( char* config_file, char* contextnode );
 
 /* bootstraps a client adding the given resource string to the host/pid, etc. resource string */
+/**
+  Sets up the global connection.
+  @param configFile The OpenSRF bootstrap config file
+  @param contextNode The location in the config file where we'll find the necessary info
+  @param resource The login resource.  If NULL a default will be created
+  @return 1 on successs, 0 on failure.
+  */
+int osrfSystemBootstrapClientResc( char* configFile, char* contextNode, char* resource );
 int osrf_system_bootstrap_client_resc( char* config_file, char* contextnode, char* resource );
 
+/**
+  Bootstrap the server.
+  @param hostname The name of this host.  This is the name that will be used to 
+       load the settings.
+  @param configfile The OpenSRF bootstrap config file
+  @param contextnode The config context
+  @return 0 on success, -1 on error
+  */
+int osrfSystemBootstrap( char* hostName, char* configfile, char* contextNode );
+
+transport_client* osrfSystemGetTransportClient();
 transport_client* osrf_system_get_transport_client();
 
 /* disconnects and destroys the current client connection */
 int osrf_system_disconnect_client();
 int osrf_system_shutdown(); 
 
-char* osrf_get_config_context();
-
-char* osrf_get_bootstrap_config();
-
 #endif
index 7af26a0..12ee0d1 100644 (file)
@@ -55,10 +55,15 @@ transport_message* new_message_from_xml( const char* msg_xml ) {
        xmlChar* router_class= xmlGetProp( root, BAD_CAST "router_class" );
        xmlChar* broadcast      = xmlGetProp( root, BAD_CAST "broadcast" );
 
-       if( sender ) {
-               new_msg->sender         = strdup((char*)sender);
-               xmlFree(sender);
+       if( router_from ) {
+               new_msg->sender         = strdup((char*)router_from);
+       } else {
+               if( sender ) {
+                       new_msg->sender         = strdup((char*)sender);
+                       xmlFree(sender);
+               }
        }
+
        if( recipient ) {
                new_msg->recipient      = strdup((char*)recipient);
                xmlFree(recipient);
index 87d7848..8d4e1b1 100644 (file)
@@ -143,7 +143,7 @@ sub bootstrap {
 
                my $client = OpenSRF::Utils::SettingsClient->new();
                my $apps = $client->config_value("activeapps", "appname");
-               if(!ref($apps) eq "ARRAY") { $apps = [$apps]; }
+               if(ref($apps) ne "ARRAY") { $apps = [$apps]; }
 
                if(!defined($apps) || @$apps == 0) {
                        print "No apps to load, exiting...";
index dc4a8e2..f2976dd 100644 (file)
@@ -306,7 +306,7 @@ int socket_send(int sock_fd, const char* data) {
        debug_handler( "socket_bundle sending to %d data %s",
                sock_fd, data);
 
-       info_handler("%d : Sending data at %lf\n", getpid(), get_timestamp_millis());
+       debug_handler("%d : Sending data at %lf\n", getpid(), get_timestamp_millis());
        signal(SIGPIPE, SIG_IGN); /* in case a unix socket was closed */
        if( send( sock_fd, data, strlen(data), 0 ) < 0 ) {
                return warning_handler( "tcp_server_send(): Error sending data" );
@@ -536,7 +536,7 @@ int _socket_handle_client_data(socket_manager* mgr, socket_node* node) {
        set_fl(sock_fd, O_NONBLOCK);
        debug_handler("Gathering client data for %d", node->sock_fd);
 
-       info_handler("%d : Received data at %lf\n", getpid(), get_timestamp_millis());
+       debug_handler("%d : Received data at %lf\n", getpid(), get_timestamp_millis());
 
        while( (read_bytes = recv(sock_fd, buf, RBUFSIZE-1, 0) ) > 0 ) {
                debug_handler("Socket %d Read %d bytes and data: %s", sock_fd, read_bytes, buf);