From d22e494c6431f00f231345a7037ee235b5aef294 Mon Sep 17 00:00:00 2001 From: lresende Date: Mon, 11 May 2009 23:13:20 +0000 Subject: Merging changes from binding-http-new that introduces support to wire format and operation selector to the main binding-http. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@773719 13f79535-47bb-0310-9956-ffa450edef68 --- .../http/provider/HTTPBindingListenerServlet.java | 1032 ++++++++++---------- .../http/provider/HTTPBindingProviderFactory.java | 5 +- .../http/provider/HTTPRRBListenerServlet.java | 102 ++ .../http/provider/HTTPServiceBindingProvider.java | 90 +- 4 files changed, 704 insertions(+), 525 deletions(-) create mode 100644 branches/sca-java-1.x/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPRRBListenerServlet.java (limited to 'branches/sca-java-1.x/modules/binding-http-runtime') diff --git a/branches/sca-java-1.x/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingListenerServlet.java b/branches/sca-java-1.x/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingListenerServlet.java index 41be041621..12f1143e3a 100644 --- a/branches/sca-java-1.x/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingListenerServlet.java +++ b/branches/sca-java-1.x/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingListenerServlet.java @@ -1,516 +1,516 @@ -/* - * 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 java.util.List; - -import javax.servlet.ServletException; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.xml.namespace.QName; - -import org.apache.tuscany.sca.assembly.Binding; -import org.apache.tuscany.sca.binding.http.HTTPCacheContext; -import org.apache.tuscany.sca.binding.http.util.HTTPHeadersParser; -import org.apache.tuscany.sca.invocation.Invoker; -import org.apache.tuscany.sca.invocation.Message; -import org.apache.tuscany.sca.invocation.MessageFactory; -import org.apache.tuscany.sca.policy.Intent; -import org.apache.tuscany.sca.policy.PolicySet; -import org.apache.tuscany.sca.policy.PolicySetAttachPoint; -import org.apache.tuscany.sca.policy.authentication.basic.BasicAuthenticationPolicy; - -/** - * 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; - - private static final QName AUTEHTICATION_INTENT = new QName("http://www.osoa.org/xmlns/sca/1.0","authentication"); - - transient private Binding binding; - - transient private boolean requiresAuthentication = false; - transient private BasicAuthenticationPolicy basicAuthenticationPolicy = null; - - 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; - - - // find out which policies are active - if (binding instanceof PolicySetAttachPoint) { - List intents = ((PolicySetAttachPoint)binding).getRequiredIntents(); - for(Intent intent : intents) { - if(intent.getName().equals(AUTEHTICATION_INTENT)) { - requiresAuthentication = true; - } - } - - - List policySets = ((PolicySetAttachPoint)binding).getApplicablePolicySets(); - for (PolicySet ps : policySets) { - for (Object p : ps.getPolicies()) { - if (BasicAuthenticationPolicy.class.isInstance(p)) { - basicAuthenticationPolicy = (BasicAuthenticationPolicy)p; - } else { - // etc. check for other types of policy being present - } - } - } - } - } - - - @Override - protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - - if(requiresAuthentication) { - if(! hasAuthorization(request, response)) { - response.setHeader("WWW-Authenticate", "BASIC realm=\"Tuscany\""); - response.sendError(HttpServletResponse.SC_UNAUTHORIZED); - } - } - - super.service(request, response); - } - - @Override - protected void doGet(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(); - - //store http headers to message - requestMessage.getHeaders().addAll(HTTPHeadersParser.getHeaders(request)); - - String id = path.substring(1); - - Message responseMessage = null; - HTTPCacheContext cacheContext = null; - try { - cacheContext = HTTPCacheContext.getCacheContextFromRequest(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()); - } - - // 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.getCacheContextFromRequest(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.getCacheContextFromRequest(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.getCacheContextFromRequest(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; - } - - - /** - * Utility Methods related to Policy - */ - - - private boolean hasAuthorization(HttpServletRequest request, ServletResponse response) { - boolean result = false; - if(request.getHeader("Authorization") != null) { - result = true; - } - - return result; - } - - -} +/* + * 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 java.util.List; + +import javax.servlet.ServletException; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.assembly.Binding; +import org.apache.tuscany.sca.binding.http.HTTPCacheContext; +import org.apache.tuscany.sca.binding.http.util.HTTPHeadersParser; +import org.apache.tuscany.sca.invocation.Invoker; +import org.apache.tuscany.sca.invocation.Message; +import org.apache.tuscany.sca.invocation.MessageFactory; +import org.apache.tuscany.sca.policy.Intent; +import org.apache.tuscany.sca.policy.PolicySet; +import org.apache.tuscany.sca.policy.PolicySetAttachPoint; +import org.apache.tuscany.sca.policy.authentication.basic.BasicAuthenticationPolicy; + +/** + * 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; + + private static final QName AUTEHTICATION_INTENT = new QName("http://www.osoa.org/xmlns/sca/1.0","authentication"); + + transient private Binding binding; + + transient private boolean requiresAuthentication = false; + transient private BasicAuthenticationPolicy basicAuthenticationPolicy = null; + + 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; + + + // find out which policies are active + if (binding instanceof PolicySetAttachPoint) { + List intents = ((PolicySetAttachPoint)binding).getRequiredIntents(); + for(Intent intent : intents) { + if(intent.getName().equals(AUTEHTICATION_INTENT)) { + requiresAuthentication = true; + } + } + + + List policySets = ((PolicySetAttachPoint)binding).getApplicablePolicySets(); + for (PolicySet ps : policySets) { + for (Object p : ps.getPolicies()) { + if (BasicAuthenticationPolicy.class.isInstance(p)) { + basicAuthenticationPolicy = (BasicAuthenticationPolicy)p; + } else { + // etc. check for other types of policy being present + } + } + } + } + } + + + @Override + protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + + if(requiresAuthentication) { + if(! hasAuthorization(request, response)) { + response.setHeader("WWW-Authenticate", "BASIC realm=\"Tuscany\""); + response.sendError(HttpServletResponse.SC_UNAUTHORIZED); + } + } + + super.service(request, response); + } + + @Override + protected void doGet(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(); + + //store http headers to message + requestMessage.getHeaders().addAll(HTTPHeadersParser.getHeaders(request)); + + String id = path.substring(1); + + Message responseMessage = null; + HTTPCacheContext cacheContext = null; + try { + cacheContext = HTTPCacheContext.getCacheContextFromRequest(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()); + } + + // 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.getCacheContextFromRequest(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.getCacheContextFromRequest(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.getCacheContextFromRequest(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; + } + + + /** + * Utility Methods related to Policy + */ + + + private boolean hasAuthorization(HttpServletRequest request, ServletResponse response) { + boolean result = false; + if(request.getHeader("Authorization") != null) { + result = true; + } + + return result; + } + + +} diff --git a/branches/sca-java-1.x/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingProviderFactory.java b/branches/sca-java-1.x/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingProviderFactory.java index fccd10f3cd..768636d478 100644 --- a/branches/sca-java-1.x/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingProviderFactory.java +++ b/branches/sca-java-1.x/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPBindingProviderFactory.java @@ -39,11 +39,12 @@ import org.apache.tuscany.sca.runtime.RuntimeComponentService; * @version $Rev$ $Date$ */ public class HTTPBindingProviderFactory implements BindingProviderFactory { - + private ExtensionPointRegistry extensionPoints; private MessageFactory messageFactory; private ServletHost servletHost; public HTTPBindingProviderFactory(ExtensionPointRegistry extensionPoints) { + this.extensionPoints = extensionPoints; ServletHostExtensionPoint servletHosts = extensionPoints.getExtensionPoint(ServletHostExtensionPoint.class); this.servletHost = servletHosts.getServletHosts().get(0); ModelFactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(ModelFactoryExtensionPoint.class); @@ -55,7 +56,7 @@ public class HTTPBindingProviderFactory implements BindingProviderFactory getModelType() { diff --git a/branches/sca-java-1.x/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPRRBListenerServlet.java b/branches/sca-java-1.x/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPRRBListenerServlet.java new file mode 100644 index 0000000000..605e2c6211 --- /dev/null +++ b/branches/sca-java-1.x/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPRRBListenerServlet.java @@ -0,0 +1,102 @@ +/* + * 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.BufferedReader; +import java.io.CharArrayWriter; +import java.io.IOException; +import java.io.InputStreamReader; + +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.binding.http.HTTPBindingContext; +import org.apache.tuscany.sca.invocation.Invoker; +import org.apache.tuscany.sca.invocation.Message; +import org.apache.tuscany.sca.invocation.MessageFactory; + +public class HTTPRRBListenerServlet extends HttpServlet { + + private static final long serialVersionUID = 6688524143716091739L; + + transient private Binding binding; + transient private Invoker bindingInvoker; + transient private MessageFactory messageFactory; + + /** + * Constructs a new HTTPServiceListenerServlet. + */ + public HTTPRRBListenerServlet(Binding binding, Invoker bindingInvoker, MessageFactory messageFactory) { + this.binding = binding; + this.bindingInvoker = bindingInvoker; + this.messageFactory = messageFactory; + } + + public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + + // Decode using the charset in the request if it exists otherwise + // use UTF-8 as this is what all browser implementations use. + // The JSON-RPC-Java JavaScript client is ASCII clean so it + // although here we can correctly handle data from other clients + // that do not escape non ASCII data + String charset = request.getCharacterEncoding(); + if (charset == null) { + charset = "UTF-8"; + } + BufferedReader in = new BufferedReader(new InputStreamReader(request.getInputStream(), charset)); + + // Read the request + CharArrayWriter data = new CharArrayWriter(); + char[] buf = new char[4096]; + int ret; + while ((ret = in.read(buf, 0, 4096)) != -1) { + data.write(buf, 0, ret); + } + + HTTPBindingContext bindingContext = new HTTPBindingContext(); + bindingContext.setHttpRequest(request); + bindingContext.setHttpResponse(response); + + // Dispatch the service interaction to the service invoker + Message requestMessage = messageFactory.createMessage(); + requestMessage.setBindingContext(bindingContext); + requestMessage.setBody(new Object[]{data}); + + Message responseMessage = bindingInvoker.invoke(requestMessage); + + // return response to client + if (responseMessage.isFault()) { + // Turn a fault into an exception + //throw new ServletException((Throwable)responseMessage.getBody()); + Throwable e = (Throwable)responseMessage.getBody(); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.toString()); + } else { + byte[] bout; + bout = responseMessage.getBody().toString().getBytes("UTF-8"); + response.getOutputStream().write(bout); + response.getOutputStream().flush(); + response.getOutputStream().close(); + } + } + +} diff --git a/branches/sca-java-1.x/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceBindingProvider.java b/branches/sca-java-1.x/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceBindingProvider.java index 6e01ac5f9f..3a3428268c 100644 --- a/branches/sca-java-1.x/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceBindingProvider.java +++ b/branches/sca-java-1.x/modules/binding-http-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPServiceBindingProvider.java @@ -25,6 +25,7 @@ import javax.servlet.Servlet; import javax.xml.namespace.QName; import org.apache.tuscany.sca.binding.http.HTTPBinding; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.host.http.SecurityContext; import org.apache.tuscany.sca.host.http.ServletHost; import org.apache.tuscany.sca.interfacedef.InterfaceContract; @@ -32,12 +33,18 @@ 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.policy.Intent; import org.apache.tuscany.sca.policy.PolicySet; import org.apache.tuscany.sca.policy.PolicySetAttachPoint; import org.apache.tuscany.sca.policy.authentication.AuthenticationConfigurationPolicy; import org.apache.tuscany.sca.policy.confidentiality.ConfidentialityPolicy; -import org.apache.tuscany.sca.provider.ServiceBindingProvider; +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.ServiceBindingProviderRRB; +import org.apache.tuscany.sca.provider.WireFormatProvider; +import org.apache.tuscany.sca.provider.WireFormatProviderFactory; import org.apache.tuscany.sca.runtime.RuntimeComponent; import org.apache.tuscany.sca.runtime.RuntimeComponentService; import org.apache.tuscany.sca.runtime.RuntimeWire; @@ -47,27 +54,74 @@ import org.apache.tuscany.sca.runtime.RuntimeWire; * * @version $Rev$ $Date$ */ -public class HTTPServiceBindingProvider implements ServiceBindingProvider { +public class HTTPServiceBindingProvider implements ServiceBindingProviderRRB { private static final QName AUTEHTICATION_INTENT = new QName("http://www.osoa.org/xmlns/sca/1.0","authentication"); private static final QName CONFIDENTIALITY_INTENT = new QName("http://www.osoa.org/xmlns/sca/1.0","confidentiality"); + private ExtensionPointRegistry extensionPoints; + + private RuntimeComponent component; private RuntimeComponentService service; + private InterfaceContract serviceContract; private HTTPBinding binding; private MessageFactory messageFactory; + private OperationSelectorProvider osProvider; + private WireFormatProvider wfProvider; + private ServletHost servletHost; private String servletMapping; private HTTPBindingListenerServlet bindingListenerServlet; public HTTPServiceBindingProvider(RuntimeComponent component, - RuntimeComponentService service, - HTTPBinding binding, - MessageFactory messageFactory, - ServletHost servletHost) { + RuntimeComponentService service, + HTTPBinding binding, + ExtensionPointRegistry extensionPoints, + MessageFactory messageFactory, + ServletHost servletHost) { + this.component = component; this.service = service; + this.binding = binding; + this.extensionPoints = extensionPoints; this.messageFactory = messageFactory; this.servletHost = servletHost; + + // retrieve operation selector and wire format service providers + + 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(component, service, binding); + } + } + + 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(component, service, binding); + } + } + + + + //clone the service contract to avoid databinding issues + try { + this.serviceContract = (InterfaceContract) service.getInterfaceContract().clone(); + + // configure data binding + if (this.wfProvider != null) { + wfProvider.configureWireFormatInterfaceContract(service.getInterfaceContract()); + } + } catch(CloneNotSupportedException e) { + this.serviceContract = service.getInterfaceContract(); + } + } public void start() { @@ -115,6 +169,10 @@ public class HTTPServiceBindingProvider implements ServiceBindingProvider { Invoker serviceInvoker = invocationChain.getHeadInvoker(); servlet = new HTTPServiceListenerServlet(binding, serviceInvoker, messageFactory); break; + } else if (binding.getOperationSelector() != null || binding.getRequestWireFormat() != null) { + Invoker bindingInvoker = wire.getBindingInvocationChain().getHeadInvoker(); + servlet = new HTTPRRBListenerServlet(binding, bindingInvoker, messageFactory); + break; } } if (servlet == null) { @@ -179,11 +237,29 @@ public class HTTPServiceBindingProvider implements ServiceBindingProvider { } public InterfaceContract getBindingInterfaceContract() { - return null; + return service.getInterfaceContract(); } public boolean supportsOneWayInvocation() { return false; } + + /** + * Add specific http interceptor to invocation chain + * @param runtimeWire + */ + public void configureBindingChain(RuntimeWire runtimeWire) { + + InvocationChain bindingChain = runtimeWire.getBindingInvocationChain(); + + if(osProvider != null) { + bindingChain.addInterceptor(Phase.SERVICE_BINDING_OPERATION_SELECTOR, osProvider.createInterceptor()); + } + + if (wfProvider != null) { + bindingChain.addInterceptor(Phase.SERVICE_BINDING_WIREFORMAT, wfProvider.createInterceptor()); + } + + } } -- cgit v1.2.3