]> git.evergreen-ils.org Git - OpenSRF.git/blob - include/opensrf/osrf_application.h
52fdccfa14e1f49901fdf5c404f689d03a3788bd
[OpenSRF.git] / include / opensrf / osrf_application.h
1 #ifndef OSRF_APPLICATION_H
2 #define OSRF_APPLICATION_H
3
4 #include <opensrf/utils.h>
5 #include <opensrf/log.h>
6 #include <opensrf/osrf_app_session.h>
7 #include <opensrf/osrf_hash.h>
8
9 #include <opensrf/osrf_json.h>
10 #include <stdio.h>
11 #include <dlfcn.h>
12
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16
17 /**
18   All OpenSRF methods take the signature
19   int methodName( osrfMethodContext* );
20   If a negative number is returned, it means an unknown error occured and an exception
21   will be returned to the client automatically.
22   If a positive number is returned, it means that libopensrf should send a 'Request Complete'
23   message following any messages sent by the method.
24   If 0 is returned, it tells libopensrf that the method completed successfully and 
25   there is no need to send any further data to the client.
26   */
27
28
29
30 /** 
31   This macro verifies methods receive the correct parameters */
32 #define OSRF_METHOD_VERIFY_CONTEXT_(x) \
33         do { \
34                 osrfMethodContext* d = x; \
35                 if(!d) return -1; \
36                 if(!d->session) { \
37                         osrfLogError( OSRF_LOG_MARK, "Session is NULL in app reqeust" ); \
38                         return -1; \
39                 } \
40                 if(!d->method) { \
41                         osrfLogError( OSRF_LOG_MARK,  "Method is NULL in app reqeust" ); \
42                         return -1; \
43                 }\
44                 if(d->method->argc) { \
45                         if(!d->params) { \
46                                 osrfLogError( OSRF_LOG_MARK, \
47                                         "Params is NULL in app reqeust %s", d->method->name ); \
48                                 return -1; \
49                         } \
50                         if( d->params->type != JSON_ARRAY ) { \
51                                 osrfLogError( OSRF_LOG_MARK, \
52                                         "'params' is not a JSON array for method %s", d->method->name);\
53                                 return -1; }\
54                 }\
55                 if( !d->method->name ) { \
56                         osrfLogError( OSRF_LOG_MARK, "Method name is NULL"); \
57                         return -1; \
58                 } \
59         } while(0)
60
61 #ifdef OSRF_LOG_PARAMS
62 #define OSRF_METHOD_VERIFY_CONTEXT(x) \
63         do { \
64                 osrfMethodContext* d = x; \
65                 OSRF_METHOD_VERIFY_CONTEXT_(d); \
66                 char* _j = jsonObjectToJSON(d->params); \
67                 if(_j) { \
68                         osrfLogInfo( OSRF_LOG_MARK, \
69                                 "CALL:  %s %s - %s", d->session->remote_service, d->method->name, _j); \
70                         free(_j); \
71                 } \
72         } \
73         while( 0 )
74 #else
75 #define OSRF_METHOD_VERIFY_CONTEXT(d) OSRF_METHOD_VERIFY_CONTEXT_(d);
76 #endif
77
78
79
80 /* used internally to make sure the method description provided is OK */
81 #define OSRF_METHOD_VERIFY_DESCRIPTION(app, d) \
82         if(!app) return -1; \
83         if(!d) return -1;\
84         if(!d->name) { osrfLogError( OSRF_LOG_MARK,  "No method name provided in description" ), return -1; } \
85         if(!d->symbol) { osrfLogError( OSRF_LOG_MARK,  "No method symbol provided in description" ), return -1; } \
86         if(!d->notes) d->notes = ""; \
87         if(!d->paramNotes) d->paramNotes = "";\
88         if(!d->returnNotes) d->returnNotes = "";
89
90
91
92
93 /* Some well known parameters */
94 #define OSRF_SYSMETHOD_INTROSPECT                               "opensrf.system.method"
95 #define OSRF_SYSMETHOD_INTROSPECT_ATOMIC                "opensrf.system.method.atomic"
96 #define OSRF_SYSMETHOD_INTROSPECT_ALL                   "opensrf.system.method.all"
97 #define OSRF_SYSMETHOD_INTROSPECT_ALL_ATOMIC    "opensrf.system.method.all.atomic"
98 #define OSRF_SYSMETHOD_ECHO                                             "opensrf.system.echo"
99 #define OSRF_SYSMETHOD_ECHO_ATOMIC                              "opensrf.system.echo.atomic"
100
101 #define OSRF_METHOD_SYSTEM                      1
102 #define OSRF_METHOD_STREAMING           2
103 #define OSRF_METHOD_ATOMIC                      4
104 #define OSRF_METHOD_CACHABLE            8
105
106         
107
108 struct _osrfApplicationStruct {
109         void* handle;                                                                   /* the lib handle */
110         osrfHash* methods;
111    void (*onExit) (void);
112 };
113 typedef struct _osrfApplicationStruct osrfApplication;
114
115
116 struct _osrfMethodStruct {
117         char* name;                                     /* the method name */
118         char* symbol;                           /* the symbol name (function) */
119         char* notes;                            /* public method documentation */
120         int argc;                                       /* how many args this method expects */
121         //char* paramNotes;                     /* Description of the params expected for this method */
122         int options;                            /* describes the various options for this method */
123         void* userData;                         /* You can put your weeeeeeed in it ... */
124
125         /*
126         int sysmethod;                          
127         int streaming;                          
128         int atomic;                                     
129         int cachable;                           
130         */
131 }; 
132 typedef struct _osrfMethodStruct osrfMethod;
133
134 struct _osrfMethodContextStruct {
135         osrfAppSession* session;        /* the current session */
136         osrfMethod* method;                     /* the requested method */      
137         jsonObject* params;                     /* the params to the method */
138         int request;                                    /* request id */
139         jsonObject* responses;          /* array of cached responses. */
140 };
141 typedef struct _osrfMethodContextStruct osrfMethodContext;
142
143
144
145 /** 
146   Register an application
147   @param appName The name of the application
148   @param soFile The library (.so) file that implements this application
149   @return 0 on success, -1 on error
150   */
151 int osrfAppRegisterApplication( const char* appName, const char* soFile );
152
153 /**
154   Register a method
155   Any method with  the OSRF_METHOD_STREAMING option set will have a ".atomic"
156   version of the method registered automatically
157   @param appName The name of the application that implements the method
158   @param methodName The fully qualified name of the method
159   @param symbolName The symbol name (function) that implements the method
160   @param notes Public documentation for this method.
161   @params argc The number of arguments this method expects 
162   @param streaming True if this is a streaming method that requires an atomic version
163   @return 0 on success, -1 on error
164   */
165 int osrfAppRegisterMethod( const char* appName, const char* methodName, 
166                 const char* symbolName, const char* notes, int argc, int options );
167
168
169 int osrfAppRegisterExtendedMethod( const char* appName, const char* methodName, 
170                 const char* symbolName, const char* notes, int argc, int options, void* );
171
172 /**
173   Finds the given method for the given app
174   @param appName The application
175   @param methodName The method to find
176   @return A method pointer or NULL if no such method 
177   exists for the given application
178   */
179 osrfMethod* _osrfAppFindMethod( const char* appName, const char* methodName );
180
181 /**
182   Runs the specified method for the specified application.
183   @param appName The name of the application who's method to run
184   @param methodName The name of the method to run
185   @param ses The app session attached to this request
186   @params reqId The request id for this request
187   @param params The method parameters
188   */
189 int osrfAppRunMethod( const char* appName, const char* methodName, 
190                 osrfAppSession* ses, int reqId, jsonObject* params );
191
192 /**
193   Responds to the client with a method exception
194   @param ses The current session
195   @param request The request id
196   @param msg The debug message to send to the client
197   @return 0 on successfully sending of the message, -1 otherwise
198   */
199 int osrfAppRequestRespondException( osrfAppSession* ses, int request, const char* msg, ... );
200
201 int osrfAppRespond( osrfMethodContext* context, const jsonObject* data );
202 int osrfAppRespondComplete( osrfMethodContext* context, const jsonObject* data );
203
204 /* OSRF_METHOD_ATOMIC and/or OSRF_METHOD_CACHABLE and/or 0 for no special options */
205 //int osrfAppProcessMethodOptions( char* method );
206
207 /**
208  * Tells the backend process to run its child init function */
209 int osrfAppRunChildInit(const char* appname);
210 void osrfAppRunExitCode();
211
212 #ifdef __cplusplus
213 }
214 #endif
215
216 #endif