From ae9b105c6718dcb91b415e257acc8b8c8bf0c6c7 Mon Sep 17 00:00:00 2001 From: antelder Date: Tue, 30 Nov 2010 18:46:45 +0000 Subject: Create branch for 2.0 beta2 release git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1040693 13f79535-47bb-0310-9956-ffa450edef68 --- .../2.0-Beta2/modules/binding-http-runtime/LICENSE | 205 +++++++++ .../binding-http-runtime/META-INF/MANIFEST.MF | 28 ++ .../2.0-Beta2/modules/binding-http-runtime/NOTICE | 6 + .../2.0-Beta2/modules/binding-http-runtime/pom.xml | 107 +++++ ...TTPDefaultOperationSelectorProviderFactory.java | 60 +++ ...DefaultServiceOperationSelectorInterceptor.java | 85 ++++ .../HTTPDefaultWireFormatProviderFactory.java | 68 +++ .../HTTPDefaultWireFormatServiceInterceptor.java | 252 +++++++++++ .../format/HTTPXMLWireFormatProviderFactory.java | 70 ++++ .../HTTPXMLWireFormatServiceInterceptor.java | 182 ++++++++ .../http/provider/HTTPBindingListenerServlet.java | 462 +++++++++++++++++++++ .../http/provider/HTTPBindingProviderFactory.java | 64 +++ .../http/provider/HTTPBindingServiceServlet.java | 53 +++ .../sca/binding/http/provider/HTTPContext.java | 46 ++ .../http/provider/HTTPServiceBindingProvider.java | 226 ++++++++++ ...che.tuscany.sca.provider.BindingProviderFactory | 20 + ...y.sca.provider.OperationSelectorProviderFactory | 18 + ....tuscany.sca.provider.WireFormatProviderFactory | 19 + .../org/apache/tuscany/sca/binding/http/BeanA.java | 60 +++ .../tuscany/sca/binding/http/ComplexStuff.java | 32 ++ .../tuscany/sca/binding/http/ComplexStuffImpl.java | 53 +++ .../sca/binding/http/ComplexStuffTestCase.java | 129 ++++++ .../tuscany/sca/binding/http/Helloworld.java | 26 ++ .../tuscany/sca/binding/http/HelloworldImpl.java | 28 ++ .../sca/binding/http/HelloworldTestCase.java | 93 +++++ .../tuscany/sca/binding/http/SomeException.java | 29 ++ .../src/test/resources/complex.composite | 41 ++ .../src/test/resources/helloworld.composite | 41 ++ 28 files changed, 2503 insertions(+) create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/LICENSE create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/META-INF/MANIFEST.MF create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/NOTICE create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/pom.xml create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultOperationSelectorProviderFactory.java create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultServiceOperationSelectorInterceptor.java create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultWireFormatProviderFactory.java create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultWireFormatServiceInterceptor.java create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPXMLWireFormatProviderFactory.java create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPXMLWireFormatServiceInterceptor.java create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingListenerServlet.java create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingProviderFactory.java create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingServiceServlet.java create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPContext.java create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceBindingProvider.java create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.BindingProviderFactory create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.OperationSelectorProviderFactory create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.WireFormatProviderFactory create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/BeanA.java create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/ComplexStuff.java create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/ComplexStuffImpl.java create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/ComplexStuffTestCase.java create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/Helloworld.java create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/HelloworldImpl.java create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/HelloworldTestCase.java create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/SomeException.java create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/resources/complex.composite create mode 100644 sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/resources/helloworld.composite (limited to 'sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime') diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/LICENSE b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/LICENSE new file mode 100644 index 0000000000..8aa906c321 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/LICENSE @@ -0,0 +1,205 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + + + diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/META-INF/MANIFEST.MF b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..0cadabbf76 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/META-INF/MANIFEST.MF @@ -0,0 +1,28 @@ +Manifest-Version: 1.0 +Private-Package: org.apache.tuscany.sca.binding.http.provider;version="2.0. + 0",.;version="2.0.0" +SCA-Version: 1.1 +Bundle-Name: Apache Tuscany SCA HTTP Binding Runtime +Bundle-Vendor: The Apache Software Foundation +Bundle-Version: 2.0.0 +Bundle-ManifestVersion: 2 +Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt +Bundle-Description: Apache Tuscany SCA HTTP Binding Runtime +Import-Package: javax.servlet, + javax.servlet.http, + org.apache.tuscany.sca.assembly;version="2.0.0", + org.apache.tuscany.sca.binding.http;version="2.0.0", + org.apache.tuscany.sca.common.http;version="2.0.0", + org.apache.tuscany.sca.core;version="2.0.0", + org.apache.tuscany.sca.host.http;version="2.0.0", + org.apache.tuscany.sca.interfacedef;version="2.0.0", + org.apache.tuscany.sca.interfacedef.util, + org.apache.tuscany.sca.invocation;version="2.0.0", + org.apache.tuscany.sca.provider;version="2.0.0", + org.apache.tuscany.sca.runtime;version="2.0.0", + org.oasisopen.sca, + org.oasisopen.sca.annotation;version="2.0.0" +Bundle-SymbolicName: org.apache.tuscany.sca.binding.http.runtime +Bundle-DocURL: http://www.apache.org/ +Bundle-RequiredExecutionEnvironment: J2SE-1.5,JavaSE-1.6 + diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/NOTICE b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/NOTICE new file mode 100644 index 0000000000..fdfa0e9faa --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/NOTICE @@ -0,0 +1,6 @@ +${pom.name} +Copyright (c) 2005 - 2008 The Apache Software Foundation + +This product includes software developed by +The Apache Software Foundation (http://www.apache.org/). + diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/pom.xml b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/pom.xml new file mode 100644 index 0000000000..7de19b3bdd --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/pom.xml @@ -0,0 +1,107 @@ + + + + 4.0.0 + + org.apache.tuscany.sca + tuscany-modules + 2.0-Beta2-SNAPSHOT + ../pom.xml + + + tuscany-binding-http-runtime + Apache Tuscany SCA HTTP Binding Runtime + + + + org.apache.tuscany.sca + tuscany-binding-http + 2.0-Beta2-SNAPSHOT + + + + org.apache.tuscany.sca + tuscany-common-http + 2.0-Beta2-SNAPSHOT + + + + org.apache.tuscany.sca + tuscany-core-spi + 2.0-Beta2-SNAPSHOT + + + + org.apache.tuscany.sca + tuscany-databinding + 2.0-Beta2-SNAPSHOT + + + + org.apache.tuscany.sca + tuscany-host-http + 2.0-Beta2-SNAPSHOT + + + + javax.servlet + servlet-api + 2.5 + provided + + + + org.apache.tuscany.sca + tuscany-node-impl + 2.0-Beta2-SNAPSHOT + test + + + + org.apache.tuscany.sca + tuscany-host-jetty + 2.0-Beta2-SNAPSHOT + test + + + + org.apache.tuscany.sca + tuscany-implementation-java-runtime + 2.0-Beta2-SNAPSHOT + test + + + + org.apache.tuscany.sca + tuscany-databinding-json + 2.0-Beta2-SNAPSHOT + test + + + + junit + junit + 4.8.1 + test + + + + + diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultOperationSelectorProviderFactory.java b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultOperationSelectorProviderFactory.java new file mode 100644 index 0000000000..bf6ad75cd3 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultOperationSelectorProviderFactory.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.tuscany.sca.binding.http.format; + +import org.apache.tuscany.sca.binding.http.HTTPDefaultOperationSelector; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.invocation.Interceptor; +import org.apache.tuscany.sca.invocation.Phase; +import org.apache.tuscany.sca.provider.OperationSelectorProvider; +import org.apache.tuscany.sca.provider.OperationSelectorProviderFactory; +import org.apache.tuscany.sca.runtime.RuntimeEndpoint; +import org.apache.tuscany.sca.runtime.RuntimeEndpointReference; + +public class HTTPDefaultOperationSelectorProviderFactory implements OperationSelectorProviderFactory{ + + public HTTPDefaultOperationSelectorProviderFactory(ExtensionPointRegistry extensionPoints) { + } + + @Override + public Class getModelType() { + return null; + } + + @Override + public OperationSelectorProvider createReferenceOperationSelectorProvider(RuntimeEndpointReference endpointReference) { + return null; + } + + @Override + public OperationSelectorProvider createServiceOperationSelectorProvider(final RuntimeEndpoint endpoint) { + return new OperationSelectorProvider(){ + @Override + public Interceptor createInterceptor() { + return new HTTPDefaultServiceOperationSelectorInterceptor(endpoint); + } + + @Override + public String getPhase() { + return Phase.SERVICE_BINDING_OPERATION_SELECTOR; + }}; + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultServiceOperationSelectorInterceptor.java b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultServiceOperationSelectorInterceptor.java new file mode 100644 index 0000000000..dc4f37dbad --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultServiceOperationSelectorInterceptor.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.tuscany.sca.binding.http.format; + +import java.util.List; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.tuscany.sca.binding.http.provider.HTTPContext; +import org.apache.tuscany.sca.interfacedef.Interface; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.invocation.Interceptor; +import org.apache.tuscany.sca.invocation.Invoker; +import org.apache.tuscany.sca.invocation.Message; +import org.apache.tuscany.sca.runtime.RuntimeEndpoint; +import org.oasisopen.sca.ServiceRuntimeException; + +/** + * Sets the operation based on the request path. + * + * From a url: http://localhost:8080/HelloworldComponent/Helloworld/sayHello?name=Petra + * where the component is HelloworldComponent and the service is Helloworld + * the path will be "/sayHello" so the operation is "sayHello". + * + * TODO: we could also do something similar to how the JMS binding supports + * a single "onMessage" method to get all requests, so perhaps this could + * also support impls with method: service(HttpServletRequest, HttpServletResponse) + */ +public class HTTPDefaultServiceOperationSelectorInterceptor implements Interceptor { + + private Invoker next; + private List operations; + + public HTTPDefaultServiceOperationSelectorInterceptor(RuntimeEndpoint endpoint) { + Interface serviceInterface = endpoint.getService().getInterfaceContract().getInterface(); + this.operations = serviceInterface.getOperations(); + } + + @Override + public Message invoke(Message msg) { + HTTPContext context = msg.getBindingContext(); + HttpServletRequest request = context.getRequest(); + String path = request.getPathInfo(); + if (path.startsWith("/")) { + path = path.substring(1); + } + + for (Operation op : operations) { + if (op.getName().equals(path)) { + msg.setOperation(op); + return next.invoke(msg); + } + } + + throw new ServiceRuntimeException("No matching operation: " + path); + } + + @Override + public void setNext(Invoker next) { + this.next = next; + } + + @Override + public Invoker getNext() { + return next; + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultWireFormatProviderFactory.java b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultWireFormatProviderFactory.java new file mode 100644 index 0000000000..45e74d8ec8 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultWireFormatProviderFactory.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.tuscany.sca.binding.http.format; + +import org.apache.tuscany.sca.binding.http.HTTPDefaultWireFormat; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.interfacedef.InterfaceContract; +import org.apache.tuscany.sca.invocation.Interceptor; +import org.apache.tuscany.sca.invocation.Phase; +import org.apache.tuscany.sca.provider.WireFormatProvider; +import org.apache.tuscany.sca.provider.WireFormatProviderFactory; +import org.apache.tuscany.sca.runtime.RuntimeEndpoint; +import org.apache.tuscany.sca.runtime.RuntimeEndpointReference; + +public class HTTPDefaultWireFormatProviderFactory implements WireFormatProviderFactory { + + public HTTPDefaultWireFormatProviderFactory(ExtensionPointRegistry extensionPoints) { + } + + @Override + public Class getModelType() { + return null; + } + + @Override + public WireFormatProvider createReferenceWireFormatProvider(RuntimeEndpointReference endpointReference) { + return null; + } + + @Override + public WireFormatProvider createServiceWireFormatProvider(final RuntimeEndpoint endpoint) { + return new WireFormatProvider() { + @Override + public InterfaceContract configureWireFormatInterfaceContract(InterfaceContract interfaceContract) { + // TODO: Ideally this wants to set the databinding on a per request basis from the + // http content type and accept headers and so support things like json or xml etc, + // for now to get started just use json + interfaceContract.getInterface().resetDataBinding("JSON"); + return interfaceContract; + } + @Override + public Interceptor createInterceptor() { + return new HTTPDefaultWireFormatServiceInterceptor(endpoint); + } + @Override + public String getPhase() { + return Phase.SERVICE_BINDING_WIREFORMAT; + }}; + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultWireFormatServiceInterceptor.java b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultWireFormatServiceInterceptor.java new file mode 100644 index 0000000000..fcbf8015f8 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPDefaultWireFormatServiceInterceptor.java @@ -0,0 +1,252 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.tuscany.sca.binding.http.format; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Set; +import java.util.SortedSet; +import java.util.StringTokenizer; +import java.util.TreeSet; + +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.tuscany.sca.binding.http.provider.HTTPContext; +import org.apache.tuscany.sca.interfacedef.DataType; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.invocation.Interceptor; +import org.apache.tuscany.sca.invocation.Invoker; +import org.apache.tuscany.sca.invocation.Message; +import org.apache.tuscany.sca.runtime.RuntimeEndpoint; +import org.oasisopen.sca.ServiceRuntimeException; + +/** + * Handles the default wire format for the http binding + * + * 1- determine the request and response format (xml, json, etc) from the + * binding config or content type header and accept headers + * - TODO: need a way to configure the databinding framework based on that format + * 2- get the request contents from the HttpServletRequest + * - for a post its just the request body + * - for a get need to convert the query string into a body based on the format (xml, json, etc) + * 3- send the request on down the wire + * 4- set the response contents in the HttpServletResponse + * (the databinding should already have put it in the correct format) + * + */ +public class HTTPDefaultWireFormatServiceInterceptor implements Interceptor { + + private Invoker next; + private String jsonpCallbackName = "callback"; + + public HTTPDefaultWireFormatServiceInterceptor(RuntimeEndpoint endpoint) { + } + + @Override + public void setNext(Invoker next) { + this.next = next; + } + + @Override + public Invoker getNext() { + return next; + } + + @Override + public Message invoke(Message msg) { + try { + return invokeResponse(getNext().invoke(invokeRequest(msg))); + } catch (IOException e) { + throw new ServiceRuntimeException(e); + } + } + + private Message invokeRequest(Message msg) throws IOException { + HTTPContext context = msg.getBindingContext(); + HttpServletRequest servletRequest = context.getRequest(); + if ("GET".equals(servletRequest.getMethod())) { + msg.setBody(getRequestFromQueryString(msg.getOperation(), servletRequest)); + } else { + msg.setBody(getRequestFromPost(msg.getOperation(), servletRequest)); + } + return msg; + } + + /** + * The data binding seems to be expecting an Object array of json strings so if the + * post data is a json array convert that to an array of strings + * TODO: should this be being done by the data binding framework? + */ + private Object[] getRequestFromPost(Operation operation, HttpServletRequest servletRequest) throws IOException { + List os = new ArrayList(); + String data = read(servletRequest); + if (data.length() > 0) { + if (data.startsWith("[") && data.endsWith("]")) { + data = data.substring(1, data.length()-1); + StringTokenizer st = new StringTokenizer(data, ","); + while (st.hasMoreElements()) { + os.add(st.nextElement()); + } + } else { + os.add(data); + } + } + return os.toArray(); + } + + private Message invokeResponse(Message msg) throws IOException { + HTTPContext context = msg.getBindingContext(); + HttpServletRequest servletRequest = context.getRequest(); + HttpServletResponse servletResponse = context.getResponse(); + + if (msg.isFault()) { + servletResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, String.valueOf(msg.getBody())); + } else { + String response = getResponseAsString(servletRequest, servletResponse, msg.getBody()); + servletResponse.getOutputStream().println(response); + } + + return msg; + } + + /** + * Turn the request into a string array of JSON structures. The data binding + * layer will then convert each of the individual parameters into the appropriate + * types for the implementation interface + * + * From ML thread: http://apache.markmail.org/message/ix3vvyomronellmi + * 1- if the binding configuration contains a mapping from query parameter name to operation parameter then use that. + * 2- if the service interface or impl uses jaxrs annotations to name the parameters then use that mapping + * 3- if the query parameters are name arg0, arg1 etc than use those names for the mapping, + * 4- otherwise use the order in the query string. + */ + protected Object[] getRequestFromQueryString(Operation operation, ServletRequest servletRequest) { + + List types = operation.getInputType().getLogical(); + int typesIndex = 0; + + List jsonRequestArray = new ArrayList(); + + for (String name : getOrderedParameterNames(servletRequest)) { + String jsonRequest = ""; + // quote string parameters so clients work in the usual javascript way + if (typesIndex < types.size() && String.class.equals(types.get(typesIndex++).getGenericType())) { + String x = servletRequest.getParameter(name); + if (x.startsWith("\"") || x.startsWith("'")) { + jsonRequest += x; + } else { + if (x.contains("\"")) { + jsonRequest += "'" + x + "'"; + } else { + jsonRequest += "\"" + x + "\""; + } + } + } else { + jsonRequest += servletRequest.getParameter(name); + } + jsonRequestArray.add(jsonRequest); + } + + return jsonRequestArray.toArray(); + } + + /** + * Get the request parameter names in the correct order. + * Either the query parameters are named arg0, arg1, arg2 etc or else use the order + * from the order in the query string. Eg, the url: + * http://localhost:8085/HelloWorldService/sayHello2?first=petra&last=arnold&callback=foo" + * should invoke: + * sayHello2("petra", "arnold") + * so the parameter names should be ordered: "first", "last" + */ + protected List getOrderedParameterNames(ServletRequest servletRequest) { + List orderedNames = new ArrayList(); + Set parameterNames = servletRequest.getParameterMap().keySet(); + if (parameterNames.contains("arg0")) { + for (int i=0; i sortedNames = new TreeSet(new Comparator(){ + public int compare(String o1, String o2) { + int i = queryString.indexOf(o1); + int j = queryString.indexOf(o2); + return i - j; + }}); + for (String name : parameterNames) { + // ignore system and jsonpCallbackName parameters + if (!name.startsWith("_") && !name.equals(jsonpCallbackName)) { + sortedNames.add(name); + } + } + orderedNames.addAll(sortedNames); + } + return orderedNames; + } + + /** + * The databinding layer will have converted the return type into a JSON string so simply + * add wrap it for return. + */ + protected String getResponseAsString(HttpServletRequest servletRequest, HttpServletResponse servletResponse, Object response) { + String jsonResponse = response == null ? "" : response.toString(); + + if ("GET".equals(servletRequest.getMethod())) { + // handle JSONP callback name padding + String callback = servletRequest.getParameter(jsonpCallbackName); + if (callback != null && callback.length() > 1) { + jsonResponse = callback + "(" + jsonResponse + ");"; + } + } + + return jsonResponse; + } + + protected static String read(HttpServletRequest servletRequest) throws IOException { + InputStream is = servletRequest.getInputStream(); + BufferedReader reader = null; + try { + reader = new BufferedReader(new InputStreamReader(is)); + StringBuffer sb = new StringBuffer(); + String str; + while ((str = reader.readLine()) != null) { + sb.append(str); + } + return sb.toString().trim(); + } finally { + if (reader != null) { + reader.close(); + } + } + } +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPXMLWireFormatProviderFactory.java b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPXMLWireFormatProviderFactory.java new file mode 100644 index 0000000000..cb60101bb7 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPXMLWireFormatProviderFactory.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.tuscany.sca.binding.http.format; + +import org.apache.tuscany.sca.binding.http.HTTPXMLWireFormat; +import org.apache.tuscany.sca.common.xml.dom.DOMHelper; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.databinding.xml.DOMDataBinding; +import org.apache.tuscany.sca.interfacedef.InterfaceContract; +import org.apache.tuscany.sca.invocation.Interceptor; +import org.apache.tuscany.sca.invocation.Phase; +import org.apache.tuscany.sca.provider.WireFormatProvider; +import org.apache.tuscany.sca.provider.WireFormatProviderFactory; +import org.apache.tuscany.sca.runtime.RuntimeEndpoint; +import org.apache.tuscany.sca.runtime.RuntimeEndpointReference; + +public class HTTPXMLWireFormatProviderFactory implements WireFormatProviderFactory { + + private DOMHelper domHelper; + + public HTTPXMLWireFormatProviderFactory(ExtensionPointRegistry extensionPoints) { + this.domHelper = DOMHelper.getInstance(extensionPoints); + } + + @Override + public Class getModelType() { + return null; + } + + @Override + public WireFormatProvider createReferenceWireFormatProvider(RuntimeEndpointReference endpointReference) { + return null; + } + + @Override + public WireFormatProvider createServiceWireFormatProvider(final RuntimeEndpoint endpoint) { + return new WireFormatProvider() { + @Override + public InterfaceContract configureWireFormatInterfaceContract(InterfaceContract interfaceContract) { + interfaceContract.getInterface().resetDataBinding(DOMDataBinding.NAME); + return interfaceContract; + } + @Override + public Interceptor createInterceptor() { + return new HTTPXMLWireFormatServiceInterceptor(endpoint, domHelper); + } + @Override + public String getPhase() { + return Phase.SERVICE_BINDING_WIREFORMAT; + }}; + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPXMLWireFormatServiceInterceptor.java b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPXMLWireFormatServiceInterceptor.java new file mode 100644 index 0000000000..8bd8b8b9f0 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/format/HTTPXMLWireFormatServiceInterceptor.java @@ -0,0 +1,182 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.tuscany.sca.binding.http.format; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; + +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.tuscany.sca.binding.http.provider.HTTPContext; +import org.apache.tuscany.sca.common.xml.dom.DOMHelper; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.interfacedef.util.FaultException; +import org.apache.tuscany.sca.invocation.Interceptor; +import org.apache.tuscany.sca.invocation.Invoker; +import org.apache.tuscany.sca.invocation.Message; +import org.apache.tuscany.sca.runtime.RuntimeEndpoint; +import org.oasisopen.sca.ServiceRuntimeException; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xml.sax.SAXException; + +/** + * Handles the xml wire format for the http binding + */ +public class HTTPXMLWireFormatServiceInterceptor implements Interceptor { + + private Invoker next; + private DOMHelper domHelper; + + public HTTPXMLWireFormatServiceInterceptor(RuntimeEndpoint endpoint, DOMHelper domHelper) { + this.domHelper = domHelper; + } + + @Override + public void setNext(Invoker next) { + this.next = next; + } + + @Override + public Invoker getNext() { + return next; + } + + @Override + public Message invoke(Message msg) { + try { + return invokeResponse(getNext().invoke(invokeRequest(msg))); + } catch (Exception e) { + throw new ServiceRuntimeException(e); + } + } + + private Message invokeRequest(Message msg) throws IOException, SAXException { + HTTPContext context = msg.getBindingContext(); + HttpServletRequest servletRequest = context.getRequest(); + if ("GET".equals(servletRequest.getMethod())) { + msg.setBody(getRequestFromQueryString(msg.getOperation(), servletRequest)); + } else { + msg.setBody(new Object[]{domHelper.load(read(servletRequest))}); + } + return msg; + } + + private Message invokeResponse(Message msg) throws IOException { + HTTPContext context = msg.getBindingContext(); + HttpServletResponse servletResponse = context.getResponse(); + + servletResponse.setContentType("text/xml"); + + Object o = msg.getBody(); + if (msg.isFault()) { + String xml = domHelper.saveAsString((Node)((FaultException)o).getFaultInfo()); + servletResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, xml); + } else { + String xml = ""; + if (o instanceof Element) { + xml = domHelper.saveAsString((Node)o); + } else if ((o instanceof Object[]) && ((Object[])o)[0] instanceof Node) { + xml = domHelper.saveAsString((Node)((Object[])o)[0]); + } else if (o != null) { + throw new IllegalStateException("expecting Node payload: " + o); + } + servletResponse.getOutputStream().println(xml); + } + + return msg; + } + + /** + * Turn the query request into XML. + */ + protected Object[] getRequestFromQueryString(Operation operation, ServletRequest servletRequest) throws IOException, SAXException { + List xmlRequestArray = new ArrayList(); + for (String name : getOrderedParameterNames(servletRequest)) { + xmlRequestArray.add(domHelper.load("<" + name + ">" + servletRequest.getParameter(name) + "")); + } + return xmlRequestArray.toArray(); + } + + /** + * Get the request parameter names in the correct order. + * Either the query parameters are named arg0, arg1, arg2 etc or else use the order + * from the order in the query string. Eg, the url: + * http://localhost:8085/HelloWorldService/sayHello2?first=petra&last=arnold&callback=foo" + * should invoke: + * sayHello2("petra", "arnold") + * so the parameter names should be ordered: "first", "last" + */ + protected List getOrderedParameterNames(ServletRequest servletRequest) { + List orderedNames = new ArrayList(); + Set parameterNames = servletRequest.getParameterMap().keySet(); + if (parameterNames.contains("arg0")) { + for (int i=0; i sortedNames = new TreeSet(new Comparator(){ + public int compare(String o1, String o2) { + int i = queryString.indexOf(o1); + int j = queryString.indexOf(o2); + return i - j; + }}); + for (String name : parameterNames) { + sortedNames.add(name); + } + orderedNames.addAll(sortedNames); + } + return orderedNames; + } + + protected static String read(HttpServletRequest servletRequest) throws IOException { + InputStream is = servletRequest.getInputStream(); + BufferedReader reader = null; + try { + reader = new BufferedReader(new InputStreamReader(is)); + StringBuffer sb = new StringBuffer(); + String str; + while ((str = reader.readLine()) != null) { + sb.append(str); + } + return sb.toString(); + } finally { + if (reader != null) { + reader.close(); + } + } + } +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingListenerServlet.java b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingListenerServlet.java new file mode 100644 index 0000000000..e2a3a5cf39 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingListenerServlet.java @@ -0,0 +1,462 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.tuscany.sca.binding.http.provider; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URLDecoder; +import java.text.ParseException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.tuscany.sca.assembly.Binding; +import org.apache.tuscany.sca.common.http.HTTPCacheContext; +import org.apache.tuscany.sca.common.http.HTTPContentTypeMapper; +import org.apache.tuscany.sca.invocation.Invoker; +import org.apache.tuscany.sca.invocation.Message; +import org.apache.tuscany.sca.invocation.MessageFactory; + +/** + * Servlet responsible for dispatching HTTP requests to the + * target component implementation. + * + * @version $Rev$ $Date$ + */ +public class HTTPBindingListenerServlet extends HttpServlet { + private static final long serialVersionUID = 2865466417329430610L; + + transient private Binding binding; + + private MessageFactory messageFactory; + private Invoker getInvoker; + private Invoker conditionalGetInvoker; + private Invoker putInvoker; + private Invoker conditionalPutInvoker; + private Invoker postInvoker; + private Invoker conditionalPostInvoker; + private Invoker deleteInvoker; + private Invoker conditionalDeleteInvoker; + + /** + * Constructs a new HTTPServiceListenerServlet. + */ + public HTTPBindingListenerServlet(Binding binding, MessageFactory messageFactory) { + this.binding = binding; + this.messageFactory = messageFactory; + } + + + @Override + protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + super.service(request, response); + } + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + // Get the request path + String pathInfo = request.getPathInfo(); + if (pathInfo == null || pathInfo.length() == 0) { + // Redirect to a URL ending with / to make relative hrefs work + // relative to the served resource. + response.sendRedirect(request.getRequestURL().append('/').toString()); + return; + } + String path = URLDecoder.decode(pathInfo, "UTF-8"); + + // Invoke the get operation on the service implementation + Message requestMessage = messageFactory.createMessage(); + + String id = path.substring(1); + + Message responseMessage = null; + HTTPCacheContext cacheContext = null; + try { + cacheContext = HTTPCacheContext.createCacheContextFromRequest(request); + } catch (ParseException e) { + } + + // Route message based on availability of cache info and cache methods + if (( cacheContext != null ) && (cacheContext.isEnabled()) && (conditionalGetInvoker != null )) { + requestMessage.setBody(new Object[] {id, cacheContext}); + responseMessage = conditionalGetInvoker.invoke(requestMessage); + } else { + requestMessage.setBody(new Object[] {id}); + responseMessage = getInvoker.invoke(requestMessage); + } + if (responseMessage.isFault()) { + Object body = responseMessage.getBody(); + + int index = -1; + if ( -1 < (index = body.getClass().getName().indexOf( "NotModifiedException")) ) { + if ( index > -1 ) + response.sendError( HttpServletResponse.SC_NOT_MODIFIED, body.toString().substring( index )); + else + response.sendError( HttpServletResponse.SC_NOT_MODIFIED ); + return; + } else if ( -1 < (index = body.getClass().getName().indexOf( "PreconditionFailedException")) ) { + if ( index > -1 ) + response.sendError( HttpServletResponse.SC_PRECONDITION_FAILED, body.toString().substring( index )); + else + response.sendError( HttpServletResponse.SC_PRECONDITION_FAILED ); + return; + } + + throw new ServletException((Throwable)responseMessage.getBody()); + } + + if(response.getContentType() == null || response.getContentType().length() == 0){ + // Calculate content-type based on extension + String contentType = HTTPContentTypeMapper.getContentType(id); + if(contentType != null && contentType.length() >0) { + response.setContentType(contentType); + } + } + + // Write the response from the service implementation to the response + // output stream + InputStream is = (InputStream)responseMessage.getBody(); + OutputStream os = response.getOutputStream(); + byte[] buffer = new byte[2048]; + for (;;) { + int n = is.read(buffer); + if (n <= 0) + break; + os.write(buffer, 0, n); + } + os.flush(); + os.close(); + } + + @Override + protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + // Get the request path + String path = URLDecoder.decode(request.getRequestURI().substring(request.getServletPath().length()), "UTF-8"); + if (path.length() ==0) { + // Redirect to a URL ending with / to make relative hrefs work + // relative to the served resource. + response.sendRedirect(request.getRequestURL().append('/').toString()); + return; + } + + // Invoke the get operation on the service implementation + Message requestMessage = messageFactory.createMessage(); + String id = path.substring(1); + + Message responseMessage = null; + HTTPCacheContext cacheContext = null; + try { + cacheContext = HTTPCacheContext.createCacheContextFromRequest(request); + } catch (ParseException e) { + } + + // Route message based on availability of cache info and cache methods + if (( cacheContext != null ) && (cacheContext.isEnabled()) && (conditionalDeleteInvoker != null )) { + requestMessage.setBody(new Object[] {id, cacheContext}); + responseMessage = conditionalDeleteInvoker.invoke(requestMessage); + } else { + requestMessage.setBody(new Object[] {id}); + responseMessage = deleteInvoker.invoke(requestMessage); + } + if (responseMessage.isFault()) { + Object body = responseMessage.getBody(); + + int index = -1; + if ( -1 < (index = body.getClass().getName().indexOf( "NotModifiedException")) ) { + if ( index > -1 ) + response.sendError( HttpServletResponse.SC_NOT_MODIFIED, body.toString().substring( index )); + else + response.sendError( HttpServletResponse.SC_NOT_MODIFIED ); + return; + } else if ( -1 < (index = body.getClass().getName().indexOf( "PreconditionFailedException")) ) { + if ( index > -1 ) + response.sendError( HttpServletResponse.SC_PRECONDITION_FAILED, body.toString().substring( index )); + else + response.sendError( HttpServletResponse.SC_PRECONDITION_FAILED ); + return; + } + + throw new ServletException((Throwable)responseMessage.getBody()); + } + + // Write the response from the service implementation to the response + // output stream + InputStream is = (InputStream)responseMessage.getBody(); + OutputStream os = response.getOutputStream(); + byte[] buffer = new byte[2048]; + for (;;) { + int n = is.read(buffer); + if (n <= 0) + break; + os.write(buffer, 0, n); + } + os.flush(); + os.close(); + } + + @Override + protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + // Get the request path + String path = URLDecoder.decode(request.getRequestURI().substring(request.getServletPath().length()), "UTF-8"); + if (path.length() ==0) { + // Redirect to a URL ending with / to make relative hrefs work + // relative to the served resource. + response.sendRedirect(request.getRequestURL().append('/').toString()); + return; + } + + // Invoke the get operation on the service implementation + Message requestMessage = messageFactory.createMessage(); + String id = path.substring(1); + + Message responseMessage = null; + HTTPCacheContext cacheContext = null; + try { + cacheContext = HTTPCacheContext.createCacheContextFromRequest(request); + } catch (ParseException e) { + } + + // Route message based on availability of cache info and cache methods + if (( cacheContext != null ) && (cacheContext.isEnabled()) && (conditionalPutInvoker != null )) { + requestMessage.setBody(new Object[] {id, cacheContext}); + responseMessage = conditionalPutInvoker.invoke(requestMessage); + } else { + requestMessage.setBody(new Object[] {id}); + responseMessage = putInvoker.invoke(requestMessage); + } + if (responseMessage.isFault()) { + Object body = responseMessage.getBody(); + + int index = -1; + if ( -1 < (index = body.getClass().getName().indexOf( "NotModifiedException")) ) { + if ( index > -1 ) + response.sendError( HttpServletResponse.SC_NOT_MODIFIED, body.toString().substring( index )); + else + response.sendError( HttpServletResponse.SC_NOT_MODIFIED ); + return; + } else if ( -1 < (index = body.getClass().getName().indexOf( "PreconditionFailedException")) ) { + if ( index > -1 ) + response.sendError( HttpServletResponse.SC_PRECONDITION_FAILED, body.toString().substring( index )); + else + response.sendError( HttpServletResponse.SC_PRECONDITION_FAILED ); + return; + } + + throw new ServletException((Throwable)responseMessage.getBody()); + } + + // Write the response from the service implementation to the response + // output stream + InputStream is = (InputStream)responseMessage.getBody(); + OutputStream os = response.getOutputStream(); + byte[] buffer = new byte[2048]; + for (;;) { + int n = is.read(buffer); + if (n <= 0) + break; + os.write(buffer, 0, n); + } + os.flush(); + os.close(); + } + + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + // Get the request path + String path = URLDecoder.decode(request.getRequestURI().substring(request.getServletPath().length()), "UTF-8"); + if (path.length() ==0) { + // Redirect to a URL ending with / to make relative hrefs work + // relative to the served resource. + response.sendRedirect(request.getRequestURL().append('/').toString()); + return; + } + + // Invoke the get operation on the service implementation + Message requestMessage = messageFactory.createMessage(); + // String id = path.substring(1); + + Message responseMessage = null; + HTTPCacheContext cacheContext = null; + try { + cacheContext = HTTPCacheContext.createCacheContextFromRequest(request); + } catch (ParseException e) { + } + + // Route message based on availability of cache info and cache methods + if (( cacheContext != null ) && (cacheContext.isEnabled()) && (conditionalPostInvoker != null )) { + requestMessage.setBody(new Object[] {cacheContext}); + responseMessage = conditionalPostInvoker.invoke(requestMessage); + } else { + requestMessage.setBody(new Object[] {}); + responseMessage = postInvoker.invoke(requestMessage); + } + if (responseMessage.isFault()) { + Object body = responseMessage.getBody(); + + int index = -1; + if ( -1 < (index = body.getClass().getName().indexOf( "NotModifiedException")) ) { + if ( index > -1 ) + response.sendError( HttpServletResponse.SC_NOT_MODIFIED, body.toString().substring( index )); + else + response.sendError( HttpServletResponse.SC_NOT_MODIFIED ); + return; + } else if ( -1 < (index = body.getClass().getName().indexOf( "PreconditionFailedException")) ) { + if ( index > -1 ) + response.sendError( HttpServletResponse.SC_PRECONDITION_FAILED, body.toString().substring( index )); + else + response.sendError( HttpServletResponse.SC_PRECONDITION_FAILED ); + return; + } + + throw new ServletException((Throwable)responseMessage.getBody()); + } + + + // Test if the ETag and LastModified are returned as a cache context. + Object body = responseMessage.getBody(); + if ( body.getClass() == HTTPCacheContext.class ) { + // Transfer to header if so. + HTTPCacheContext cc = (HTTPCacheContext)responseMessage.getBody(); + if (( cc != null ) && ( cc.isEnabled() )) { + String eTag = cc.getETag(); + if ( eTag != null ) + response.setHeader( "ETag", cc.getETag() ); + String lastModified = cc.getLastModified(); + if ( lastModified != null) + response.setHeader( "LastModified", cc.getLastModified() ); + } + } + } + + /** + * @return the getInvoker + */ + public Invoker getGetInvoker() { + return getInvoker; + } + + /** + * @param getInvoker the getInvoker to set + */ + public void setGetInvoker(Invoker getInvoker) { + this.getInvoker = getInvoker; + } + + /** + * @return the conditionalGetInvoker + */ + public Invoker getConditionalGetInvoker() { + return conditionalGetInvoker; + } + + /** + * @param conditionalGetInvoker the conditionalGetInvoker to set + */ + public void setConditionalGetInvoker(Invoker conditionalGetInvoker) { + this.conditionalGetInvoker = conditionalGetInvoker; + } + + /** + * @return the putInvoker + */ + public Invoker getPutInvoker() { + return putInvoker; + } + + /** + * @param putInvoker the putInvoker to set + */ + public void setPutInvoker(Invoker putInvoker) { + this.putInvoker = putInvoker; + } + + /** + * @return the conditionalPutInvoker + */ + public Invoker getConditionalPutInvoker() { + return conditionalPutInvoker; + } + + /** + * @param conditionalPutInvoker the conditionalPutInvoker to set + */ + public void setConditionalPutInvoker(Invoker conditionalPutInvoker) { + this.conditionalPutInvoker = conditionalPutInvoker; + } + + /** + * @return the postInvoker + */ + public Invoker getPostInvoker() { + return postInvoker; + } + + /** + * @param postInvoker the postInvoker to set + */ + public void setPostInvoker(Invoker postInvoker) { + this.postInvoker = postInvoker; + } + + /** + * @return the conditionalPostInvoker + */ + public Invoker getConditionalPostInvoker() { + return conditionalPostInvoker; + } + + /** + * @param conditionalPostInvoker the conditionalPostInvoker to set + */ + public void setConditionalPostInvoker(Invoker conditionalPostInvoker) { + this.conditionalPostInvoker = conditionalPostInvoker; + } + + /** + * @return the deleteInvoker + */ + public Invoker getDeleteInvoker() { + return deleteInvoker; + } + + /** + * @param deleteInvoker the deleteInvoker to set + */ + public void setDeleteInvoker(Invoker deleteInvoker) { + this.deleteInvoker = deleteInvoker; + } + + /** + * @return the conditionalDeleteInvoker + */ + public Invoker getConditionalDeleteInvoker() { + return conditionalDeleteInvoker; + } + + /** + * @param conditionalDeleteInvoker the conditionalDeleteInvoker to set + */ + public void setConditionalDeleteInvoker(Invoker conditionalDeleteInvoker) { + this.conditionalDeleteInvoker = conditionalDeleteInvoker; + } +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingProviderFactory.java b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingProviderFactory.java new file mode 100644 index 0000000000..118a2c3bc4 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingProviderFactory.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.tuscany.sca.binding.http.provider; + +import org.apache.tuscany.sca.binding.http.HTTPBinding; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; +import org.apache.tuscany.sca.host.http.ServletHost; +import org.apache.tuscany.sca.host.http.ServletHostHelper; +import org.apache.tuscany.sca.invocation.MessageFactory; +import org.apache.tuscany.sca.provider.BindingProviderFactory; +import org.apache.tuscany.sca.provider.ReferenceBindingProvider; +import org.apache.tuscany.sca.provider.ServiceBindingProvider; +import org.apache.tuscany.sca.runtime.RuntimeEndpoint; +import org.apache.tuscany.sca.runtime.RuntimeEndpointReference; + + +/** + * Factory for HTTP binding providers. + * + * @version $Rev$ $Date$ + */ +public class HTTPBindingProviderFactory implements BindingProviderFactory { + private ExtensionPointRegistry extensionPoints; + private MessageFactory messageFactory; + private ServletHost servletHost; + + public HTTPBindingProviderFactory(ExtensionPointRegistry extensionPoints) { + this.extensionPoints = extensionPoints; + this.servletHost = ServletHostHelper.getServletHost(extensionPoints); + FactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); + messageFactory = modelFactories.getFactory(MessageFactory.class); + } + + public ReferenceBindingProvider createReferenceBindingProvider(RuntimeEndpointReference endpointReference) { + // Binding HTTP is currently NOT supporting References + return null; + } + + public ServiceBindingProvider createServiceBindingProvider(RuntimeEndpoint endpoint) { + return new HTTPServiceBindingProvider(endpoint, extensionPoints, messageFactory, servletHost); + } + + public Class getModelType() { + return HTTPBinding.class; + } +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingServiceServlet.java b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingServiceServlet.java new file mode 100644 index 0000000000..686032571e --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingServiceServlet.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.tuscany.sca.binding.http.provider; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.tuscany.sca.invocation.Message; +import org.apache.tuscany.sca.invocation.MessageFactory; +import org.apache.tuscany.sca.runtime.RuntimeEndpoint; + +public class HTTPBindingServiceServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + + protected transient MessageFactory messageFactory; + protected transient RuntimeEndpoint wire; + + public HTTPBindingServiceServlet(RuntimeEndpoint wire, MessageFactory messageFactory) { + this.wire = wire; + this.messageFactory = messageFactory; + } + + @Override + protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + HTTPContext bindingContext = new HTTPContext(); + bindingContext.setRequest(request); + bindingContext.setResponse(response); + Message msg = messageFactory.createMessage(); + msg.setBindingContext(bindingContext); + wire.invoke(msg); + } +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPContext.java b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPContext.java new file mode 100644 index 0000000000..0a49823f06 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPContext.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.tuscany.sca.binding.http.provider; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * Holder to pass servlet request and response between the Inteceptors + */ +public class HTTPContext { + + private HttpServletRequest request; + private HttpServletResponse response; + + public HttpServletRequest getRequest() { + return request; + } + public void setRequest(HttpServletRequest request) { + this.request = request; + } + public HttpServletResponse getResponse() { + return response; + } + public void setResponse(HttpServletResponse response) { + this.response = response; + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceBindingProvider.java b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceBindingProvider.java new file mode 100644 index 0000000000..e123c28e02 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceBindingProvider.java @@ -0,0 +1,226 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.tuscany.sca.binding.http.provider; + +import javax.servlet.Servlet; + +import org.apache.tuscany.sca.binding.http.HTTPBinding; +import org.apache.tuscany.sca.binding.http.HTTPDefaultOperationSelector; +import org.apache.tuscany.sca.binding.http.HTTPDefaultWireFormat; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.host.http.ServletHost; +import org.apache.tuscany.sca.interfacedef.InterfaceContract; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.invocation.InvocationChain; +import org.apache.tuscany.sca.invocation.Invoker; +import org.apache.tuscany.sca.invocation.MessageFactory; +import org.apache.tuscany.sca.invocation.Phase; +import org.apache.tuscany.sca.provider.EndpointProvider; +import org.apache.tuscany.sca.provider.OperationSelectorProvider; +import org.apache.tuscany.sca.provider.OperationSelectorProviderFactory; +import org.apache.tuscany.sca.provider.ProviderFactoryExtensionPoint; +import org.apache.tuscany.sca.provider.WireFormatProvider; +import org.apache.tuscany.sca.provider.WireFormatProviderFactory; +import org.apache.tuscany.sca.runtime.RuntimeEndpoint; + +/** + * Implementation of an HTTP binding provider. + * + * @version $Rev$ $Date$ + */ +public class HTTPServiceBindingProvider implements EndpointProvider { + private ExtensionPointRegistry extensionPoints; + + private RuntimeEndpoint endpoint; + private HTTPBinding binding; + private MessageFactory messageFactory; + private OperationSelectorProvider osProvider; + private WireFormatProvider wfProvider; + private ServletHost servletHost; + private String servletMapping; + private InterfaceContract interfaceContract; + private boolean widget; + + private HTTPBindingListenerServlet bindingListenerServlet; + + public HTTPServiceBindingProvider(RuntimeEndpoint endpoint, + ExtensionPointRegistry extensionPoints, + MessageFactory messageFactory, + ServletHost servletHost) { + + this.endpoint = endpoint; + this.binding = (HTTPBinding)endpoint.getBinding(); + this.widget = "Widget".equals(binding.getName()); + + this.extensionPoints = extensionPoints; + this.messageFactory = messageFactory; + this.servletHost = servletHost; + + if (binding.getOperationSelector() == null && !widget) { + binding.setOperationSelector(new HTTPDefaultOperationSelector()); + } + if (binding.getRequestWireFormat() == null && !widget) { + binding.setRequestWireFormat(new HTTPDefaultWireFormat()); + } + if (binding.getResponseWireFormat() == null && !widget) { + binding.setResponseWireFormat(new HTTPDefaultWireFormat()); + } + + ProviderFactoryExtensionPoint providerFactories = extensionPoints.getExtensionPoint(ProviderFactoryExtensionPoint.class); + + if (binding.getOperationSelector() != null) { + // Configure the interceptors for operation selection + OperationSelectorProviderFactory osProviderFactory = (OperationSelectorProviderFactory) providerFactories.getProviderFactory(binding.getOperationSelector().getClass()); + if (osProviderFactory != null) { + this.osProvider = osProviderFactory.createServiceOperationSelectorProvider(endpoint); + } + } + + if (binding.getRequestWireFormat() != null && binding.getResponseWireFormat() != null) { + // Configure the interceptors for wire format + WireFormatProviderFactory wfProviderFactory = (WireFormatProviderFactory) providerFactories.getProviderFactory(binding.getRequestWireFormat().getClass()); + if (wfProviderFactory != null) { + this.wfProvider = wfProviderFactory.createServiceWireFormatProvider(endpoint); + } + } + + //clone the service contract to avoid databinding issues + try { + interfaceContract = (InterfaceContract)endpoint.getComponentServiceInterfaceContract().clone(); + + // configure data binding + if (this.wfProvider != null) { + wfProvider.configureWireFormatInterfaceContract(interfaceContract); + } + } catch(CloneNotSupportedException e) { + // shouldn't happen + } + + servletMapping = binding.getURI(); + if (!servletMapping.endsWith("/")) { + servletMapping += "/"; + } + if (!servletMapping.endsWith("*")) { + servletMapping += "*"; + } + } + + public void start() { + if (widget) { + start1x(); + } else { + servletHost.addServletMapping(servletMapping, new HTTPBindingServiceServlet(endpoint, messageFactory)); + } + } + + public void start1x() { + // Get the invokers for the supported operations + Servlet servlet = null; + bindingListenerServlet = new HTTPBindingListenerServlet(binding, messageFactory ); + for (InvocationChain invocationChain : endpoint.getInvocationChains()) { + Operation operation = invocationChain.getTargetOperation(); + String operationName = operation.getName(); + if (operationName.equals("get")) { + Invoker getInvoker = invocationChain.getHeadInvoker(); + bindingListenerServlet.setGetInvoker(getInvoker); + servlet = bindingListenerServlet; + } else if (operationName.equals("conditionalGet")) { + Invoker conditionalGetInvoker = invocationChain.getHeadInvoker(); + bindingListenerServlet.setConditionalGetInvoker(conditionalGetInvoker); + servlet = bindingListenerServlet; + } else if (operationName.equals("delete")) { + Invoker deleteInvoker = invocationChain.getHeadInvoker(); + bindingListenerServlet.setDeleteInvoker(deleteInvoker); + servlet = bindingListenerServlet; + } else if (operationName.equals("conditionalDelete")) { + Invoker conditionalDeleteInvoker = invocationChain.getHeadInvoker(); + bindingListenerServlet.setConditionalDeleteInvoker(conditionalDeleteInvoker); + servlet = bindingListenerServlet; + } else if (operationName.equals("put")) { + Invoker putInvoker = invocationChain.getHeadInvoker(); + bindingListenerServlet.setPutInvoker(putInvoker); + servlet = bindingListenerServlet; + } else if (operationName.equals("conditionalPut")) { + Invoker conditionalPutInvoker = invocationChain.getHeadInvoker(); + bindingListenerServlet.setConditionalPutInvoker(conditionalPutInvoker); + servlet = bindingListenerServlet; + } else if (operationName.equals("post")) { + Invoker postInvoker = invocationChain.getHeadInvoker(); + bindingListenerServlet.setPostInvoker(postInvoker); + servlet = bindingListenerServlet; + } else if (operationName.equals("conditionalPost")) { + Invoker conditionalPostInvoker = invocationChain.getHeadInvoker(); + bindingListenerServlet.setConditionalPostInvoker(conditionalPostInvoker); + servlet = bindingListenerServlet; + } else if (operationName.equals("service")) { + Invoker serviceInvoker = invocationChain.getHeadInvoker(); +// servlet = new HTTPServiceListenerServlet(binding, serviceInvoker, messageFactory); + break; + } + } + if (servlet == null) { + throw new IllegalStateException("No get or service method found on the service"); + } + + // Create our HTTP service listener Servlet and register it with the + // Servlet host + servletMapping = binding.getURI(); + if (!servletMapping.endsWith("/")) { + servletMapping += "/"; + } + if (!servletMapping.endsWith("*")) { + servletMapping += "*"; + } + + servletHost.addServletMapping(servletMapping, servlet); + } + + public void stop() { + servletHost.removeServletMapping(servletMapping); + } + + public InterfaceContract getBindingInterfaceContract() { + return interfaceContract; + } + + public boolean supportsOneWayInvocation() { + return false; + } + + /** + * Add specific http interceptor to invocation chain + */ + public void configure() { + + if (widget) return; + + InvocationChain bindingChain = endpoint.getBindingInvocationChain(); + + if(osProvider != null) { + bindingChain.addInterceptor(Phase.SERVICE_BINDING_OPERATION_SELECTOR, osProvider.createInterceptor()); + } + + if (wfProvider != null) { + bindingChain.addInterceptor(Phase.SERVICE_BINDING_WIREFORMAT, wfProvider.createInterceptor()); + } + + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.BindingProviderFactory b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.BindingProviderFactory new file mode 100644 index 0000000000..48678871eb --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.BindingProviderFactory @@ -0,0 +1,20 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + +# Implementation class for the binding extension +org.apache.tuscany.sca.binding.http.provider.HTTPBindingProviderFactory;model=org.apache.tuscany.sca.binding.http.HTTPBinding,ranking=100 + diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.OperationSelectorProviderFactory b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.OperationSelectorProviderFactory new file mode 100644 index 0000000000..8d9b98604c --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.OperationSelectorProviderFactory @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + +org.apache.tuscany.sca.binding.http.format.HTTPDefaultOperationSelectorProviderFactory;model=org.apache.tuscany.sca.binding.http.HTTPDefaultOperationSelector diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.WireFormatProviderFactory b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.WireFormatProviderFactory new file mode 100644 index 0000000000..88cd59bb13 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.WireFormatProviderFactory @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + +org.apache.tuscany.sca.binding.http.format.HTTPDefaultWireFormatProviderFactory;model=org.apache.tuscany.sca.binding.http.HTTPDefaultWireFormat +org.apache.tuscany.sca.binding.http.format.HTTPXMLWireFormatProviderFactory;model=org.apache.tuscany.sca.binding.http.HTTPXMLWireFormat diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/BeanA.java b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/BeanA.java new file mode 100644 index 0000000000..2c33895f67 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/BeanA.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.tuscany.sca.binding.http; + +public class BeanA { + + protected Boolean b; + protected String s; + protected int x; + protected Integer y; + + public Boolean getB() { + return b; + } + + public void setB(Boolean b) { + this.b = b; + } + + public String getS() { + return s; + } + + public void setS(String s) { + this.s = s; + } + + public int getX() { + return x; + } + + public void setX(int x) { + this.x = x; + } + + public Integer getY() { + return y; + } + + public void setY(Integer y) { + this.y = y; + } +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/ComplexStuff.java b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/ComplexStuff.java new file mode 100644 index 0000000000..cf0d457317 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/ComplexStuff.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.tuscany.sca.binding.http; + +import org.oasisopen.sca.annotation.Remotable; + +@Remotable +public interface ComplexStuff { + BeanA echoBeanA(BeanA bean); + String multiParams(int x, String s, Boolean b); + String noArgs(); + void voidReturn(); + String checkedException() throws SomeException; + String runtimeException(); +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/ComplexStuffImpl.java b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/ComplexStuffImpl.java new file mode 100644 index 0000000000..9395024e5b --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/ComplexStuffImpl.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.tuscany.sca.binding.http; + +public class ComplexStuffImpl implements ComplexStuff { + + @Override + public BeanA echoBeanA(BeanA bean) { + return bean; + } + + @Override + public String multiParams(int x, String s, Boolean b) { + return x + s + b; + } + + @Override + public String noArgs() { + return "noArgs"; + } + + @Override + public void voidReturn() { + } + + @Override + public String checkedException() throws SomeException { + throw new SomeException("some msg"); + } + + @Override + public String runtimeException() { + throw new RuntimeException("bang"); + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/ComplexStuffTestCase.java b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/ComplexStuffTestCase.java new file mode 100644 index 0000000000..704a24554b --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/ComplexStuffTestCase.java @@ -0,0 +1,129 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ +package org.apache.tuscany.sca.binding.http; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; + +import junit.framework.Assert; + +import org.apache.tuscany.sca.node.Node; +import org.apache.tuscany.sca.node.NodeFactory; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * HTTP binding unit tests for Helloworld service. + */ +public class ComplexStuffTestCase { + + private static Node node; + + @BeforeClass + public static void setUp() throws Exception { + node = NodeFactory.newInstance().createNode("complex.composite", new String[] {"target/test-classes"}); + node.start(); + } + + @AfterClass + public static void tearDown() throws Exception { + if (node != null) { + node.stop(); + } + } + + @Test + public void testGet() throws Exception { + URL url = new URL("http://localhost:8080/ComplexComponent/ComplexStuff/multiParams?x=1&s=petra&b=true"); + InputStream is = url.openStream(); + Assert.assertEquals("\"1petratrue\"", read(is)); + } + + @Test + public void testNoArgs() throws Exception { + URL url = new URL("http://localhost:8080/ComplexComponent/ComplexStuff/noArgs"); + InputStream is = url.openStream(); + Assert.assertEquals("\"noArgs\"", read(is)); + } + + @Test + public void testEchoBean() throws Exception { + URL url = new URL("http://localhost:8080/ComplexComponent/ComplexStuff/echoBeanA?x={\"s\":\"petra\",\"b\":true,\"y\":42,\"x\":1}"); + InputStream is = url.openStream(); + String result = read(is); + Assert.assertTrue(result.startsWith("{")); + Assert.assertTrue(result.contains("\"s\":\"petra\"")); + Assert.assertTrue(result.contains("\"b\":true")); + Assert.assertTrue(result.contains("\"y\":42")); + Assert.assertTrue(result.contains("\"x\":1")); + // Assert.assertEquals("{\"s\":\"petra\",\"b\":true,\"y\":42,\"x\":1}", read(is)); + } + + @Test + public void testVoidReturn() throws Exception { + URL url = new URL("http://localhost:8080/ComplexComponent/ComplexStuff/voidReturn"); + InputStream is = url.openStream(); + Assert.assertEquals("", read(is)); + } + + @Test + public void testCheckedException() throws Exception { + URL url = new URL("http://localhost:8080/ComplexComponent/ComplexStuff/checkedException"); + try { + InputStream is = url.openStream(); + Assert.fail(); + } catch (IOException e) { + // expected + // TODO: what should happen with checked exceptions? + } + } + + @Test + public void testRuntimeException() throws Exception { + URL url = new URL("http://localhost:8080/ComplexComponent/ComplexStuff/runtimeException"); + try { + InputStream is = url.openStream(); + Assert.fail(); + } catch (IOException e) { + Assert.assertTrue(e.getMessage().contains("HTTP response code: 500")); + } + } + + private static String read(InputStream is) throws IOException { + BufferedReader reader = null; + try { + reader = new BufferedReader(new InputStreamReader(is)); + StringBuffer sb = new StringBuffer(); + String str; + while ((str = reader.readLine()) != null) { + sb.append(str); + } + return sb.toString(); + } finally { + if (reader != null) { + reader.close(); + } + } + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/Helloworld.java b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/Helloworld.java new file mode 100644 index 0000000000..17a0b28fdb --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/Helloworld.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ +package org.apache.tuscany.sca.binding.http; + +import org.oasisopen.sca.annotation.Remotable; + +@Remotable +public interface Helloworld { + String sayHello(String name); +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/HelloworldImpl.java b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/HelloworldImpl.java new file mode 100644 index 0000000000..e245f607f1 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/HelloworldImpl.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ +package org.apache.tuscany.sca.binding.http; + +public class HelloworldImpl implements Helloworld { + + @Override + public String sayHello(String name) { + return "Hello " + name; + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/HelloworldTestCase.java b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/HelloworldTestCase.java new file mode 100644 index 0000000000..89598b91c7 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/HelloworldTestCase.java @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ +package org.apache.tuscany.sca.binding.http; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; + +import junit.framework.Assert; + +import org.apache.tuscany.sca.node.Node; +import org.apache.tuscany.sca.node.NodeFactory; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * HTTP binding unit tests for Helloworld service. + */ +public class HelloworldTestCase { + + private static Node node; + + @BeforeClass + public static void setUp() throws Exception { + node = NodeFactory.newInstance().createNode("helloworld.composite", new String[] {"target/test-classes"}); + node.start(); + } + + @AfterClass + public static void tearDown() throws Exception { + if (node != null) { + node.stop(); + } + } + + @Test + public void testGet() throws Exception { + URL url = new URL("http://localhost:8080/HelloworldComponent/Helloworld/sayHello?name=Petra"); + InputStream is = url.openStream(); + Assert.assertEquals("\"Hello Petra\"", read(is)); + } + + @Test + public void testGetArg0() throws Exception { + URL url = new URL("http://localhost:8080/HelloworldComponent/Helloworld/sayHello?arg0=Petra"); + InputStream is = url.openStream(); + Assert.assertEquals("\"Hello Petra\"", read(is)); + } + + @Test + public void testXml() throws Exception { + URL url = new URL("http://localhost:8080/HelloworldXmlComponent/Helloworld/sayHello?arg0=Petra"); + InputStream is = url.openStream(); + Assert.assertTrue(read(is).endsWith(">Hello Petra")); + } + + private static String read(InputStream is) throws IOException { + BufferedReader reader = null; + try { + reader = new BufferedReader(new InputStreamReader(is)); + StringBuffer sb = new StringBuffer(); + String str; + while ((str = reader.readLine()) != null) { + sb.append(str); + } + return sb.toString(); + } finally { + if (reader != null) { + reader.close(); + } + } + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/SomeException.java b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/SomeException.java new file mode 100644 index 0000000000..f4ffd19c9c --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/java/org/apache/tuscany/sca/binding/http/SomeException.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +package org.apache.tuscany.sca.binding.http; + +public class SomeException extends Exception { + private static final long serialVersionUID = 1L; + + public SomeException(String msg) { + super(msg); + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/resources/complex.composite b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/resources/complex.composite new file mode 100644 index 0000000000..7f4cc64fe2 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/resources/complex.composite @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/resources/helloworld.composite b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/resources/helloworld.composite new file mode 100644 index 0000000000..7497cfcbac --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/binding-http-runtime/src/test/resources/helloworld.composite @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3