All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.cxf.transport.http_osgi.OsgiServletController Maven / Gradle / Ivy

There is a newer version: 3.0.0-milestone2
Show newest version
/**
 * 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.cxf.transport.http_osgi;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.cxf.Bus;
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.helpers.HttpHeaderHelper;
import org.apache.cxf.message.ExchangeImpl;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageImpl;
import org.apache.cxf.resource.ResourceManager;
import org.apache.cxf.security.SecurityContext;
import org.apache.cxf.service.model.EndpointInfo;
import org.apache.cxf.service.model.OperationInfo;
import org.apache.cxf.transport.http.AbstractHTTPDestination;
import org.apache.cxf.transport.http.HTTPSession;
import org.apache.cxf.transport.https.SSLUtils;
import org.apache.cxf.transport.servlet.AbstractServletController;
import org.apache.cxf.transports.http.QueryHandler;
import org.apache.cxf.transports.http.QueryHandlerRegistry;
import org.apache.cxf.wsdl.http.AddressType;

public class OsgiServletController extends AbstractServletController {
    private static final Logger LOG = LogUtils.getL7dLogger(OsgiServlet.class);
      
    private OsgiServlet servlet;
    public OsgiServletController(OsgiServlet servlet) {
        super(servlet.getServletConfig());
        this.servlet = servlet;
    }

    private synchronized void updateDests(HttpServletRequest request) {
        if (disableAddressUpdates) {
            return;
        }
        String base = forcedBaseAddress == null ? getBaseURL(request) : forcedBaseAddress;

               
        Set paths = servlet.getTransport().getDestinationsPaths();
        for (String path : paths) {
            OsgiDestination d2 = servlet.getTransport().getDestinationForPath(path);
            String ad = d2.getEndpointInfo().getAddress();
            if (ad.equals(path)) {
                d2.getEndpointInfo().setAddress(base + path);
                if (d2.getEndpointInfo().getExtensor(AddressType.class) != null) {
                    d2.getEndpointInfo().getExtensor(AddressType.class).setLocation(base + path);
                }
            }
        }
    }

    public void invoke(HttpServletRequest request, HttpServletResponse res) throws ServletException {
        try {
            EndpointInfo ei = new EndpointInfo();
            String address = request.getPathInfo() == null ? "" : request.getPathInfo();

            ei.setAddress(address);
            OsgiDestination d = 
                (OsgiDestination)servlet.getTransport().getDestinationForPath(ei.getAddress());

            if (d == null) {
                if (!isHideServiceList && (request.getRequestURI().endsWith(serviceListRelativePath)
                    || request.getRequestURI().endsWith(serviceListRelativePath + "/"))
                    || StringUtils.isEmpty(request.getPathInfo())
                    || "/".equals(request.getPathInfo())) {
                    updateDests(request);
                    generateServiceList(request, res);
                } else {
                    d = checkRestfulRequest(request);
                    if (d == null || d.getMessageObserver() == null) {
                        LOG.warning("Can't find the the request for "
                                    + request.getRequestURL() + "'s Observer ");
                        generateNotFound(request, res);
                    }  else { // the request should be a restful service request
                        updateDests(request);
                        invokeDestination(request, res, d);
                    }
                }
            } else {
                ei = d.getEndpointInfo();
                Bus bus = d.getBus();
                ClassLoader orig = Thread.currentThread().getContextClassLoader();
                try {
                    ResourceManager manager = bus.getExtension(ResourceManager.class);
                    if (manager != null) {
                        ClassLoader loader = manager.resolveResource("", ClassLoader.class);
                        if (loader != null) {
                            //need to set the context classloader to the loader of the bundle
                            Thread.currentThread().setContextClassLoader(loader);
                        }
                    }
                    
                    if (null != request.getQueryString()
                        && request.getQueryString().length() > 0
                        && bus.getExtension(QueryHandlerRegistry.class) != null) {
    
                        String ctxUri = request.getPathInfo();
                        String baseUri = request.getRequestURL().toString()
                            + "?" + request.getQueryString();
                        // update the EndPoint Address with request url
                        if ("GET".equals(request.getMethod())) {
                            updateDests(request);
                        }
    
                        for (QueryHandler qh : bus.getExtension(QueryHandlerRegistry.class).getHandlers()) {
                            if (qh.isRecognizedQuery(baseUri, ctxUri, ei)) {
    
                                res.setContentType(qh.getResponseContentType(baseUri, ctxUri));
                                OutputStream out = res.getOutputStream();
                                try {
                                    qh.writeResponse(baseUri, ctxUri, ei, out);
                                    out.flush();
                                    return;
                                } catch (Exception e) {
                                    LOG.warning(qh.getClass().getName()
                                        + " Exception caught writing response: "
                                        + e.getMessage());
                                    throw new ServletException(e);
                                }
                            }
                        }
                    } else if ("/".equals(address) || address.length() == 0) {
                        updateDests(request);
                    }
                    invokeDestination(request, res, d);
                } finally {
                    Thread.currentThread().setContextClassLoader(orig);
                }
                
            }
        } catch (IOException e) {
            throw new ServletException(e);
        }
    }

    private OsgiDestination checkRestfulRequest(HttpServletRequest request) throws IOException {
        int len = -1;
        OsgiDestination ret = null;

        String address = request.getPathInfo() == null ? "" : request.getPathInfo();

        for (String path : servlet.getTransport().getDestinationsPaths()) {
            if ((address.equals(path) 
                || "/".equals(path)
                || (address.length() > path.length() 
                    && address.startsWith(path) && address.charAt(path.length()) == '/'))
                && path.length() > len) {
                ret = servlet.getTransport().getDestinationForPath(path);
                len = path.length();
            }
        }
        return ret;
    }

    protected void generateServiceList(HttpServletRequest request, HttpServletResponse response)
        throws IOException {        
        response.setContentType("text/html; charset=UTF-8");        
        
        response.getWriter().write("");
        response.getWriter().write("");
        if (serviceListStyleSheet != null) {
            response.getWriter().write(
                    "");
        } else {
            response.getWriter().write(
                                       "");            
        }
        response.getWriter().write("");
        response.getWriter().write("CXF - Service list");
        response.getWriter().write("");
        
        Collection destinations = servlet.getTransport().getDestinations();
            
        if (destinations.size() > 0) {
            writeSOAPEndpoints(response, destinations);
            writeRESTfulEndpoints(response, destinations);
        } else {
            response.getWriter().write("No services have been found.");
        }
        
        response.getWriter().write("");
    }

    private void writeSOAPEndpoints(HttpServletResponse response, Collection destinations)
        throws IOException {
        response.getWriter().write("Available SOAP services:
"); response.getWriter().write(""); for (OsgiDestination sd : destinations) { if (null != sd.getEndpointInfo().getName() && null != sd.getEndpointInfo().getInterface()) { response.getWriter().write(""); } } response.getWriter().write("
"); response.getWriter().write("" + sd.getEndpointInfo().getInterface().getName().getLocalPart() + ""); response.getWriter().write("
    "); for (OperationInfo oi : sd.getEndpointInfo().getInterface().getOperations()) { response.getWriter().write("
  • " + oi.getName().getLocalPart() + "
  • "); } response.getWriter().write("
"); response.getWriter().write("
"); String address = sd.getEndpointInfo().getAddress(); response.getWriter().write("Endpoint address: " + "" + address + ""); response.getWriter().write("
WSDL : " + "" + sd.getEndpointInfo().getService().getName() + ""); response.getWriter().write("
Target namespace: " + "" + sd.getEndpointInfo().getService().getTargetNamespace() + ""); response.getWriter().write("


"); } private void writeRESTfulEndpoints(HttpServletResponse response, Collection destinations) throws IOException { List restfulDests = new ArrayList(); for (OsgiDestination sd : destinations) { // use some more reasonable check - though this one seems to be the only option at the moment if (null == sd.getEndpointInfo().getInterface()) { restfulDests.add(sd); } } if (restfulDests.size() == 0) { return; } response.getWriter().write("Available RESTful services:
"); response.getWriter().write(""); for (OsgiDestination sd : destinations) { if (null == sd.getEndpointInfo().getInterface()) { response.getWriter().write(""); } } response.getWriter().write("
"); String address = sd.getEndpointInfo().getAddress(); response.getWriter().write("Endpoint address: " + "" + address + ""); response.getWriter().write("
WADL : " + "" + address + "?_wadl&type=xml" + ""); response.getWriter().write("
"); } protected void generateNotFound(HttpServletRequest request, HttpServletResponse res) throws IOException { res.setStatus(404); res.setContentType("text/html"); res.getWriter().write("No service was found."); } public void invokeDestination(final HttpServletRequest request, HttpServletResponse response, OsgiDestination d) throws ServletException { if (LOG.isLoggable(Level.FINE)) { LOG.fine("Service http request on thread: " + Thread.currentThread()); } try { MessageImpl inMessage = servlet.createInMessage(); inMessage.setContent(InputStream.class, request.getInputStream()); inMessage.put(AbstractHTTPDestination.HTTP_REQUEST, request); inMessage.put(AbstractHTTPDestination.HTTP_RESPONSE, response); inMessage.put(AbstractHTTPDestination.HTTP_CONTEXT, servlet.getServletContext()); inMessage.put(AbstractHTTPDestination.HTTP_CONFIG, servlet.getServletConfig()); inMessage.put(Message.HTTP_REQUEST_METHOD, request.getMethod()); inMessage.put(Message.REQUEST_URI, request.getRequestURI()); inMessage.put(Message.PATH_INFO, request.getPathInfo()); inMessage.put(Message.QUERY_STRING, request.getQueryString()); inMessage.put(Message.CONTENT_TYPE, request.getContentType()); inMessage.put(Message.ACCEPT_CONTENT_TYPE, request.getHeader("Accept")); inMessage.put(Message.BASE_PATH, d.getAddress().getAddress().getValue()); inMessage.put(SecurityContext.class, new SecurityContext() { public Principal getUserPrincipal() { return request.getUserPrincipal(); } public boolean isUserInRole(String role) { return request.isUserInRole(role); } }); // work around a bug with Jetty which results in the character // encoding not being trimmed correctly. String enc = request.getCharacterEncoding(); if (enc != null && enc.endsWith("\"")) { enc = enc.substring(0, enc.length() - 1); } String normalizedEncoding = HttpHeaderHelper.mapCharset(enc); if (normalizedEncoding == null) { String m = new org.apache.cxf.common.i18n.Message("INVALID_ENCODING_MSG", LOG, enc).toString(); LOG.log(Level.WARNING, m); throw new IOException(m); } inMessage.put(Message.ENCODING, normalizedEncoding); SSLUtils.propogateSecureSession(request, inMessage); ExchangeImpl exchange = servlet.createExchange(); exchange.setInMessage(inMessage); exchange.setSession(new HTTPSession(request)); d.doMessage(inMessage); } catch (IOException e) { throw new ServletException(e); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy