You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by js...@apache.org on 2006/12/02 09:57:49 UTC
svn commit: r481521 - in /incubator/tuscany/cpp/sca/runtime/extensions/rest:
reference/curl/src/tuscany/sca/rest/RESTServiceWrapper.cpp
service/httpd/src/tuscany/sca/rest/ModREST.cpp
service/httpd/src/tuscany/sca/rest/RESTServiceProxy.cpp
Author: jsdelfino
Date: Sat Dec 2 00:57:48 2006
New Revision: 481521
URL: http://svn.apache.org/viewvc?view=rev&rev=481521
Log:
Completed POST resource support, added PUT and DELETE support.
Modified:
incubator/tuscany/cpp/sca/runtime/extensions/rest/reference/curl/src/tuscany/sca/rest/RESTServiceWrapper.cpp
incubator/tuscany/cpp/sca/runtime/extensions/rest/service/httpd/src/tuscany/sca/rest/ModREST.cpp
incubator/tuscany/cpp/sca/runtime/extensions/rest/service/httpd/src/tuscany/sca/rest/RESTServiceProxy.cpp
Modified: incubator/tuscany/cpp/sca/runtime/extensions/rest/reference/curl/src/tuscany/sca/rest/RESTServiceWrapper.cpp
URL: http://svn.apache.org/viewvc/incubator/tuscany/cpp/sca/runtime/extensions/rest/reference/curl/src/tuscany/sca/rest/RESTServiceWrapper.cpp?view=diff&rev=481521&r1=481520&r2=481521
==============================================================================
--- incubator/tuscany/cpp/sca/runtime/extensions/rest/reference/curl/src/tuscany/sca/rest/RESTServiceWrapper.cpp (original)
+++ incubator/tuscany/cpp/sca/runtime/extensions/rest/reference/curl/src/tuscany/sca/rest/RESTServiceWrapper.cpp Sat Dec 2 00:57:48 2006
@@ -143,7 +143,7 @@
if (strlen(str) > 10 && !strncmp(str, "Location: ", 10))
{
string s = &str[10];
- mem->location = s.substr(0,s.find_last_not_of("\r\n"));
+ mem->location = s.substr(0,s.find_last_not_of("\r\n")+1);
}
delete str;
@@ -235,7 +235,6 @@
if (opName == "retrieve")
{
// Build the request URL
-
bool firstParm = 0;
string uri;
if (operation.getNParms() !=0)
@@ -302,7 +301,7 @@
// Pass our 'chunk' struct to the callback function
curl_easy_setopt(curl_handle, CURLOPT_HEADERDATA, (void *)&headerChunk);
- // Perform the HTTP get
+ // Perform the HTTP GET
CURLcode rc = curl_easy_perform(curl_handle);
if (rc)
@@ -332,6 +331,10 @@
+ "</Part>";
setReturn(xmlHelper, part, operation);
}
+ else
+ {
+ throwException(ServiceInvocationException, "Failed to retrieve resource, empty response");
+ }
}
else
{
@@ -354,10 +357,7 @@
// Create the input payload
ostringstream spayload;
- for (int i=0; i<operation.getNParms(); i++)
- {
- writeParameter(xmlHelper, spayload, operation.getParameter(i));
- }
+ writeParameter(xmlHelper, spayload, operation.getParameter(0));
const string& requestPayload = spayload.str();
requestChunk.memory = requestPayload.c_str();
requestChunk.size = requestPayload.size();
@@ -386,10 +386,9 @@
curl_slist *requestHeaders = NULL;
requestHeaders = curl_slist_append(requestHeaders, "Expect:");
requestHeaders = curl_slist_append(requestHeaders, "Content-Type: text/xml");
- requestHeaders = curl_slist_append(requestHeaders, "Connection: close");
curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, requestHeaders);
- // Perform the HTTP post
+ // Perform the HTTP POST
curl_easy_setopt(curl_handle, CURLOPT_POST, true);
CURLcode rc = curl_easy_perform(curl_handle);
@@ -429,11 +428,226 @@
else if (opName == "update")
{
// HTTP PUT
+
+ // Build the request URL
+ bool firstParm = 0;
+ string uri;
+ if (operation.getNParms() > 1)
+ {
+
+ // If the first parameter is a URI, then we'll use it,
+ // otherwise we'll use the binding URI
+ ostringstream s0;
+ writeParameter(xmlHelper, s0, operation.getParameter(0));
+ string p0 = s0.str();
+ if (p0.find("://") != string::npos)
+ {
+ firstParm = 1;
+ uri = p0;
+ }
+ else
+ {
+ uri = binding->getURI();
+ }
+ }
+ else
+ {
+ uri = binding->getURI();
+ }
+ // Add the parameters to the end of the URI
+ ostringstream os;
+ if (uri[uri.length()-1] == '?')
+ {
+ // If the URI ends with a "?" then we use the query
+ // form param=value&
+ os << uri;
+ for (int i = firstParm; i < operation.getNParms()-1; i++)
+ {
+ os << "param" << (i + 1) << "=";
+ writeParameter(xmlHelper, os, operation.getParameter(i));
+ if (i < operation.getNParms()-1)
+ os << "&";
+ }
+ }
+ else
+ {
+ // Add the parameters in the form
+ // value1 / value2 / value3
+ os << uri;
+ for (int i = firstParm; i < operation.getNParms()-1; i++)
+ {
+ os << "/";
+ writeParameter(xmlHelper, os, operation.getParameter(i));
+ }
+ }
+
+ string url = os.str();
+ curl_easy_setopt(curl_handle, CURLOPT_URL, url.c_str());
+
+ // Create the input payload
+ ostringstream spayload;
+ writeParameter(xmlHelper, spayload, operation.getParameter(operation.getNParms()-1));
+ const string& requestPayload = spayload.str();
+ requestChunk.memory = requestPayload.c_str();
+ requestChunk.size = requestPayload.size();
+
+ // Read all data using this function
+ curl_easy_setopt(curl_handle, CURLOPT_READFUNCTION, read_callback);
+
+ // Pass our 'chunk' struct to the callback function
+ curl_easy_setopt(curl_handle, CURLOPT_READDATA, (void *)&requestChunk);
+
+ // Send all data to this function
+ curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_callback);
+
+ // Pass our 'chunk' struct to the callback function
+ curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&responseChunk);
+
+ // Send all headers to this function
+ curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, header_callback);
+
+ // Pass our 'chunk' struct to the callback function
+ curl_easy_setopt(curl_handle, CURLOPT_HEADERDATA, (void *)&headerChunk);
+
+ // Configure headers
+ curl_slist *requestHeaders = NULL;
+ requestHeaders = curl_slist_append(requestHeaders, "Expect:");
+ requestHeaders = curl_slist_append(requestHeaders, "Content-Type: text/xml");
+ curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, requestHeaders);
+
+ // Perform the HTTP PUT
+ curl_easy_setopt(curl_handle, CURLOPT_PUT, true);
+ curl_easy_setopt(curl_handle, CURLOPT_UPLOAD, true) ;
+ long size = (long)requestChunk.size;
+ curl_easy_setopt(curl_handle, CURLOPT_INFILESIZE, size);
+
+ CURLcode rc = curl_easy_perform(curl_handle);
+
+ curl_slist_free_all(requestHeaders);
+
+ if (rc)
+ {
+ throwException(ServiceInvocationException, curl_easy_strerror(rc));
+ }
+
+ // Get the output and location of the created resource
+ string responsePayload = "";
+ if (responseChunk.memory)
+ {
+ responsePayload = string((const char*)responseChunk.memory, responseChunk.size);
+ }
+
+ long httprc;
+ curl_easy_getinfo (curl_handle, CURLINFO_RESPONSE_CODE, &httprc);
+ if (httprc != 200)
+ {
+ ostringstream msg;
+ msg << "Failed to update REST resource, HTTP code: " << httprc;
+ if (responsePayload != "")
+ {
+ msg << ", payload: " << responsePayload;
+ }
+ throwException(ServiceInvocationException, msg.str().c_str());
+ }
}
else if (opName == "delete")
{
// HTTP DELETE
-
+
+ // Build the request URL
+ bool firstParm = 0;
+ string uri;
+ if (operation.getNParms() !=0)
+ {
+
+ // If the first parameter is a URI, then we'll use it,
+ // otherwise we'll use the binding URI
+ ostringstream s0;
+ writeParameter(xmlHelper, s0, operation.getParameter(0));
+ string p0 = s0.str();
+ if (p0.find("://") != string::npos)
+ {
+ firstParm = 1;
+ uri = p0;
+ }
+ else
+ {
+ uri = binding->getURI();
+ }
+ }
+ else
+ {
+ uri = binding->getURI();
+ }
+ // Add the parameters to the end of the URI
+ ostringstream os;
+ if (uri[uri.length()-1] == '?')
+ {
+ // If the URI ends with a "?" then we use the query
+ // form param=value&
+ os << uri;
+ for (int i = firstParm; i < operation.getNParms(); i++)
+ {
+ os << "param" << (i + 1) << "=";
+ writeParameter(xmlHelper, os, operation.getParameter(i));
+ if (i < operation.getNParms()-1)
+ os << "&";
+ }
+ }
+ else
+ {
+ // Add the parameters in the form
+ // value1 / value2 / value3
+ os << uri;
+ for (int i = firstParm; i < operation.getNParms(); i++)
+ {
+ os << "/";
+ writeParameter(xmlHelper, os, operation.getParameter(i));
+ }
+ }
+
+ string url = os.str();
+ curl_easy_setopt(curl_handle, CURLOPT_URL, url.c_str());
+
+ // Send all data to this function
+ curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_callback);
+
+ // Pass our 'chunk' struct to the callback function
+ curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&responseChunk);
+
+ // Send all headers to this function
+ curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, header_callback);
+
+ // Pass our 'chunk' struct to the callback function
+ curl_easy_setopt(curl_handle, CURLOPT_HEADERDATA, (void *)&headerChunk);
+
+ // Perform the HTTP DELETE
+ curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, "DELETE");
+ CURLcode rc = curl_easy_perform(curl_handle);
+ if (rc)
+ {
+ throwException(ServiceInvocationException, curl_easy_strerror(rc));
+ }
+
+ // Get the output data out of the returned document
+ string responsePayload = "";
+ if (responseChunk.memory)
+ {
+ responsePayload = string((const char*)responseChunk.memory, responseChunk.size);
+ }
+
+ long httprc;
+ curl_easy_getinfo (curl_handle, CURLINFO_RESPONSE_CODE, &httprc);
+ if (httprc != 200)
+ {
+ ostringstream msg;
+ msg << "Failed to delete REST resource, HTTP code: " << httprc;
+ if (responsePayload != "")
+ {
+ msg << ", payload: " << responsePayload;
+ }
+ throwException(ServiceInvocationException, msg.str().c_str());
+ }
}
else
{
@@ -618,9 +832,7 @@
}
default:
{
- ostringstream msg;
- msg << "Unsupported parameter type: " << parm.getType();
- throwException(ServiceDataException, msg.str().c_str());
+ break;
}
}
}
Modified: incubator/tuscany/cpp/sca/runtime/extensions/rest/service/httpd/src/tuscany/sca/rest/ModREST.cpp
URL: http://svn.apache.org/viewvc/incubator/tuscany/cpp/sca/runtime/extensions/rest/service/httpd/src/tuscany/sca/rest/ModREST.cpp?view=diff&rev=481521&r1=481520&r2=481521
==============================================================================
--- incubator/tuscany/cpp/sca/runtime/extensions/rest/service/httpd/src/tuscany/sca/rest/ModREST.cpp (original)
+++ incubator/tuscany/cpp/sca/runtime/extensions/rest/service/httpd/src/tuscany/sca/rest/ModREST.cpp Sat Dec 2 00:57:48 2006
@@ -218,6 +218,8 @@
{
request->chunked = true;
}
+
+ apr_table_setn(request->headers_out, "Connection", "close");
if (printRequest)
{
@@ -674,6 +676,26 @@
args = next;
}
}
+
+ // Parse the query string
+ if (request->args)
+ {
+ string query = request->args;
+ for (; query != ""; )
+ {
+ string param;
+ string next;
+ Utils::tokeniseString("&", query, param, next);
+ if (param != "")
+ {
+ string n;
+ string* data = new string;
+ Utils::tokeniseString("=", param, n, *data);
+ operation.addParameter(data);
+ }
+ query = next;
+ }
+ }
// Read the POST input
ostringstream sinput;
@@ -776,12 +798,175 @@
}
else if (request->method_number == M_PUT)
{
-
+
+ // Handle an HTTP PUT
+
+ // Determine the operation to invoke
+ WSDLOperation wsdlOperation;
+ string wsdlNamespace = "";
+ string op_name = "update";
+ string uriArgs = uri;
+
+ // Create a default document literal wrapped WSDL operation
+ wsdlNamespace = compositeService->getName();
+ wsdlOperation = WSDLOperation();
+ wsdlOperation.setOperationName(op_name.c_str());
+ wsdlOperation.setSoapAction(wsdlNamespace+ "#" +op_name);
+ wsdlOperation.setEndpoint("");
+ wsdlOperation.setSoapVersion(WSDLOperation::SOAP11);
+ wsdlOperation.setDocumentStyle(true);
+ wsdlOperation.setWrappedStyle(true);
+ wsdlOperation.setEncoded(false);
+ wsdlOperation.setInputType(string("http://tempuri.org") + "#" + op_name);
+ wsdlOperation.setOutputType(string("http://tempuri.org") + "#" + op_name + "Response");
+
+ // Create the input DataObject
+ Operation operation(op_name.c_str());
+
+ // Parse the args part of the URI
+ if (uriArgs != "")
+ {
+ string args = uriArgs;
+ for (; args != ""; )
+ {
+ string param;
+ string next;
+ Utils::tokeniseString("/", args, param, next);
+ if (param != "")
+ {
+ string* data = new string;
+ *data = param;
+ operation.addParameter(data);
+ }
+ args = next;
+ }
+ }
+
+ // Parse the query string
+ if (request->args)
+ {
+ string query = request->args;
+ for (; query != ""; )
+ {
+ string param;
+ string next;
+ Utils::tokeniseString("&", query, param, next);
+ if (param != "")
+ {
+ string n;
+ string* data = new string;
+ Utils::tokeniseString("=", param, n, *data);
+ operation.addParameter(data);
+ }
+ query = next;
+ }
+ }
+
+ // Read the PUT input
+ ostringstream sinput;
+ char buffer[2049];
+ for ( ; ; )
+ {
+ int size = ap_get_client_block(request, buffer, 2048);
+ if (size > 0)
+ {
+ buffer[size] = '\0';
+ sinput << buffer;
+ }
+ else if (size == 0)
+ {
+ break;
+ }
+ else if (size < 0)
+ {
+ throwException(ServiceInvocationException, "Error reading PUT input");
+ }
+ }
+ string input = sinput.str();
+ addPart(xmlHelper, input, operation);
+
+ DataObjectPtr inputDataObject = createPayload(dataFactory, operation, wsdlOperation);
+
+ // Dispatch to the REST proxy
+ DataObjectPtr outputDataObject = proxy->invoke(wsdlOperation, inputDataObject);
+
+ // Send the response back to the client
+ ap_set_content_type(request, "text/xml");
+
return OK;
}
else if (request->method_number == M_DELETE)
{
+
+ // Determine the operation to invoke
+ WSDLOperation wsdlOperation;
+ string wsdlNamespace = "";
+ string op_name = "delete";
+ string uriArgs = uri;
+ // Create a default document literal wrapped WSDL operation
+ wsdlNamespace = compositeService->getName();
+ wsdlOperation = WSDLOperation();
+ wsdlOperation.setOperationName(op_name.c_str());
+ wsdlOperation.setSoapAction(wsdlNamespace+ "#" +op_name);
+ wsdlOperation.setEndpoint("");
+ wsdlOperation.setSoapVersion(WSDLOperation::SOAP11);
+ wsdlOperation.setDocumentStyle(true);
+ wsdlOperation.setWrappedStyle(true);
+ wsdlOperation.setEncoded(false);
+ wsdlOperation.setInputType(string("http://tempuri.org") + "#" + op_name);
+ wsdlOperation.setOutputType(string("http://tempuri.org") + "#" + op_name + "Response");
+
+ // Create the input DataObject
+ Operation operation(op_name.c_str());
+
+ // Parse the args part of the URI
+ if (uriArgs != "")
+ {
+ string args = uriArgs;
+ for (; args != ""; )
+ {
+ string param;
+ string next;
+ Utils::tokeniseString("/", args, param, next);
+ if (param != "")
+ {
+ string* data = new string;
+ *data = param;
+ operation.addParameter(data);
+ }
+ args = next;
+ }
+ }
+
+ // Parse the query string
+ if (request->args)
+ {
+ string query = request->args;
+ for (; query != ""; )
+ {
+ string param;
+ string next;
+ Utils::tokeniseString("&", query, param, next);
+ if (param != "")
+ {
+ string n;
+ string* data = new string;
+ Utils::tokeniseString("=", param, n, *data);
+ operation.addParameter(data);
+ }
+ query = next;
+ }
+ }
+
+ DataObjectPtr inputDataObject = createPayload(dataFactory, operation, wsdlOperation);
+
+ // Dispatch to the REST proxy
+ DataObjectPtr outputDataObject = proxy->invoke(wsdlOperation, inputDataObject);
+
+ // Send the response back to the client
+ ap_set_content_type(request, "text/xml");
+
return OK;
}
else
@@ -868,9 +1053,7 @@
}
default:
{
- ostringstream msg;
- msg << "Unsupported parameter type: " << parm.getType();
- throwException(ServiceDataException, msg.str().c_str());
+ break;
}
}
}
@@ -895,9 +1078,9 @@
break;
}
default:
- ostringstream msg;
- msg << "Unsupported parameter type: " << parm.getType();
- throwException(ServiceDataException, msg.str().c_str());
+ {
+ break;
+ }
}
}
}
Modified: incubator/tuscany/cpp/sca/runtime/extensions/rest/service/httpd/src/tuscany/sca/rest/RESTServiceProxy.cpp
URL: http://svn.apache.org/viewvc/incubator/tuscany/cpp/sca/runtime/extensions/rest/service/httpd/src/tuscany/sca/rest/RESTServiceProxy.cpp?view=diff&rev=481521&r1=481520&r2=481521
==============================================================================
--- incubator/tuscany/cpp/sca/runtime/extensions/rest/service/httpd/src/tuscany/sca/rest/RESTServiceProxy.cpp (original)
+++ incubator/tuscany/cpp/sca/runtime/extensions/rest/service/httpd/src/tuscany/sca/rest/RESTServiceProxy.cpp Sat Dec 2 00:57:48 2006
@@ -242,10 +242,7 @@
else
{
(*dataObjectData)->detach();
-
- std::cout << *dataObjectData;
}
-
operation.addParameter(dataObjectData);
}
break;
@@ -349,10 +346,7 @@
setOutputData(operation, outputDataObject, dataFactoryPtr);
- std::cout << outputDataObject;
-
return outputDataObject;
-
}
catch(SDORuntimeException& ex)
{
@@ -450,9 +444,7 @@
}
default:
{
- ostringstream msg;
- msg << "Unsupported result type: " << resultType;
- throwException(SystemConfigurationException, msg.str().c_str());
+ break;
}
}
}
@@ -554,9 +546,7 @@
}
default:
{
- ostringstream msg;
- msg << "Unsupported result type: " << resultType;
- throwException(SystemConfigurationException, msg.str().c_str());
+ break;
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: tuscany-commits-unsubscribe@ws.apache.org
For additional commands, e-mail: tuscany-commits-help@ws.apache.org