From 450e77168179ef623abb26b0af9775bb55d9347d Mon Sep 17 00:00:00 2001 From: erickson Date: Tue, 4 Oct 2005 20:22:02 +0000 Subject: [PATCH] added atomic method cabilities register the method as streaming and an atomic version will also be registered left space for adding cachable and potentially other method transformations ported existing apps to new method structure automatically initializing the app logger when the app is initialized ported the application code to osrfHash'es instead of linked lists git-svn-id: svn://svn.open-ils.org/ILS/trunk@1894 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- Open-ILS/src/Makefile | 10 +- Open-ILS/src/c-apps/oils_auth.c | 20 +- OpenSRF/bin/opensrf_all | 6 +- OpenSRF/src/c-apps/osrf_dbmath.c | 12 +- OpenSRF/src/c-apps/osrf_math.c | 21 +- OpenSRF/src/c-apps/osrf_version.c | 7 +- OpenSRF/src/libstack/osrf_application.c | 307 +++++++++++++++--------- OpenSRF/src/libstack/osrf_application.h | 53 +++- 8 files changed, 274 insertions(+), 162 deletions(-) diff --git a/Open-ILS/src/Makefile b/Open-ILS/src/Makefile index 70a0c2cd55..8b8a7307df 100644 --- a/Open-ILS/src/Makefile +++ b/Open-ILS/src/Makefile @@ -42,11 +42,17 @@ webcore-install: #mkdir -p $(WEBDIR) #cp -r ../web/* $(WEBDIR) -c_apps: mod_ils_rest_gateway +libfieldmapper: + make -C apachemods libfieldmapper.so + +libfieldmapper-install: + make -C apachemods libfieldmapper-install + +c_apps: libfieldmapper @echo $@ make -C c-apps -c_apps-install: +c_apps-install: libfieldmapper-install @echo $@ make -C c-apps install diff --git a/Open-ILS/src/c-apps/oils_auth.c b/Open-ILS/src/c-apps/oils_auth.c index cdb0e84a58..432d8439e9 100644 --- a/Open-ILS/src/c-apps/oils_auth.c +++ b/Open-ILS/src/c-apps/oils_auth.c @@ -16,35 +16,33 @@ int osrfMathRun( osrfMethodContext* ); int osrfAppInitialize() { - osrfLogInit(MODULENAME); - osrfAppRegisterMethod( MODULENAME, "open-ils.auth.authenticate.init", "oilsAuthInit", "Start the authentication process and returns the intermediate authentication seed", - " [ username ]", 1 ); + " [ username ]", 1, 0 ); osrfAppRegisterMethod( MODULENAME, "open-ils.auth.authenticate.complete", "oilsAuthComplete", "Completes the authentication process and returns the auth token", - "[ username, md5sum( seed + password ) ]", 2 ); + "[ username, md5sum( seed + password ) ]", 2, 0 ); osrfAppRegisterMethod( MODULENAME, "open-ils.auth.session.retrieve", "oilsAuthSessionRetrieve", "Returns the user object (password blanked) for the given login session", - "[ authToken ]", 1 ); + "[ authToken ]", 1, 0 ); osrfAppRegisterMethod( MODULENAME, "open-ils.auth.session.delete", "oilsAuthSessionDelete", "Destroys the given login session", - "[ authToken ]", 1 ); + "[ authToken ]", 1, 0 ); return 0; } @@ -73,7 +71,7 @@ int oilsAuthInit( osrfMethodContext* ctx ) { osrfLog( OSRF_DEBUG, "oilsAuthInit(): has seed %s and key %s", md5seed, key ); resp = jsonNewObject(md5seed); - osrfAppRequestRespondComplete( ctx->session, ctx->request, resp ); + osrfAppRespondComplete( ctx, resp ); jsonObjectFree(resp); free(seed); @@ -151,17 +149,19 @@ int oilsAuthComplete( osrfMethodContext* ctx ) { char* string = va_list_to_string( "%d.%d.%s", getpid(), time(NULL), uname ); /**/ char* authToken = md5sum(string); /**/ char* authKey = va_list_to_string( "%s%s", OILS_AUTH_CACHE_PRFX, authToken ); /**/ + oilsFMSetString( userObj, "passwd", "" ); osrfCachePutObject( authKey, userObj, 28800 ); /* XXX config value */ response = jsonNewObject( authToken ); free(string); free(authToken); free(authKey); } else { + osrfLog( OSRF_INFO, "Login failed for for %s", uname ); response = jsonNewNumberObject(0); } - osrfAppRequestRespondComplete( ctx->session, ctx->request, response ); + osrfAppRespondComplete( ctx, response ); jsonObjectFree(response); osrfMessageFree(omsg); osrfAppSessionFree(session); @@ -187,7 +187,7 @@ int oilsAuthSessionRetrieve( osrfMethodContext* ctx ) { free(key); } - osrfAppRequestRespondComplete( ctx->session, ctx->request, userObj ); + osrfAppRespondComplete( ctx, userObj ); jsonObjectFree(userObj); return 0; } @@ -205,7 +205,7 @@ int oilsAuthSessionDelete( osrfMethodContext* ctx ) { free(key); } - osrfAppRequestRespondComplete( ctx->session, ctx->request, resp ); + osrfAppRespondComplete( ctx, resp ); jsonObjectFree(resp); return 0; } diff --git a/OpenSRF/bin/opensrf_all b/OpenSRF/bin/opensrf_all index cdc998c5d4..10eda5b578 100755 --- a/OpenSRF/bin/opensrf_all +++ b/OpenSRF/bin/opensrf_all @@ -81,7 +81,7 @@ function startJserver { function startRouter { - "$BINDIR/opensrf_router" "$ETCDIR/opensrf_core.xml" + "$BINDIR/opensrf_router" "$ETCDIR/opensrf_core.xml" "router" } function startOpenSRF { @@ -125,12 +125,12 @@ function stopMe { sleep 1; echo "Stopping The Router..."; - killall "OpenSRF Router" + killall -9 "opensrf_router" sleep 1; echo "Stopping Chop Chop..."; - killall jserver-c; + killall -9 jserver-c; return 0; } diff --git a/OpenSRF/src/c-apps/osrf_dbmath.c b/OpenSRF/src/c-apps/osrf_dbmath.c index 0acecafdea..d05a138502 100644 --- a/OpenSRF/src/c-apps/osrf_dbmath.c +++ b/OpenSRF/src/c-apps/osrf_dbmath.c @@ -12,35 +12,33 @@ int osrfMathRun( osrfMethodContext* ); int osrfAppInitialize() { - osrfLogInit(MODULENAME); - osrfAppRegisterMethod( MODULENAME, "add", "osrfMathRun", "Addss two numbers", - "[ num1, num2 ]", 2 ); + "[ num1, num2 ]", 2, 0 ); osrfAppRegisterMethod( MODULENAME, "sub", "osrfMathRun", "Subtracts two numbers", - "[ num1, num2 ]", 2 ); + "[ num1, num2 ]", 2, 0 ); osrfAppRegisterMethod( MODULENAME, "mult", "osrfMathRun", "Multiplies two numbers", - "[ num1, num2 ]", 2 ); + "[ num1, num2 ]", 2, 0 ); osrfAppRegisterMethod( MODULENAME, "div", "osrfMathRun", "Divides two numbers", - "[ num1, num2 ]", 2 ); + "[ num1, num2 ]", 2, 0 ); return 0; } @@ -73,7 +71,7 @@ int osrfMathRun( osrfMethodContext* ctx ) { if(!strcmp(ctx->method->name, "div")) r = i / j; jsonObject* resp = jsonNewNumberObject(r); - osrfAppRequestRespondComplete( ctx->session, ctx->request, resp ); + osrfAppRespondComplete( ctx, resp ); jsonObjectFree(resp); free(a); free(b); diff --git a/OpenSRF/src/c-apps/osrf_math.c b/OpenSRF/src/c-apps/osrf_math.c index 78a9ddc256..fc2bc448ce 100644 --- a/OpenSRF/src/c-apps/osrf_math.c +++ b/OpenSRF/src/c-apps/osrf_math.c @@ -11,35 +11,36 @@ int osrfMathRun( osrfMethodContext* ); int osrfAppInitialize() { - osrfLogInit(MODULENAME); osrfAppRegisterMethod( - MODULENAME, - "add", - "osrfMathRun", - "Addss two numbers", - "( num1, num2 )", 2 ); + MODULENAME, /* which application has this method */ + "add", /* the name of the method */ + "osrfMathRun", /* the symbol that runs the method */ + "Adds two numbers", /* description of the method */ + "( num1, num2 )", /* description of the method params */ + 2, /* the minimum number of params required to run the method */ + 0 ); /* streaming method? yes / no */ osrfAppRegisterMethod( MODULENAME, "sub", "osrfMathRun", "Subtracts two numbers", - "( num1, num2 )", 2 ); + "( num1, num2 )", 2, 0 ); osrfAppRegisterMethod( MODULENAME, "mult", "osrfMathRun", "Multiplies two numbers", - "( num1, num2 )", 2 ); + "( num1, num2 )", 2, 0 ); osrfAppRegisterMethod( MODULENAME, "div", "osrfMathRun", "Divides two numbers", - "( num1, num2 )", 2 ); + "( num1, num2 )", 2, 0 ); return 0; } @@ -80,7 +81,7 @@ int osrfMathRun( osrfMethodContext* ctx ) { if(omsg) { /* return dbmath's response to the user */ - osrfAppRequestRespondComplete( ctx->session, ctx->request, osrfMessageGetResult(omsg) ); + osrfAppRespondComplete( ctx, osrfMessageGetResult(omsg) ); osrfMessageFree(omsg); osrfAppSessionFree(ses); return 0; diff --git a/OpenSRF/src/c-apps/osrf_version.c b/OpenSRF/src/c-apps/osrf_version.c index 2936607bee..ac0e3fbceb 100644 --- a/OpenSRF/src/c-apps/osrf_version.c +++ b/OpenSRF/src/c-apps/osrf_version.c @@ -12,7 +12,6 @@ int osrfVersion( osrfMethodContext* ); int osrfAppInitialize() { - osrfLogInit("opensrf.version"); osrfAppRegisterMethod( "opensrf.version", @@ -21,7 +20,7 @@ int osrfAppInitialize() { "The data for a service/method/params combination will be retrieved " "from the necessary server and the MD5 sum of the total values received " "will be returned", - "( serviceName, methodName, [param1, ...] )", 2 ); + "( serviceName, methodName, [param1, ...] )", 2, 0 ); return 0; } @@ -43,7 +42,7 @@ int osrfVersion( osrfMethodContext* ctx ) { if( cachedmd5 ) { osrfLog( OSRF_DEBUG, "Found %s object in cache, returning....", cachedmd5 ); jsonObject* resp = jsonNewObject(cachedmd5); - osrfAppRequestRespondComplete( ctx->session, ctx->request, resp ); + osrfAppRespondComplete( ctx, resp ); jsonObjectFree(resp); free(paramsmd5); free(cachedmd5); @@ -77,7 +76,7 @@ int osrfVersion( osrfMethodContext* ctx ) { if( resultmd5 ) { jsonObject* resp = jsonNewObject(resultmd5); - osrfAppRequestRespondComplete( ctx->session, ctx->request, resp ); + osrfAppRespondComplete( ctx, resp ); jsonObjectFree(resp); osrfAppSessionFree(ses); osrfLog(OSRF_DEBUG, "Found version string %s, caching and returning...", resultmd5 ); diff --git a/OpenSRF/src/libstack/osrf_application.c b/OpenSRF/src/libstack/osrf_application.c index e91920869d..0feb9b803e 100644 --- a/OpenSRF/src/libstack/osrf_application.c +++ b/OpenSRF/src/libstack/osrf_application.c @@ -2,13 +2,17 @@ #include "osrf_log.h" #include "objson/object.h" -osrfApplication* __osrfAppList = NULL; +//osrfApplication* __osrfAppList = NULL; + +osrfHash* __osrfAppHash = NULL; int osrfAppRegisterApplication( char* appName, char* soFile ) { if(!appName || ! soFile) return -1; char* error; + if(!__osrfAppHash) __osrfAppHash = osrfNewHash(); + info_handler("Registering application %s with file %s", appName, soFile ); osrfApplication* app = safe_malloc(sizeof(osrfApplication)); @@ -21,12 +25,8 @@ int osrfAppRegisterApplication( char* appName, char* soFile ) { return -1; } - app->name = strdup(appName); - - /* this has to be done before initting the application */ - app->next = __osrfAppList; - __osrfAppList = app; - + app->methods = osrfNewHash(); + osrfHashSet( __osrfAppHash, app, appName ); /* see if we can run the initialize method */ int (*init) (void); @@ -52,14 +52,23 @@ int osrfAppRegisterApplication( char* appName, char* soFile ) { info_handler("Application %s registered successfully", appName ); + osrfLogInit(appName); return 0; } -int osrfAppRegisterMethod( char* appName, - char* methodName, char* symbolName, char* notes, char* params, int argc ) { - if( !appName || ! methodName || ! symbolName ) return -1; +int osrfAppRegisterMethod( char* appName, char* methodName, + char* symbolName, char* notes, char* params, int argc, int streaming ) { + + return _osrfAppRegisterMethod(appName, methodName, + symbolName, notes, params, argc, streaming, 0 ); +} + +int _osrfAppRegisterMethod( char* appName, char* methodName, + char* symbolName, char* notes, char* params, int argc, int streaming, int system ) { + + if( !appName || ! methodName ) return -1; osrfApplication* app = _osrfAppFindApplication(appName); if(!app) return warning_handler("Unable to locate application %s", appName ); @@ -67,80 +76,80 @@ int osrfAppRegisterMethod( char* appName, debug_handler("Registering method %s for app %s", methodName, appName ); osrfMethod* method = _osrfAppBuildMethod( - methodName, symbolName, notes, params, argc, 0 ); + methodName, symbolName, notes, params, argc, system, 0 ); + method->streaming = streaming; /* plug the method into the list of methods */ - method->next = app->methods; - app->methods = method; + osrfHashSet( app->methods, method, method->name ); + + if( streaming ) { /* build the atomic counterpart */ + osrfMethod* atomicMethod = _osrfAppBuildMethod( + methodName, symbolName, notes, params, argc, system, 1 ); + osrfHashSet( app->methods, atomicMethod, atomicMethod->name ); + } + return 0; } + osrfMethod* _osrfAppBuildMethod( char* methodName, - char* symbolName, char* notes, char* params, int argc, int sysmethod ) { + char* symbolName, char* notes, char* params, int argc, int sysmethod, int atomic ) { osrfMethod* method = safe_malloc(sizeof(osrfMethod)); + if(methodName) method->name = strdup(methodName); if(symbolName) method->symbol = strdup(symbolName); if(notes) method->notes = strdup(notes); if(params) method->paramNotes = strdup(params); + method->argc = argc; method->sysmethod = sysmethod; - return method; -} + method->atomic = atomic; + method->cachable = 0; + + if(atomic) { /* add ".atomic" to the end of the name */ + char mb[strlen(method->name) + 8]; + sprintf(mb, "%s.atomic", method->name); + free(method->name); + method->name = strdup(mb); + method->streaming = 1; + } + debug_handler("Built method %s", method->name ); -int _osrfAppRegisterSystemMethod( char* appName, char* methodName, - char* notes, char* params, int argc ) { - if(!(appName && methodName)) return -1; - osrfApplication* app = _osrfAppFindApplication(appName); - if(!app) return warning_handler("Unable to locate application %s", appName ); - debug_handler("Registering system method %s for app %s", methodName, appName ); - osrfMethod* method = _osrfAppBuildMethod( - methodName, NULL, notes, params, argc, 1 ); - - /* plug the method into the list of methods */ - method->next = app->methods; - app->methods = method; - return 0; - + return method; } + int __osrfAppRegisterSysMethods( char* app ) { - _osrfAppRegisterSystemMethod( - app, OSRF_SYSMETHOD_INTROSPECT, + _osrfAppRegisterMethod( + app, OSRF_SYSMETHOD_INTROSPECT, NULL, "Return a list of methods whose names have the same initial " "substring as that of the provided method name", - "( methodNameSubstring )", 1 ); + "( methodNameSubstring )", 1, 1 , 1); - _osrfAppRegisterSystemMethod( - app, OSRF_SYSMETHOD_INTROSPECT_ALL, - "Returns a complete list of methods", "()", 0 ); + _osrfAppRegisterMethod( + app, OSRF_SYSMETHOD_INTROSPECT_ALL, NULL, + "Returns a complete list of methods", "()", 0, 1, 1 ); + + _osrfAppRegisterMethod( + app, OSRF_SYSMETHOD_ECHO, NULL, + "Echos all data sent to the server back to the client", + "([a, b, ...])", 0, 1, 1); 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; + return (osrfApplication*) osrfHashGet(__osrfAppHash, name); } 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; + return (osrfMethod*) osrfHashGet( app->methods, methodName ); } osrfMethod* _osrfAppFindMethod( char* appName, char* methodName ) { @@ -162,6 +171,7 @@ int osrfAppRunMethod( char* appName, char* methodName, context.session = ses; context.params = params; context.request = reqId; + context.responses = NULL; /* this is the method we're gonna run */ int (*meth) (osrfMethodContext*); @@ -187,42 +197,91 @@ int osrfAppRunMethod( char* appName, char* methodName, } #endif + int retcode = 0; + if( method->sysmethod ) { + retcode = __osrfAppRunSystemMethod(&context); - int sysres = __osrfAppRunSystemMethod(&context); - if(sysres == 0) return 0; + } else { - if(sysres > 0) - return osrfAppSessionStatus( ses, OSRF_STATUS_COMPLETE, - "osrfConnectStatus", reqId, "Request Complete" ); + /* open and now run the method */ + *(void **) (&meth) = dlsym(app->handle, method->symbol); - if(sysres < 0) - return osrfAppRequestRespondException( - ses, reqId, "An unknown server error occurred" ); + if( (error = dlerror()) != NULL ) { + return osrfAppRequestRespondException( ses, reqId, + "Unable to execute method [%s] for service %s", methodName, appName ); + } + + retcode = (*meth) (&context); } + if(retcode < 0) + return osrfAppRequestRespondException( + ses, reqId, "An unknown server error occurred" ); - /* open the method */ - *(void **) (&meth) = dlsym(app->handle, method->symbol); + return __osrfAppPostProcess( &context, retcode ); - if( (error = dlerror()) != NULL ) { - return osrfAppRequestRespondException( ses, reqId, - "Unable to execute method [%s] for service %s", methodName, appName ); +} + + +int osrfAppRespond( osrfMethodContext* ctx, jsonObject* data ) { + return _osrfAppRespond( ctx, data, 0 ); +} + +int osrfAppRespondComplete( osrfMethodContext* context, jsonObject* data ) { + return _osrfAppRespond( context, data, 1 ); +} + +int _osrfAppRespond( osrfMethodContext* ctx, jsonObject* data, int complete ) { + if(!(ctx && ctx->method)) return -1; + + if( ctx->method->atomic ) { + osrfLog( OSRF_DEBUG, + "Adding responses to stash for atomic method %s", ctx->method ); + + if( ctx->responses == NULL ) + ctx->responses = jsonParseString("[]"); + jsonObjectPush( ctx->responses, jsonObjectClone(data) ); } - /* run the method */ - int ret; - if( (ret = (*meth) (&context)) < 0 ) - return osrfAppRequestRespondException( - ses, reqId, "An unknown server error occurred" ); - if( ret > 0 ) - osrfAppSessionStatus( ses, OSRF_STATUS_COMPLETE, - "osrfConnectStatus", reqId, "Request Complete" ); + if( !ctx->method->atomic && ! ctx->method->cachable ) { + if(complete) + osrfAppRequestRespondComplete( ctx->session, ctx->request, data ); + else + osrfAppRequestRespond( ctx->session, ctx->request, data ); + return 0; + } return 0; } + + + +int __osrfAppPostProcess( osrfMethodContext* ctx, int retcode ) { + if(!(ctx && ctx->method)) return -1; + + osrfLog( OSRF_DEBUG, "Postprocessing method %s with retcode %d", + ctx->method->name, retcode ); + + if(ctx->responses) { /* we have cached responses to return */ + + osrfAppRequestRespondComplete( ctx->session, ctx->request, ctx->responses ); + jsonObjectFree(ctx->responses); + ctx->responses = NULL; + + } else { + + if( retcode > 0 ) + osrfAppSessionStatus( ctx->session, OSRF_STATUS_COMPLETE, + "osrfConnectStatus", ctx->request, "Request Complete" ); + } + + return 0; + +} + int osrfAppRequestRespondException( osrfAppSession* ses, int request, char* msg, ... ) { if(!ses) return -1; if(!msg) msg = ""; @@ -235,13 +294,15 @@ int osrfAppRequestRespondException( osrfAppSession* ses, int request, char* msg, static void __osrfAppSetIntrospectMethod( osrfMethodContext* ctx, osrfMethod* method, jsonObject* resp ) { if(!(ctx && resp)) return; - jsonObjectSetKey(resp, "api_name", jsonNewObject(method->name)); - jsonObjectSetKey(resp, "method", jsonNewObject(method->symbol)); - jsonObjectSetKey(resp, "service", jsonNewObject(ctx->session->remote_service)); - jsonObjectSetKey(resp, "notes", jsonNewObject(method->notes)); - jsonObjectSetKey(resp, "argc", jsonNewNumberObject(method->argc)); - jsonObjectSetKey(resp, "params", jsonNewObject(method->paramNotes) ); + jsonObjectSetKey(resp, "api_name", jsonNewObject(method->name)); + jsonObjectSetKey(resp, "method", jsonNewObject(method->symbol)); + jsonObjectSetKey(resp, "service", jsonNewObject(ctx->session->remote_service)); + jsonObjectSetKey(resp, "notes", jsonNewObject(method->notes)); + jsonObjectSetKey(resp, "argc", jsonNewNumberObject(method->argc)); + jsonObjectSetKey(resp, "params", jsonNewObject(method->paramNotes) ); jsonObjectSetKey(resp, "sysmethod", jsonNewNumberObject(method->sysmethod) ); + jsonObjectSetKey(resp, "atomic", jsonNewNumberObject(method->atomic) ); + jsonObjectSetKey(resp, "cachable", jsonNewNumberObject(method->cachable) ); jsonObjectSetClass(resp, "method"); } @@ -250,57 +311,77 @@ static void __osrfAppSetIntrospectMethod( osrfMethodContext* ctx, osrfMethod* me int __osrfAppRunSystemMethod(osrfMethodContext* ctx) { OSRF_METHOD_VERIFY_CONTEXT(ctx); - if( !strcmp(ctx->method->name, OSRF_SYSMETHOD_INTROSPECT_ALL )) { - - jsonObject* resp = NULL; - osrfApplication* app = _osrfAppFindApplication( ctx->session->remote_service ); - if(app) { - osrfMethod* method = app->methods; - while(method) { - resp = jsonNewObject(NULL); - __osrfAppSetIntrospectMethod( ctx, method, resp ); - osrfAppRequestRespond(ctx->session, ctx->request, resp); - jsonObjectFree(resp); - method = method->next; - } - return 1; - } + if( !strcmp(ctx->method->name, OSRF_SYSMETHOD_INTROSPECT_ALL ) || + !strcmp(ctx->method->name, OSRF_SYSMETHOD_INTROSPECT_ALL_ATOMIC )) { - return -1; + return osrfAppIntrospectAll(ctx); } - if( !strcmp(ctx->method->name, OSRF_SYSMETHOD_INTROSPECT )) { + if( !strcmp(ctx->method->name, OSRF_SYSMETHOD_INTROSPECT ) || + !strcmp(ctx->method->name, OSRF_SYSMETHOD_INTROSPECT_ATOMIC )) { + + return osrfAppIntrospect(ctx); + } + + osrfAppRequestRespondException( ctx->session, + ctx->request, "System method implementation not found"); + + return 0; +} + + +int osrfAppIntrospect( osrfMethodContext* ctx ) { - jsonObject* resp = NULL; - char* methodSubstring = jsonObjectGetString( jsonObjectGetIndex(ctx->params, 0) ); - osrfApplication* app = _osrfAppFindApplication( ctx->session->remote_service ); - int len = 0; + jsonObject* resp = NULL; + char* methodSubstring = jsonObjectGetString( jsonObjectGetIndex(ctx->params, 0) ); + osrfApplication* app = _osrfAppFindApplication( ctx->session->remote_service ); + int len = 0; - if(!methodSubstring) return 1; /* respond with no methods */ + if(!methodSubstring) return 1; /* respond with no methods */ - if(app) { - osrfMethod* method = app->methods; - while(method) { - if( (len = strlen(methodSubstring)) <= strlen(method->name) ) { - if( !strncmp( method->name, methodSubstring, len) ) { - resp = jsonNewObject(NULL); - __osrfAppSetIntrospectMethod( ctx, method, resp ); - osrfAppRequestRespond(ctx->session, ctx->request, resp); - jsonObjectFree(resp); - } + if(app) { + + osrfHashIterator* itr = osrfNewHashIterator(app->methods); + osrfMethod* method; + + while( (method = osrfHashIteratorNext(itr)) ) { + if( (len = strlen(methodSubstring)) <= strlen(method->name) ) { + if( !strncmp( method->name, methodSubstring, len) ) { + resp = jsonNewObject(NULL); + __osrfAppSetIntrospectMethod( ctx, method, resp ); + osrfAppRespond(ctx, resp); + jsonObjectFree(resp); } - method = method->next; } - return 1; } - - return -1; + osrfHashIteratorFree(itr); + return 1; } return -1; + } +int osrfAppIntrospectAll( osrfMethodContext* ctx ) { + jsonObject* resp = NULL; + osrfApplication* app = _osrfAppFindApplication( ctx->session->remote_service ); + + if(app) { + osrfHashIterator* itr = osrfNewHashIterator(app->methods); + osrfMethod* method; + while( (method = osrfHashIteratorNext(itr)) ) { + resp = jsonNewObject(NULL); + __osrfAppSetIntrospectMethod( ctx, method, resp ); + osrfAppRespond(ctx, resp); + jsonObjectFree(resp); + } + osrfHashIteratorFree(itr); + return 1; + } + + return -1; +} diff --git a/OpenSRF/src/libstack/osrf_application.h b/OpenSRF/src/libstack/osrf_application.h index 451450b146..4dea5a2809 100644 --- a/OpenSRF/src/libstack/osrf_application.h +++ b/OpenSRF/src/libstack/osrf_application.h @@ -4,6 +4,7 @@ #include "opensrf/logging.h" #include "objson/object.h" #include "osrf_app_session.h" +#include "osrf_hash.h" /** @@ -36,7 +37,7 @@ _OSRF_METHOD_VERIFY_CONTEXT(d); \ char* __j = jsonObjectToJSON(d->params);\ if(__j) { \ - osrfLog( OSRF_INFO, "[%s:%s] params: %s", d->session->remote_service, d->method->name, __j);\ + osrfLog( OSRF_INFO, "%s %s - %s", d->session->remote_service, d->method->name, __j);\ free(__j); \ } #else @@ -45,7 +46,6 @@ - /* used internally to make sure the method description provided is OK */ #define OSRF_METHOD_VERIFY_DESCRIPTION(app, d) \ if(!app) return -1; \ @@ -58,17 +58,26 @@ + /* Some well known parameters */ -#define OSRF_SYSMETHOD_INTROSPECT "opensrf.system.method" -#define OSRF_SYSMETHOD_INTROSPECT_ALL "opensrf.system.method.all" +#define OSRF_SYSMETHOD_INTROSPECT "opensrf.system.method" +#define OSRF_SYSMETHOD_INTROSPECT_ATOMIC "opensrf.system.method.atomic" +#define OSRF_SYSMETHOD_INTROSPECT_ALL "opensrf.system.method.all" +#define OSRF_SYSMETHOD_INTROSPECT_ALL_ATOMIC "opensrf.system.method.all.atomic" +#define OSRF_SYSMETHOD_ECHO "opensrf.system.echo" +#define OSRF_SYSMETHOD_ECHO_ATOMIC "opensrf.system.echo.atomic" + +//#define OSRF_METHOD_ATOMIC 1 +//#define OSRF_METHOD_CACHABLE 2 struct _osrfApplicationStruct { - char* name; /* the name of our application */ + //char* name; /* the name of our application */ void* handle; /* the lib handle */ - struct _osrfMethodStruct* methods; /* list of methods */ - struct _osrfApplicationStruct* next; /* next application */ + osrfHash* methods; + //struct _osrfMethodStruct* methods; /* list of methods */ +// struct _osrfApplicationStruct* next; /* next application */ }; typedef struct _osrfApplicationStruct osrfApplication; @@ -79,8 +88,11 @@ struct _osrfMethodStruct { char* notes; /* public method documentation */ int argc; /* how many args this method expects */ char* paramNotes; /* Description of the params expected for this method */ - struct _osrfMethodStruct* next; /* nest method in the list */ +// struct _osrfMethodStruct* next; /* nest method in the list */ int sysmethod; /* true if this is a system method */ + int streaming; /* true if this is a streamable method */ + int atomic; /* true if the method is an atomic method */ + int cachable; /* true if the method is cachable */ }; typedef struct _osrfMethodStruct osrfMethod; @@ -89,6 +101,7 @@ struct _osrfMethodContextStruct { osrfMethod* method; /* the requested method */ jsonObject* params; /* the params to the method */ int request; /* request id */ + jsonObject* responses; /* array of cached responses. */ }; typedef struct _osrfMethodContextStruct osrfMethodContext; @@ -110,16 +123,17 @@ int osrfAppRegisterApplication( char* appName, char* soFile ); @param notes Public documentation for this method. @params params String description description of the params expected @params argc The number of arguments this method expects + @param streaming True if this is a streaming method that requires an atomic version @return 0 on success, -1 on error */ -int osrfAppRegisterMethod( char* appName, - char* methodName, char* symbolName, char* notes, char* params, int argc ); +int osrfAppRegisterMethod( char* appName, char* methodName, + char* symbolName, char* notes, char* params, int argc, int streaming ); -int _osrfAppRegisterSystemMethod( char* appName, char* methodName, - char* notes, char* params, int argc ); +int _osrfAppRegisterMethod( char* appName, char* methodName, + char* symbolName, char* notes, char* params, int argc, int streaming, int system ); osrfMethod* _osrfAppBuildMethod( char* methodName, - char* symbolName, char* notes, char* params, int argc, int sysmethod ); + char* symbolName, char* notes, char* params, int argc, int sysmethod, int streaming ); /** Registher a method @@ -197,4 +211,17 @@ int __osrfAppRegisterSysMethods( char* app ); */ int osrfAppRequestRespondException( osrfAppSession* ses, int request, char* msg, ... ); +int __osrfAppPostProcess( osrfMethodContext* context, int retcode ); + + +int osrfAppRespond( osrfMethodContext* context, jsonObject* data ); +int _osrfAppRespond( osrfMethodContext* context, jsonObject* data, int complete ); +int osrfAppRespondComplete( osrfMethodContext* context, jsonObject* data ); + +/* OSRF_METHOD_ATOMIC and/or OSRF_METHOD_CACHABLE and/or 0 for no special options */ +//int osrfAppProcessMethodOptions( char* method ); + +int osrfAppIntrospect( osrfMethodContext* ctx ); +int osrfAppIntrospectAll( osrfMethodContext* ctx ); + -- 2.43.2