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