summaryrefslogtreecommitdiffstats
path: root/tags/native-sca-1.0.incubating-M3-RC4/runtime/extensions/rest/service/httpd/src/tuscany/sca/rest/ModREST.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tags/native-sca-1.0.incubating-M3-RC4/runtime/extensions/rest/service/httpd/src/tuscany/sca/rest/ModREST.cpp')
-rw-r--r--tags/native-sca-1.0.incubating-M3-RC4/runtime/extensions/rest/service/httpd/src/tuscany/sca/rest/ModREST.cpp1351
1 files changed, 0 insertions, 1351 deletions
diff --git a/tags/native-sca-1.0.incubating-M3-RC4/runtime/extensions/rest/service/httpd/src/tuscany/sca/rest/ModREST.cpp b/tags/native-sca-1.0.incubating-M3-RC4/runtime/extensions/rest/service/httpd/src/tuscany/sca/rest/ModREST.cpp
deleted file mode 100644
index eb3ac60e01..0000000000
--- a/tags/native-sca-1.0.incubating-M3-RC4/runtime/extensions/rest/service/httpd/src/tuscany/sca/rest/ModREST.cpp
+++ /dev/null
@@ -1,1351 +0,0 @@
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <sstream>
-
-#include "apr_strings.h"
-#include "apr_fnmatch.h"
-#include "apr_lib.h"
-
-#define APR_WANT_STRFUNC
-#include "apr_want.h"
-#include "ap_config.h"
-#include "httpd.h"
-
-// This section removes the windows/httpd build error "strtoul_is_not_a_portable_function_use_strtol_instead"
-#if defined(WIN32) || defined (_WINDOWS)
-#ifdef strtoul
-#undef strtoul
-#endif
-#define strtoul strtoul
-#endif
-
-#include "http_config.h"
-#include "http_core.h"
-#include "http_request.h"
-#include "http_protocol.h"
-#include "http_log.h"
-#include "http_main.h"
-#include "util_script.h"
-#include "util_md5.h"
-
-#include "mod_core.h"
-
-#include "commonj/sdo/SDO.h"
-
-#include "tuscany/sca/core/Exceptions.h"
-#include "tuscany/sca/util/Logging.h"
-#include "RESTServiceProxy.h"
-#include "model/RESTReferenceBinding.h"
-#include "tuscany/sca/rest/model/RESTInterface.h"
-#include "tuscany/sca/model/Composite.h"
-#include "tuscany/sca/model/CompositeService.h"
-#include "tuscany/sca/model/Component.h"
-#include "tuscany/sca/model/Reference.h"
-#include "tuscany/sca/model/ReferenceType.h"
-#include "tuscany/sca/model/WSDLDefinition.h"
-#include "tuscany/sca/model/WSDLOperation.h"
-#include "tuscany/sca/model/WSDLInterface.h"
-#include "tuscany/sca/model/Interface.h"
-#include "tuscany/sca/core/SCARuntime.h"
-#include "tuscany/sca/util/Utils.h"
-
-using namespace std;
-using namespace commonj::sdo;
-using namespace tuscany::sca;
-using namespace tuscany::sca::model;
-using namespace tuscany::sca::util;
-
-
-extern "C"
-{
- extern module AP_MODULE_DECLARE_DATA sca_rest_module;
-}
-
-namespace tuscany
-{
- namespace sca
- {
- namespace rest
- {
-
- typedef struct rest_server_config_rec
- {
- char * home;
- } rest_server_config_rec_t;
-
- typedef struct rest_dir_config_rec
- {
- char * root;
- char * path;
- char * base_uri;
- char * component;
- } rest_dir_config_rec_t;
-
- CompositeService* initializeSCARuntime(const char* home, const char* root,
- const char* path, const char* baseURI, const char *component, const char* service);
-
- DataObjectPtr createPayload(DataFactoryPtr dataFactory,
- Operation& operation, const WSDLOperation& wsdlOperation);
-
- void addPart(XMLHelper* xmlHelper, string& payload, Operation& operation);
-
- int logHeaders(void* request, const char* key, const char* value);
-
- /**
- * Initialize the SCA runtime
- */
- CompositeService* initializeSCARuntime(const char* home, const char* root,
- const char* path, const char* baseURI, const char *component, const char* service)
- {
- logentry();
- loginfo("Home: %s", home);
- loginfo("Root: %s", root);
- loginfo("Path: %s", path);
- loginfo("Base URI: %s", baseURI);
- loginfo("Component: %s", component);
- loginfo("Service: %s", service);
-
- try
- {
- SCARuntime* runtime = SCARuntime::initializeSharedRuntime(home, root, path, baseURI);
-
- string componentName;
- if (strlen(component))
- {
- componentName = component;
- }
- else
- {
- componentName = runtime->getDefaultComponentName();
- }
- string serviceName = service;
-
- loginfo("Resolving composite: %s, service: %s", componentName.c_str(), serviceName.c_str());
- Component* compositeComponent = runtime->getSystem()->findComponent(componentName);
- if (compositeComponent == NULL)
- {
- string msg = "Component not found " + componentName;
- throwException(SystemConfigurationException, msg.c_str());
- }
- runtime->setDefaultComponent(compositeComponent);
-
- Composite* composite = (Composite*)compositeComponent->getType();
- CompositeService* compositeService = (CompositeService*)composite->findComponent(serviceName);
- if (compositeService == NULL)
- {
- string msg = "Composite service not found " + serviceName;
- throwException(SystemConfigurationException, msg.c_str());
- }
-
- return compositeService;
- }
- catch(TuscanyRuntimeException &ex)
- {
- ostringstream msg;
- msg << ex;
- logerror("Failed to initialize SCA runtime: %s", msg.str().c_str());
- throw;
- }
- }
-
- bool printRequest = false;
-
- int logHeaders(void* request, const char* key, const char* value)
- {
- loginfo("Header key: %s, value: %s", key, value);
- if (printRequest)
- {
- ap_rprintf((request_rec*)request, "<br>Header key: %s, value: %s", key, value);
- }
- return 1;
- }
-
- int rest_handler(request_rec *request)
- {
- logentry();
-
- if (strcmp(request->handler, "sca_rest_module"))
- {
- return DECLINED;
- }
-
- try {
-
- // Set up the read policy
- int rc = ap_setup_client_block(request, REQUEST_CHUNKED_DECHUNK);
- if (rc != OK)
- {
- return rc;
- }
- ap_should_client_block(request);
- if (request->read_chunked == true && request->remaining == 0)
- {
- request->chunked = true;
- }
-
- apr_table_setn(request->headers_out, "Connection", "close");
-
- if (printRequest)
- {
- // Set the content type
- ap_set_content_type(request, "text/html");
-
- // Send the response document
- ap_rputs("<html><body><p>Tuscany Mod_rest works!", request);
- }
-
- rest_server_config_rec_t* server_conf = (rest_server_config_rec_t*)ap_get_module_config(request->server->module_config, &sca_rest_module);
- loginfo("Tuscany home: %s", server_conf->home);
- if (printRequest)
- {
- ap_rprintf(request, "<p>Tuscany home: %s", server_conf->home);
- }
-
- rest_dir_config_rec_t* dir_conf = (rest_dir_config_rec_t*)ap_get_module_config(request->per_dir_config, &sca_rest_module);
- loginfo("Tuscany root: %s", dir_conf->root);
- if (printRequest)
- {
- ap_rprintf(request, "<p>Tuscany root: %s", dir_conf->root);
- }
- loginfo("Tuscany path: %s", dir_conf->path);
- if (printRequest)
- {
- ap_rprintf(request, "<p>Tuscany path: %s", dir_conf->path);
- }
- loginfo("SCA component: %s", dir_conf->component);
- if (printRequest)
- {
- ap_rprintf(request, "<p>SCA component: %s", dir_conf->component);
- }
-
- if (request->protocol)
- {
- loginfo("Protocol: %s", request->protocol);
- if (printRequest)
- {
- ap_rprintf(request, "<p>Protocol: %s", request->protocol);
- }
- }
-
- if (request->method)
- {
- loginfo("HTTP method: %s", request->method);
- if (printRequest)
- {
- ap_rprintf(request, "<p>HTTP method: %s", request->method);
- }
- }
-
- loginfo("HTTP method number: %d", request->method_number);
- if (printRequest)
- {
- ap_rprintf(request, "<p>HTTP method number: %d", request->method_number);
- }
-
- const char* content_type = apr_table_get(request->headers_in, "Content-Type");
- if (content_type)
- {
- loginfo("Content type: %s", content_type);
- if (printRequest)
- {
- ap_rprintf(request, "<p>Content type: %s", content_type);
- }
- }
- else
- {
- content_type = "text/plain";
- }
-
- if (request->content_encoding)
- {
- loginfo("Content encoding: %s", request->content_encoding);
- if (printRequest)
- {
- ap_rprintf(request, "<p>Content encoding: %s", request->content_encoding);
- }
- }
-
- if (printRequest)
- {
- ap_rputs("<p>", request);
- }
- apr_table_do(logHeaders, request, request->headers_in, NULL);
-
- if (request->uri)
- {
- loginfo("URI: %s", request->uri);
- if (printRequest)
- {
- ap_rprintf(request, "<p>URI: %s", request->uri);
- }
- }
-
- if (request->path_info)
- {
- loginfo("Path info: %s", request->path_info);
- if (printRequest)
- {
- ap_rprintf(request, "<p>Path info: %s", request->path_info);
- }
- }
-
- if (request->args)
- {
- loginfo("Args: %s", request->args);
- if (printRequest)
- {
- ap_rprintf(request, "<p>Args: %s", request->args);
- }
- }
-
- if (printRequest)
- {
- ap_rputs("</body></html>", request);
- }
-
- // Extract the service and component names from the HTTP URI path
- string path;
- if (strlen(request->path_info) != 0 && *(request->path_info) == '/')
- {
- path = request->path_info + 1;
- }
- else
- {
- path = request->path_info;
- }
- string uri;
-
- string component;
- string service;
- if (strlen(dir_conf->component))
- {
- // The path only specifies the service, the component name
- // is configured in the directory/location configured
- component = dir_conf->component;
- Utils::tokeniseString("/", path, service, uri);
- }
- else
- {
- // The path must be in the form component / service
- string path2;
- Utils::tokeniseString("/", path, component, path2);
- Utils::tokeniseString("/", path2, service, uri);
- }
-
- loginfo("Component name: %s", component.c_str());
- loginfo("Service name: %s", service.c_str());
-
- // Initialize the SCA runtime
- CompositeService* compositeService = initializeSCARuntime(
- server_conf->home, dir_conf->root, dir_conf->path, dir_conf->base_uri, component.c_str(), service.c_str());
-
- if(!compositeService)
- {
- throwException(SystemConfigurationException,
- "Failed to initialize SCA runtime, could not initialize CompositeService");
- }
-
- Composite* composite = compositeService->getComposite();
- DataFactoryPtr dataFactory = composite->getDataFactory();
- if (dataFactory == 0)
- {
- throwException(SystemConfigurationException,
- "Failed to initialize SCA runtime, could not get DataFactory");
- }
- XMLHelper* xmlHelper = composite->getXMLHelper();
-
- // Get the REST binding
- Reference* reference = compositeService->getReference();
- RESTReferenceBinding* binding = (RESTReferenceBinding*)reference->getBinding();
-
- // Get the REST proxy
- RESTServiceProxy* proxy = (RESTServiceProxy*)binding->getServiceProxy();
-
- // Get the component interface
- Interface* iface = reference->getType()->getInterface();
-
- if (request->method_number == M_GET)
- {
- // Handle an HTTP GET
-
- // Determine the operation to invoke
- WSDLOperation wsdlOperation;
- string wsdlNamespace = "";
- string op_name = "";
- string uriArgs = "";
- if (iface != NULL)
- {
- // If we have a REST interface, the operation name is "retrieve"
- if (iface->getInterfaceTypeQName() == RESTInterface::typeQName)
- {
- op_name = "retrieve";
- uriArgs = uri;
- }
- else if (iface->getInterfaceTypeQName() == WSDLInterface::typeQName)
- {
- // we have a WSDL interface, the operation name is part of the URI
- Utils::tokeniseString("/", uri, op_name, uriArgs);
-
- // look for the WSDL operation definition
- WSDLInterface* wsdlInterface = (WSDLInterface*)iface;
- wsdlNamespace = wsdlInterface->getNamespaceURI();
-
- if (wsdlNamespace != "")
- {
- WSDLDefinition* wsdl = composite->findWSDLDefinition(wsdlNamespace);
- if (wsdl == 0)
- {
- string msg = "WSDL not found for: " + wsdlNamespace;
- throwException(SystemConfigurationException, msg.c_str());
- }
- try
- {
- wsdlOperation = wsdl->findOperation(wsdlInterface->getName(), op_name.c_str());
- }
- catch(SystemConfigurationException&)
- {
- throw;
- }
-
- if (!wsdlOperation.isDocumentStyle() || !wsdlOperation.isWrappedStyle())
- {
- throwException(ServiceInvocationException,
- "Only wrapped document style WSDL operations are currentlysupported");
- }
- }
- }
- }
- else
- {
- Utils::tokeniseString("/", uri, op_name, uriArgs);
- }
-
- // Create a default document literal wrapped WSDL operation
- if (wsdlNamespace == "")
- {
- 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 output DataObject
- if (iface!=NULL &&
- iface->getInterfaceTypeQName() == RESTInterface::typeQName)
- {
- if (outputDataObject == NULL)
- {
- throwException(ServiceInvocationException, "Null output from REST create operation");
- }
- else
- {
-
- // Pure REST, send the response document
- XMLHelperPtr xm = HelperProvider::getXMLHelper(dataFactory);
- DataObjectList& l = outputDataObject->getList("return");
- if (l.size() != 0)
- {
- DataObjectPtr resourceDataObject = l[0];
- XMLDocumentPtr doc = xm->createDocument(
- resourceDataObject,
- resourceDataObject->getType().getURI(),
- resourceDataObject->getType().getName());
- char* str = xm->save(doc);
-
- // Calculate an Etag hash for the response
- char* etag = ap_md5(request->pool, (const unsigned char*)str);
-
- // Handle a conditional GET, if the etag matches the etag
- // sent by the client, we don't need to send the whole response
- const char* match = apr_table_get(request->headers_in, "If-None-Match");
- if (match != NULL && !strcmp(etag, match))
- {
- loginfo("REST resource matches ETag, sending HTTP 304 response code");
- request->status = HTTP_NOT_MODIFIED;
- }
- else
- {
- loginfo("Sending response: %s", str);
- ap_set_content_type(request, "text/xml");
- apr_table_setn(request->headers_out, "ETag", etag);
-
- // Send an Etag header to allow caching and
- // conditional gets
- apr_table_setn(request->headers_out, "ETag", etag);
-
- ap_rputs(str, request);
- }
- }
- else
- {
- loginfo("REST resource not found, sending HTTP 404 response code");
- request->status = HTTP_NOT_FOUND;
-
- return OK;
- }
- }
- }
- else
- {
- // Command style, send the response wrapper element
-
- if (outputDataObject == NULL)
- {
- loginfo("Sending empty response");
- //request->status = HTTP_NO_CONTENT;
- }
- else
- {
- XMLHelperPtr xm = HelperProvider::getXMLHelper(dataFactory);
- DataObjectList& l = outputDataObject->getList("return");
- if (l.size() != 0)
- {
- DataObjectPtr resultDataObject = l[0];
- XMLDocumentPtr doc = xm->createDocument(
- resultDataObject,
- resultDataObject->getType().getURI(),
- resultDataObject->getType().getName());
- char* str = xm->save(doc);
-
- loginfo("Sending response: %s", str);
- ap_set_content_type(request, "text/xml");
- ap_rputs(str, request);
- }
- else
- {
- loginfo("Sending empty response");
- //request->status = HTTP_NO_CONTENT;
- }
- }
- }
-
- return OK;
- }
- else if (request->method_number == M_POST)
- {
- // Handle an HTTP POST
-
- // Determine the operation to invoke
- WSDLOperation wsdlOperation;
- string wsdlNamespace = "";
- string op_name = "";
- string uriArgs = "";
- if (iface != NULL)
- {
- // If we have a REST interface, the operation name is "create"
- if (iface->getInterfaceTypeQName() == RESTInterface::typeQName)
- {
- op_name = "create";
- }
- else if (iface->getInterfaceTypeQName() == WSDLInterface::typeQName)
- {
- // we have a WSDL interface, the operation name is part of the URI
- Utils::tokeniseString("/", uri, op_name, uriArgs);
-
- // look for the WSDL operation definition
- WSDLInterface* wsdlInterface = (WSDLInterface*)iface;
- wsdlNamespace = wsdlInterface->getNamespaceURI();
-
- if (wsdlNamespace != "")
- {
- WSDLDefinition* wsdl = composite->findWSDLDefinition(wsdlNamespace);
- if (wsdl == 0)
- {
- string msg = "WSDL not found for: " + wsdlNamespace;
- throwException(SystemConfigurationException, msg.c_str());
- }
- try
- {
- wsdlOperation = wsdl->findOperation(wsdlInterface->getName(), op_name.c_str());
- }
- catch(SystemConfigurationException&)
- {
- throw;
- }
-
- if (!wsdlOperation.isDocumentStyle() || !wsdlOperation.isWrappedStyle())
- {
- throwException(ServiceInvocationException,
- "Only wrapped document style WSDL operations are currentlysupported");
- }
- }
- }
- }
- else
- {
- Utils::tokeniseString("/", uri, op_name, uriArgs);
- }
-
- // Create a default document literal wrapped WSDL operation
- if (wsdlNamespace == "")
- {
- 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 POST 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 POST input");
- }
- }
- string input = sinput.str();
-
- string contentType = content_type;
- if (contentType.find("multipart/form-data") == 0)
- {
- // This is a multipart POST, extract each part from the
- // POST body
- string begin;
- string boundary;
- Utils::tokeniseString("boundary=", contentType, begin, boundary);
-
- for (;;)
- {
- // Read each part
- string part;
- string next;
- Utils::tokeniseString(boundary, input, part, next);
- input = next;
-
- // Skip first and last empty parts
- if (part.length() == 0 || part == "--")
- continue;
-
- // Read headers
- bool xml = false;
- int empty = -1;
- for (;;)
- {
- string header;
- Utils::tokeniseString("\r\n", part, header, next);
- part = next;
- if (header == "")
- {
- // Two empty lines signal the beginning of the content
- empty++;
- if (empty == 1)
- break;
- }
- else
- {
- empty = 0;
-
- // Detect XML content
- if (header == "Content-Type: text/xml")
- xml = true;
- }
- }
-
- // Read the part content
- if (part.length())
- {
- // Strip the trailer
- string value;
- Utils::tokeniseString("\r\n--", part, value, next);
-
- if (xml)
- {
- // Add an XML parameter to the operation
- addPart(xmlHelper, value, operation);
- }
- else
- {
- // Add a text parameter to the operation
- string* stringData = new string;
- *stringData = value;
- operation.addParameter(stringData);
- }
- }
-
- // Read till the end of the POST body
- if (input.length() == 0)
- break;
- }
- }
- else
- {
- // The POST body represents a single part
- 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
- if (iface!=NULL &&
- iface->getInterfaceTypeQName() == RESTInterface::typeQName)
- {
- // Pure REST, send the location of the created resource
-
- if (outputDataObject == NULL)
- {
- throwException(ServiceInvocationException, "Null output from REST create operation");
- }
-
- string location = "";
-
- DataObjectList& l = outputDataObject->getList("return");
- if (l.size())
- {
- location = l.getCString(0);
- }
-
- if (location == "")
- {
- loginfo("No resource location, sending HTTP 400 response code");
- request->status = HTTP_BAD_REQUEST;
-
- return OK;
- }
-
- string locuri = request->uri;
- locuri += '/';
- locuri += location;
-
- const char* loc = ap_construct_url(request->pool, locuri.c_str(), request);
- loginfo("Sending resource location: %s", loc);
- apr_table_setn(request->headers_out, "Location", loc);
- apr_table_setn(request->headers_out, "Content-Location", loc);
- request->status = HTTP_CREATED;
-
- // Send the created resource entity back to the client
- ap_set_content_type(request, "text/xml");
- ap_rputs(input.c_str(), request);
-
- }
- else
- {
- // Command style, send the response element
-
- if (outputDataObject == NULL)
- {
- loginfo("Sending empty response");
- //request->status = HTTP_NO_CONTENT;
- }
- else
- {
- XMLHelperPtr xm = HelperProvider::getXMLHelper(dataFactory);
- DataObjectList& l = outputDataObject->getList("return");
- if (l.size() != 0)
- {
- DataObjectPtr resultDataObject = l[0];
- XMLDocumentPtr doc = xm->createDocument(
- resultDataObject,
- resultDataObject->getType().getURI(),
- resultDataObject->getType().getName());
- char* str = xm->save(doc);
-
- loginfo("Sending response: %s", str);
- ap_set_content_type(request, "text/xml");
- ap_rputs(str, request);
- }
- else
- {
- loginfo("Sending empty response");
- //request->status = HTTP_NO_CONTENT;
- }
- }
- }
-
- return OK;
- }
- 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);
-
- // Empty response
- //request->status = HTTP_NO_CONTENT;
- 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);
-
- // Empty response
- //request->status = HTTP_NO_CONTENT;
- return OK;
- }
- else
- {
- if (request->method)
- {
- logerror("Unsupported HTTP method: %s", request->method);
- }
- else
- {
- logerror("Unsupported HTTP method: %d", request->method_number);
- }
- return HTTP_NOT_IMPLEMENTED;
- }
- }
- catch(TuscanyRuntimeException& ex)
- {
- ostringstream msg;
- msg << ex;
- logerror("Failed to process REST request: %s", msg.str().c_str());
- return HTTP_INTERNAL_SERVER_ERROR;
- }
- }
-
- DataObjectPtr createPayload(DataFactoryPtr dataFactory, Operation& operation, const WSDLOperation& wsdlOperation)
- {
- logentry();
-
- DataObjectPtr inputDataObject;
- try
- {
-
- // Create the input wrapper
- const Type& rootType = dataFactory->getType(wsdlOperation.getInputTypeUri().c_str(), "RootType");
- const Property& prop = rootType.getProperty(wsdlOperation.getInputTypeName().c_str());
- const Type& inputType = prop.getType();
- inputDataObject = dataFactory->create(inputType);
- }
- catch (SDORuntimeException&)
- {
- try
- {
- // Create the input wrapper
- const Type& inputType = dataFactory->getType(wsdlOperation.getInputTypeUri().c_str(),
- wsdlOperation.getInputTypeName().c_str());
- inputDataObject = dataFactory->create(inputType);
- }
- catch (SDORuntimeException&)
- {
-
- // The input wrapper type is not known, create an open DataObject
- inputDataObject = dataFactory->create("http://tempuri.org", "Wrapper");
- }
- }
-
- // Go through data object to set the input parameters
- PropertyList pl = inputDataObject->getType().getProperties();
-
- if(pl.size() == 0)
- {
- if(inputDataObject->getType().isOpenType() && inputDataObject->getType().isDataObjectType())
- {
- /*
- * This code deals with sending xsd:any elements
- */
- for (int i=0; i<operation.getNParms(); i++)
- {
- ostringstream pname;
- pname << "param" << (i+1);
- DataObjectList& l = inputDataObject->getList(pname.str());
-
- const Operation::Parameter& parm = operation.getParameter(i);
- switch(parm.getType())
- {
- case Operation::STRING:
- {
- l.append((*(string*)parm.getValue()).c_str());
- break;
- }
- case Operation::DATAOBJECT:
- {
- l.append(*(DataObjectPtr*)parm.getValue());
- break;
- }
- default:
- {
- break;
- }
- }
- }
- }
- }
- else {
-
- // Each parameter in the operation should be a property on the request dataobject
- for (unsigned int i=0; i<operation.getNParms(); i++)
- {
- const Operation::Parameter& parm = operation.getParameter(i);
- switch(parm.getType())
- {
- case Operation::STRING:
- {
- inputDataObject->setCString(i, (*(string*)parm.getValue()).c_str());
- break;
- }
- case Operation::DATAOBJECT:
- {
- inputDataObject->setDataObject(i, *(DataObjectPtr*)parm.getValue());
- break;
- }
- default:
- {
- break;
- }
- }
- }
- }
-
- return inputDataObject;
- }
-
- void addPart(XMLHelper* xmlHelper, string& payload, Operation& operation)
- {
- logentry();
-
-
- //TODO Remove this workaround once SDO supports loading of open top level content
- // The workaround is to wrap the open content in a wrapper element
- string xmldecl;
- string xml;
- Utils::rTokeniseString("?>", payload, xmldecl, xml);
- string body = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
- body += "<Wrapper xmlns=\"http://tempuri.org\" xmlns:tns=\"http://tempuri.org\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n";
- body += xml;
- body += "\n</Wrapper>";
-
- // Convert the body to an SDO DataObject
- DataObjectPtr inputWrapperDataObject = NULL;
- XMLDocumentPtr theXMLDocument = xmlHelper->load(body.c_str(), NULL);
- if (theXMLDocument != 0)
- {
- inputWrapperDataObject = theXMLDocument->getRootDataObject();
- }
- if(!inputWrapperDataObject)
- {
- ostringstream msg;
- msg << "Could not convert received document to SDO: " << body;
- throwException(ServiceDataException, msg.str().c_str());
- }
-
- // Get the body part
- DataObjectPtr inputDataObject = NULL;
- PropertyList bpl = inputWrapperDataObject->getInstanceProperties();
- if (bpl.size()!=0)
- {
- if (bpl[0].isMany())
- {
- DataObjectList& parts = inputWrapperDataObject->getList((unsigned int)0);
- inputDataObject = parts[0];
- }
- else
- {
- inputDataObject = inputWrapperDataObject->getDataObject(bpl[0]);
- }
- }
- if (inputDataObject == NULL)
- {
- ostringstream msg;
- msg << "Could not convert received document to SDO: " << body;
- throwException(ServiceDataException, msg.str().c_str());
- }
-
- DataObjectPtr* dataObjectData = new DataObjectPtr;
- *dataObjectData = inputDataObject;
- (*dataObjectData)->detach();
- operation.addParameter(dataObjectData);
- }
-
- const char *rest_set_home(cmd_parms *cmd, void *dummy,
- const char *arg)
- {
- rest_server_config_rec_t *conf = (rest_server_config_rec_t*)ap_get_module_config(
- cmd->server->module_config, &sca_rest_module);
- conf->home = apr_pstrdup(cmd->pool, arg);
- return NULL;
- }
-
- const char *rest_set_path(cmd_parms *cmd, void *c,
- const char *arg)
- {
- rest_dir_config_rec_t *conf = (rest_dir_config_rec_t*)c;
- conf->path = apr_pstrdup(cmd->pool, arg);
- return NULL;
- }
-
- const char *rest_set_root(cmd_parms *cmd, void *c,
- const char *arg)
- {
- rest_dir_config_rec_t *conf = (rest_dir_config_rec_t*)c;
- conf->root = apr_pstrdup(cmd->pool, arg);
- return NULL;
- }
-
- const char *rest_set_base_uri(cmd_parms *cmd, void *c,
- const char *arg)
- {
- rest_dir_config_rec_t *conf = (rest_dir_config_rec_t*)c;
- conf->base_uri = apr_pstrdup(cmd->pool, arg);
- return NULL;
- }
-
- const char *rest_set_component(cmd_parms *cmd, void *c,
- const char *arg)
- {
- rest_dir_config_rec_t *conf = (rest_dir_config_rec_t*)c;
- conf->component = apr_pstrdup(cmd->pool, arg);
- return NULL;
- }
-
- const command_rec rest_module_cmds[] =
- {
- AP_INIT_TAKE1("TuscanyHome", (const char*(*)())tuscany::sca::rest::rest_set_home, NULL, RSRC_CONF,
- "Tuscany home directory"),
- AP_INIT_TAKE1("TuscanyPath", (const char*(*)())tuscany::sca::rest::rest_set_path, NULL, ACCESS_CONF,
- "Tuscany SCA composite search path"),
- AP_INIT_TAKE1("TuscanyRoot", (const char*(*)())tuscany::sca::rest::rest_set_root, NULL, ACCESS_CONF,
- "Tuscany root SCA configuration path"),
- AP_INIT_TAKE1("TuscanyBaseURI", (const char*(*)())tuscany::sca::rest::rest_set_base_uri, NULL, ACCESS_CONF,
- "Tuscany SCA system base URI"),
- AP_INIT_TAKE1("TuscanyComponent", (const char*(*)())tuscany::sca::rest::rest_set_component, NULL, ACCESS_CONF,
- "SCA component name"),
- {NULL}
- };
-
- int rest_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp,
- server_rec *s)
- {
- return OK;
- }
-
- void rest_child_init(apr_pool_t* p, server_rec* svr_rec)
- {
- rest_server_config_rec_t *conf = (rest_server_config_rec_t*)ap_get_module_config(
- svr_rec->module_config, &sca_rest_module);
-
- if(false)
- {
- fprintf(stderr, "[Tuscany] Due to one or more errors mod_rest loading"
- " failed. Causing apache2 to stop loading\n");
- exit(APEXIT_CHILDFATAL);
- }
- }
-
- void register_hooks(apr_pool_t *p)
- {
- ap_hook_handler(rest_handler, NULL, NULL, APR_HOOK_MIDDLE);
- ap_hook_post_config(rest_init, NULL, NULL, APR_HOOK_MIDDLE);
- ap_hook_child_init(rest_child_init, NULL, NULL, APR_HOOK_MIDDLE);
- }
-
- void *rest_create_dir_config(apr_pool_t *p, char *dirspec)
- {
- rest_dir_config_rec_t* conf = (rest_dir_config_rec_t* )apr_palloc(p, sizeof(*conf));
- conf->path = "";
- conf->root = "";
- conf->base_uri = "";
- conf->component = "";
- return conf;
- }
-
- void* rest_create_server_config(apr_pool_t *p, server_rec *s)
- {
- rest_server_config_rec_t* conf = (rest_server_config_rec_t* )apr_palloc(p, sizeof(*conf));
- conf->home = "";
- return conf;
- }
-
- } // End namespace rest
- } // End namespace sca
-} // End namespace tuscany
-
-extern "C"
-{
-
- module AP_MODULE_DECLARE_DATA sca_rest_module =
- {
- STANDARD20_MODULE_STUFF,
- tuscany::sca::rest::rest_create_dir_config, /* dir config */
- NULL, /* dir merger --- default is to override */
- tuscany::sca::rest::rest_create_server_config, /* server config */
- NULL, /* merge server config */
- tuscany::sca::rest::rest_module_cmds, /* command table */
- tuscany::sca::rest::register_hooks /* register_hooks */
- };
-
-}