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