]> git.evergreen-ils.org Git - OpenSRF.git/blob - include/opensrf/osrf_application.h
d05f2ccd8ab5e280572541eaea19998ef16a2a7c
[OpenSRF.git] / include / opensrf / osrf_application.h
1 #ifndef OSRF_APPLICATION_H
2 #define OSRF_APPLICATION_H
3
4 /**
5         @file osrf_application.h
6         @brief Routines to load and manage shared object libraries.
7
8         Every method of a service is implemented by a C function.  In a few cases those
9         functions are generic to all services.  In other cases they are loaded and executed from
10         a shared object library that is specific to the application offering the service,  A
11         registry maps method names to function names so that we can call the right function.
12
13         Each such function has a similar signature:
14
15                 int method_name( osrfMethodContext* ctx );
16
17         The return value is negative in case of an error.  A return code of zero implies that
18         the method has already sent the client a STATUS message to say that it is finished.
19         A return code greater than zero implies that the method has not sent such a STATUS
20         message, so we need to do so after the method returns.
21
22         Any arguments passed to the method are bundled together in a jsonObject inside the
23         osrfMethodContext.
24
25         An application's shared object may also implement any or all of three standard functions:
26
27         - int osrfAppInitialize( void ) Called when an application is registered
28         - int osrfAppChildInit( void ) Called when a server drone is spawned
29         - void osrfAppChildExit( void ) Called when a server drone terminates
30
31         osrfAppInitialize() and osrfAppChild return zero if successful, and non-zero if not.
32 */
33
34 #include <opensrf/utils.h>
35 #include <opensrf/log.h>
36 #include <opensrf/osrf_app_session.h>
37 #include <opensrf/osrf_hash.h>
38 #include <opensrf/string_array.h>
39
40 #include <opensrf/osrf_json.h>
41 #include <stdio.h>
42 #include <dlfcn.h>
43
44 #ifdef __cplusplus
45 extern "C" {
46 #endif
47
48 /**
49         All OpenSRF methods take the signature
50         int methodName( osrfMethodContext* );
51         If a negative number is returned, it means an unknown error occured and an exception
52         will be returned to the client automatically.
53         If a positive number is returned, it means that libopensrf should send a 'Request Complete'
54         message following any messages sent by the method.
55         If 0 is returned, it tells libopensrf that the method completed successfully and
56         there is no need to send any further data to the client.
57 */
58
59 /** This macro verifies that methods receive the correct parameters */
60 #define _OSRF_METHOD_VERIFY_CONTEXT(d) \
61         if(!d) return -1; \
62         if(!d->session) { \
63                  osrfLogError( OSRF_LOG_MARK, "Session is NULL in app request" ); \
64                  return -1; \
65         } \
66         if(!d->method) { \
67                 osrfLogError( OSRF_LOG_MARK, "Method is NULL in app request" ); \
68                 return -1; \
69         } \
70         if(d->method->argc) { \
71                 if(!d->params) { \
72                         osrfLogError( OSRF_LOG_MARK, "Params is NULL in app request %s", d->method->name ); \
73                         return -1; \
74                 } \
75                 if( d->params->type != JSON_ARRAY ) { \
76                         osrfLogError( OSRF_LOG_MARK, "'params' is not a JSON array for method %s", \
77                                 d->method->name); \
78                         return -1; } \
79         } \
80         if( !d->method->name ) { \
81                 osrfLogError( OSRF_LOG_MARK, "Method name is NULL"); return -1; \
82         }
83
84 #ifdef OSRF_LOG_PARAMS
85 #define OSRF_METHOD_VERIFY_CONTEXT(d) \
86         _OSRF_METHOD_VERIFY_CONTEXT(d); \
87         char* __j = jsonObjectToJSON(d->params); \
88         if(__j) { \
89                 osrfLogInfo( OSRF_LOG_MARK, "CALL:\t%s %s - %s", d->session->remote_service, \
90                                 d->method->name, __j);\
91                 free(__j); \
92         }
93 #else
94 #define OSRF_METHOD_VERIFY_CONTEXT(d) _OSRF_METHOD_VERIFY_CONTEXT(d);
95 #endif
96
97 /**
98         @name Method options
99         @brief Macros that get OR'd together to form method options.
100 */
101 /*@{*/
102 /**
103         @brief Notes that the method may return more than one result.
104
105         For a @em streaming method, we register both an atomic method and a non-atomic method.
106 */
107 #define OSRF_METHOD_STREAMING       2
108 /**
109         @brief  Notes that a previous result to the same call may be available in memcache.
110
111         Before calling the registered function, a cachable method checks memcache for a previously
112         determined result for the same call.  If no such result is available, it calls the
113         registered function and caches the new result before returning.
114
115         This caching is not currently implemented for C methods.
116 */
117 #define OSRF_METHOD_CACHABLE        8
118 /*@}*/
119
120 typedef struct {
121         char* name;                 /**< Method name. */
122         char* symbol;               /**< Symbol name (function name) within the shared object. */
123         char* notes;                /**< Public method documentation. */
124         int argc;                   /**< The minimum number of arguments for the method. */
125         //char* paramNotes;         /**< Description of the params expected for this method. */
126         int options;                /**< Bit switches setting various options for this method. */
127         void* userData;             /**< Opaque pointer to application-specific data. */
128         size_t bufsize;             /**< How big a buffer to use for non-atomic methods */
129
130         /*
131         int sysmethod;
132         int streaming;
133         int atomic;
134         int cachable;
135         */
136 } osrfMethod;
137
138 typedef struct {
139         osrfAppSession* session;    /**< Pointer to the current application session. */
140         osrfMethod* method;         /**< Pointer to the requested method. */
141         jsonObject* params;         /**< Parameters to the method. */
142         int request;                /**< Request id. */
143         jsonObject* responses;      /**< Array of cached responses. */
144 } osrfMethodContext;
145
146 int osrfAppRegisterApplication( const char* appName, const char* soFile );
147
148 int osrfAppRegisterMethod( const char* appName, const char* methodName,
149                 const char* symbolName, const char* notes, int argc, int options );
150
151 int osrfAppRegisterExtendedMethod( const char* appName, const char* methodName,
152                 const char* symbolName, const char* notes, int argc, int options, void* );
153
154 int osrfMethodSetBufferSize( const char* appName, const char* methodName, size_t bufsize );
155
156 osrfMethod* _osrfAppFindMethod( const char* appName, const char* methodName );
157
158 int osrfAppRunMethod( const char* appName, const char* methodName,
159                 osrfAppSession* ses, int reqId, jsonObject* params );
160
161 int osrfAppRequestRespondException( osrfAppSession* ses, int request, const char* msg, ... );
162
163 int osrfAppRespond( osrfMethodContext* context, const jsonObject* data );
164
165 int osrfAppRespondComplete( osrfMethodContext* context, const jsonObject* data );
166
167 int osrfAppRunChildInit(const char* appname);
168
169 void osrfAppRunExitCode( void );
170
171 int osrfMethodVerifyContext( osrfMethodContext* ctx );
172
173 #ifdef __cplusplus
174 }
175 #endif
176
177 #endif