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;
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 \
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 \
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
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:
# --------------------------------------------------------------------------------
# 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
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
-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 .
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
--- /dev/null
+#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;
+}
+
+
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));
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);
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 );
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;
+}
+
+
+
+
+
+
#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"
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 {
};
typedef struct osrf_app_session_struct osrf_app_session;
+typedef struct osrf_app_session_struct osrfAppSession;
/** 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
--- /dev/null
+
+#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;
+}
+
+
+
--- /dev/null
+
+#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 );
+
+
free(resc);
prefork_simple* forker = prefork_simple_init(
- osrf_system_get_transport_client(), maxr, minc, maxc);
+ osrfSystemGetTransportClient(), maxr, minc, maxc);
forker->appname = strdup(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);
}
-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) {
}
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;
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;
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?
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++;
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;
#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"
int prefork_child_free( prefork_child* );
+void osrf_prefork_register_routers( char* appname );
+
+
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 );
#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* );
// -----------------------------------------------------------------------------
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 );
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];
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;
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:
* 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;
}
+
#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;
}
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();
+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 **/
+}
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
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);
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...";
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" );
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);