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