31 |
#include <gwmsgchain.h> |
#include <gwmsgchain.h> |
32 |
|
|
33 |
#include "pnetvm.h" |
#include "pnetvm.h" |
34 |
|
#include "clrCache.h" |
35 |
#include "dgreadenv.h" |
#include "dgreadenv.h" |
36 |
|
|
37 |
#include "../fields/dgfid.h" |
#include "../fields/dgfid.h" |
72 |
long clen = 0; |
long clen = 0; |
73 |
long mlen = 0; |
long mlen = 0; |
74 |
long blen = 0; |
long blen = 0; |
75 |
|
DGImage *dgimg = NULL; |
76 |
|
|
77 |
char dgeeinvoke[128] = {0}; |
char dgeeinvoke[128] = {0}; |
78 |
char *args[70] = {0}; |
char *args[70] = {0}; |
79 |
int i = 0; |
int i = 0; |
80 |
int pix = 0; |
int pix = 0; |
81 |
|
|
82 |
|
static int init = 0; |
83 |
|
|
84 |
|
if( !init ) { |
85 |
|
pnetVM_initCache(); |
86 |
|
init = 1; |
87 |
|
} |
88 |
|
|
89 |
|
|
90 |
do { |
do { |
91 |
/* Instantiate a 'message buffer' from input data stream |
/* Instantiate a 'message buffer' from input data stream |
99 |
/* Extract URI, WebService ID and Request Data |
/* Extract URI, WebService ID and Request Data |
100 |
*/ |
*/ |
101 |
ctype = MIME_TEXT_PLAIN; |
ctype = MIME_TEXT_PLAIN; |
102 |
wsname = (char*)gwmc_read_data( request, DGF_WS_NAME, &ctype, 1, &wlen); |
wsname = (char*)gwmc_read_data(request, DGF_WS_NAME, &ctype, 1, &wlen); |
103 |
class = (char*)gwmc_read_data( request, DGF_CLASS_NAME, &ctype, 1, &clen); |
class = (char*)gwmc_read_data(request, DGF_CLASS_NAME, &ctype, 1, &clen); |
104 |
method = (char*)gwmc_read_data( request, DGF_METHOD_NAME, &ctype, 1, &mlen); |
method = (char*)gwmc_read_data(request, DGF_METHOD_NAME, &ctype, 1, &mlen); |
105 |
|
|
106 |
if( !(wsname && class && method) ) { |
if( !(wsname && class && method) ) { |
107 |
gw_logf( LOG_ERROR, "Insufficient parameters in input" ); |
gw_logf( LOG_ERROR, "Insufficient parameters in input" ); |
108 |
gwusrerr = ERR_INTERNAL_FAILURE; |
gwusrerr = ERR_INTERNAL_FAILURE; |
109 |
break; |
break; |
110 |
} |
} |
111 |
|
|
112 |
|
/* Check if we have already loaded this webservice and have it in our |
113 |
|
* cache. |
114 |
|
*/ |
115 |
|
if( (dgimg = pnetVM_findCachedObject( wsname )) == NULL ) { |
116 |
|
gw_logf( LOG_DEBUG, |
117 |
|
"Fetch Webservice '%s' from Resource Manager", wsname ); |
118 |
|
|
119 |
gw_logf( LOG_DEBUG, "Fetch Webservice '%s' from Resource Manager", wsname ); |
/* Get bytecode from Resource Manager |
120 |
|
*/ |
121 |
if( (bc_stream = fetch_bytecode( wsname )) == NULL ) { |
if( (bc_stream = fetch_bytecode( wsname )) == NULL ) { |
122 |
gw_logf(LOG_ERROR, "Failure Requesting webservice from Resource Manager"); |
gw_logf( LOG_ERROR, |
123 |
gwusrerr = ERR_INTERNAL_FAILURE; |
"Failure Requesting webservice from Resource Manager"); |
124 |
break; |
gwusrerr = ERR_INTERNAL_FAILURE; |
125 |
} |
break; |
126 |
|
} |
127 |
if( bc_stream ) { |
|
128 |
/* We've got some bytecode to execute |
/* We've got some bytecode to execute |
129 |
*/ |
*/ |
130 |
ctype = MIME_OCTET_STREAM; |
ctype = MIME_OCTET_STREAM; |
131 |
bcode = (char*)gwmc_read_data(bc_stream, DGF_APP_BYTECODE, &ctype, 1, &blen); |
bcode = (char*)gwmc_read_data( bc_stream, DGF_APP_BYTECODE, |
132 |
/* We'd use the bytecode if pnet allowed us to... instead we just |
&ctype, 1, &blen); |
133 |
* pass in a full filename to pnet. |
|
134 |
|
if( blen == 0 ) { |
135 |
|
gw_logf( LOG_ERROR, |
136 |
|
"Failure Requesting webservice from Resource Manager"); |
137 |
|
gwusrerr = ERR_INTERNAL_FAILURE; |
138 |
|
break; |
139 |
|
} |
140 |
|
|
141 |
|
/* Add bytecode to cache ready for AssemblyContainer's internal call |
142 |
|
* to fetch it. |
143 |
|
*/ |
144 |
|
pnetVM_addBytecodeToCache( wsname, (uchar *)bcode, (ulong)blen ); |
145 |
|
/* FIXME From this moment on, destroying bc_stream will also destroy |
146 |
|
* the bcode. |
147 |
|
* We may need to store the bc_stream itself in the DGImage or make a |
148 |
|
* copy of the bcode. |
149 |
* |
* |
150 |
* TODO - Get pnet to allow instantiation of assembly from memory instead |
* XXX The Goldwater API is not getting a bit horrible. XXX |
|
* of from disc. |
|
151 |
*/ |
*/ |
152 |
|
} else { |
153 |
|
bcode = dgimg->bytes; |
154 |
|
blen = dgimg->len; |
155 |
|
} |
156 |
|
|
157 |
|
if( bcode ) { |
158 |
gw_logf( LOG_DEBUG, "Passing WS to pnet VM.." ); |
gw_logf( LOG_DEBUG, "Passing WS to pnet VM.." ); |
159 |
|
|
160 |
sprintf( dgeeinvoke, "%s/PROTOCOL_SERVICE", dgee_libdir ); |
sprintf( dgeeinvoke, "%s/%s", dgee_libdir, PROTOCOL_SERVICE ); |
161 |
|
|
162 |
i = 0; |
i = 0; |
163 |
args[i++] = "Invoke"; |
args[i++] = "Invoke"; |
180 |
|
|
181 |
gwusrerr = ERR_VM_FAILURE; |
gwusrerr = ERR_VM_FAILURE; |
182 |
|
|
183 |
if( pnetvm_entry(i-1, args) == 0 ) { |
if( pnetvm_entry(dgeeinvoke) == 0 ) { |
184 |
|
|
185 |
if( (replyXML = pnetvm_get_reply_xml() ) != NULL ) { |
gw_logf( LOG_DEBUG, "Processing WS..." ); |
186 |
|
|
187 |
|
if( (replyXML = pnetvm_get_reply_xml(i-1, args) ) != NULL ) { |
188 |
|
|
189 |
if( (replyMC = gwmc_create() ) != NULL ) { |
if( (replyMC = gwmc_create() ) != NULL ) { |
190 |
gwmc_add_data( replyMC, DGF_XMLRPC_REPLY, MIME_TEXT_XML, |
gwmc_add_data( replyMC, DGF_XMLRPC_REPLY, MIME_TEXT_XML, |
207 |
if( state == GWSuccess ) gw_send_reply( state, stream, blen ); |
if( state == GWSuccess ) gw_send_reply( state, stream, blen ); |
208 |
else gw_send_reply( state, "", 0 ); |
else gw_send_reply( state, "", 0 ); |
209 |
|
|
|
/* Destroy pnet VM process */ |
|
|
pnetvm_cleanup(); |
|
|
|
|
210 |
/* Cleanup Messages |
/* Cleanup Messages |
211 |
*/ |
*/ |
212 |
if( request ) gwmc_destroy( &request ); |
if( request ) gwmc_destroy( &request ); |
245 |
ret = -1; |
ret = -1; |
246 |
do { |
do { |
247 |
gwmc_add_data( request, DGF_WS_NAME, MIME_TEXT_PLAIN, |
gwmc_add_data( request, DGF_WS_NAME, MIME_TEXT_PLAIN, |
248 |
wsname, strlen(wsname) ); |
wsname, strlen(wsname) ); |
249 |
|
|
250 |
/* Get data stream to send |
/* Get data stream to send |
251 |
*/ |
*/ |
252 |
if( (stream = gwmc_get_message_ptr( request, &len )) == NULL ) { |
if( (stream = gwmc_get_message_ptr( request, &len )) == NULL ) { |
253 |
gw_logf( LOG_ERROR, "Failed to get message stream" ); |
gw_logf( LOG_ERROR, "Failed to get message stream" ); |
254 |
break; |
break; |
255 |
} |
} |
256 |
|
|
257 |
if( ( ret = gw_svc_call( "/DGEE/RM/GetBytecode", stream, len, &replymsg, 0 )) < 0 ){ |
if( ( ret = gw_svc_call( "/DGEE/RM/GetBytecode", stream, len, &replymsg, 0 )) < 0 ){ |
258 |
gw_logf( LOG_ERROR, "gw_svc_call for '/DGEE/RM/GetBytecode' failed with code %d [%s]\n", gwerror, gw_errorstr(gwerror) ); |
gw_logf(LOG_ERROR, |
259 |
break; |
"gw_svc_call '/DGEE/RM/GetBytecode' failed with code %d [%s]\n", |
260 |
|
gwerror, gw_errorstr(gwerror) ); |
261 |
|
break; |
262 |
} |
} |
263 |
|
|
264 |
/* We've now got a message with bytecode embedded within it |
/* We've now got a message with bytecode embedded within it |
265 |
*/ |
*/ |
266 |
} while(0); |
} while(0); |
267 |
|
|
268 |
gwmc_destroy( &request ); |
gwmc_destroy( &request ); |
270 |
if( ret < 0 ) { |
if( ret < 0 ) { |
271 |
/* Drop all memory */ |
/* Drop all memory */ |
272 |
gw_free_message( &replymsg ); |
gw_free_message( &replymsg ); |
273 |
return NULL; |
return NULL; |
274 |
} |
} |
275 |
|
|
276 |
if( (request = gwmc_importGWMessage( &replymsg )) == NULL ) { |
if( (request = gwmc_importGWMessage( &replymsg )) == NULL ) { |