Package org.knopflerfish.axis2.impl

Source Code of org.knopflerfish.axis2.impl.Axis2AdminImpl

/*
* Copyright (c) 2003-2008, KNOPFLERFISH project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
*   notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above/*
* Copyright (c) 2003-2004, KNOPFLERFISH project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
*   notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above
*   copyright notice, this list of conditions and the following
*   disclaimer in the documentation and/or other materials
*   provided with the distribution.
*
* - Neither the name of the KNOPFLERFISH project nor the names of its
*   contributors may be used to endorse or promote products derived
*   from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.knopflerfish.axis2.impl;


import java.util.*;
import java.net.URL;

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

import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleException;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceEvent;

import org.osgi.service.http.HttpService;
import org.osgi.service.http.HttpContext;

import org.apache.axis2.engine.AxisConfiguration;
import org.apache.axis2.description.AxisService;

import org.knopflerfish.service.axis2.Axis2Admin;
import org.knopflerfish.service.log.LogRef;


public class Axis2AdminImpl implements Axis2Admin {
  LogRef        log;
  BundleContext bc;

  // servlet aliases. this is where the axis2 and axis2admin servlets
  // are registered in the HTTP server
  static final String  AXIS2_SERVLET_ALIAS      = "/axis2";
  static final String  AXIS2ADMIN_SERVLET_ALIAS = "/axis2admin";

  // Map for keeping track of services to be deployed as SOAP services
  // ServiceReference -> SOAPService
  protected Map soapServices = new HashMap();

  // Map for keeping track of axis2 servlet in http servers
  // ServiceReference -> Object[] { HttpContext, Axis2Servlet, Axis2AdminServlet }
  Hashtable servletRegistrations = new Hashtable();

  public Axis2AdminImpl(BundleContext bc) {
    this.bc = bc;
    log = Activator.log;
  }

  void init() throws Exception {
    setupSOAPServiceListener();
    setupHttpServiceListener();
  }

  public void cleanup() {

    undeploySOAPServices(null);

    bc.removeServiceListener(soapServiceListener);
    bc.removeServiceListener(httpServiceListener);

    log.close();
    log = null;
    bc  = null;
  }


  public String[] getPublishedServiceNames() {
    synchronized(soapServices) {
      Set names = new TreeSet();
      for(Iterator it = soapServices.keySet().iterator(); it.hasNext();) {
        ServiceReference sr          = (ServiceReference)it.next();
        SOAPService      soapService = (SOAPService)soapServices.get(sr);
        if(soapService.getDeployCount() > 0) {
          names.add(soapService.serviceName);
        }
      }
      String[] r = new String[names.size()];
      names.toArray(r);
      return r;
    }
  }

  void setupSOAPServiceListener() throws Exception {
    log.debug("Activator.setupSOAPServiceListener()");

    // yes, listen for ALL services.
    bc.addServiceListener(soapServiceListener);

    // Make sure we get services already registered
    handleRegisteredSOAPServices();

    log.debug("Activator.setupAxis() done");
  }

  /**
   * Get all registered SOAP services and deploy them in axis servlets
   */
  void handleRegisteredSOAPServices() throws Exception {
    ServiceReference[] srl = bc.getServiceReferences(null, null);
    for(int i = 0; srl != null && i < srl.length; i++) {
      soapServiceListener.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, srl[i]));
    }
  }


  void setupHttpServiceListener() throws Exception {
    String filter = "(objectclass=" + HttpService.class.getName() + ")";
   
    Activator.bc.addServiceListener(httpServiceListener, filter);
   
    ServiceReference[] srl = Activator.bc.getServiceReferences(null, filter);
    for(int i = 0; srl != null && i < srl.length; i++) {
        httpServiceListener.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED,
                                                            srl[i]));
    }
  }


  // Service listener for http services.
  // Called only for http services
  protected ServiceListener httpServiceListener = new ServiceListener() {
      public void serviceChanged(ServiceEvent ev) {
        ServiceReference sr = ev.getServiceReference();
       
        switch(ev.getType()) {
        case ServiceEvent.REGISTERED:
          setupAxisServlet(sr);
          break;
        case ServiceEvent.UNREGISTERING:
          removeAxisServlet(sr);
          break;
        }
      }
    };


  // Service listener for possible SOAP services.
  // Called for ALL services
  protected ServiceListener soapServiceListener = new ServiceListener() {
      public void serviceChanged(ServiceEvent event) {
        ServiceReference sr = event.getServiceReference();
       
        try {
          switch(event.getType()) {
          case ServiceEvent.REGISTERED:
            if (isSOAPService(sr)) {
              deploySOAPServiceRegistration(sr);
            }
            break;
          case ServiceEvent.MODIFIED: // modification is handled by undeploy + deploy
            if (soapServices.containsKey(sr)) {
              undeploySOAPServiceRegistration(sr, null);
            }
            if (isSOAPService(sr)) { // perhaps it's no longer an exported SOAP service
              deploySOAPServiceRegistration(sr);
            }
            break;
          case ServiceEvent.UNREGISTERING:
            if (soapServices.containsKey(sr)) {
              undeploySOAPServiceRegistration(sr, null);
            }
            break;
          }
        } catch (Exception e) {
          log.error("soapServiceListener", e);
        }
      }
    };

 
  // use the same httpcontext for all servlets
  HttpContext myHttpContext = new HttpContext() {
      public boolean handleSecurity(HttpServletRequest  request,
                                    HttpServletResponse response)
        throws java.io.IOException {
        return true;
      }
     
      public URL getResource(String name) {
        return null;
      }
     
      public String getMimeType(String reqEntry) {
        return null; // server decides type
      }
    };
 

  /**
   * Setup Axis2Servlet at the http service referenced by sr
   */
  void setupAxisServlet(ServiceReference httpSR) {

    synchronized(servletRegistrations) {
      if(servletRegistrations.containsKey(httpSR)) {
        return; // already done
      }
     
      log.debug("set axis servlet for " + httpSR);
     
      HttpService http = (HttpService)Activator.bc.getService(httpSR);
     
      try {
        Axis2Servlet      axisServlet  = new Axis2Servlet();
        Axis2AdminServlet adminServlet = new Axis2AdminServlet(axisServlet);

        http.registerServlet(AXIS2_SERVLET_ALIAS, axisServlet, new Hashtable(), myHttpContext);
        http.registerServlet(AXIS2ADMIN_SERVLET_ALIAS, adminServlet, new Hashtable(), myHttpContext);
       
        log.info("registered axis servlet at " + AXIS2_SERVLET_ALIAS);
        log.info("registered axis admin servlet at " + AXIS2ADMIN_SERVLET_ALIAS);
       
        servletRegistrations.put(httpSR, new Object[] {
          myHttpContext,
          axisServlet,
          adminServlet,
        });

        handleRegisteredSOAPServices();
      
      } catch (Exception e) {
        log.error("Failed to setup Axis2Servlet", e);
      }
    }
  }

  /**
   * Remove Axis2Servlet at the http service referenced by httpSR
   */
  void removeAxisServlet(ServiceReference httpSR) {
    synchronized(servletRegistrations) {
      if(!servletRegistrations.containsKey(httpSR)) {
        return; // nothing to do
      }
     
      log.debug("remove axis " + httpSR);

      try {
        Object[]          v          = (Object[])servletRegistrations.get(httpSR);
        Axis2Servlet      servlet    = (Axis2Servlet)v[1];       
        AxisConfiguration axisConfig = servlet.getAxisConfigurator().getAxisConfiguration();
       
        for(Iterator it = soapServices.keySet().iterator(); it.hasNext(); ) {           
          ServiceReference soapSR      = (ServiceReference)it.next();
          SOAPService      soapService = (SOAPService)soapServices.get(soapSR);
          soapService.undeploy(axisConfig);
        }
      } catch (Exception e) {
        log.warn("Failed to undeploy", e);
      }
     
      HttpService http = (HttpService)Activator.bc.getService(httpSR);
     
      if(http != null) {
        http.unregister(AXIS2_SERVLET_ALIAS);
        http.unregister(AXIS2ADMIN_SERVLET_ALIAS);
        bc.ungetService(httpSR);
      }
      servletRegistrations.remove(httpSR);
    }
  }


  boolean isSOAPService(ServiceReference sr) {   
    Object serviceName = sr.getProperty(Axis2Admin.SOAP_SERVICE_NAME);
    return
      (serviceName != null) &&
      (serviceName instanceof String);
  }

  /**
   * Undeploy all SOAP services present in the soapServices map
   *
   * @param httpSR if null, remove from all http service, otherwise
   *               specifies the http server to remove the soap service from
   */
  void undeploySOAPServices(ServiceReference httpSR) {
    synchronized(soapServices) {
      for(Iterator it = soapServices.keySet().iterator(); it.hasNext();) {
        ServiceReference sr = (ServiceReference)it.next();
        SOAPService  soapService = (SOAPService)soapServices.get(sr);
        undeploySOAPService(soapService, httpSR);
      }
      soapServices.clear();
    }
  }
 
  /**
   * Undeploy a single SOAPService from one or all http servers
   *
   * @param httpSR if null, remove from all http service, otherwise
   *               specifies the http server to remove the soap service from
   */
  public void undeploySOAPService(SOAPService soapService,
                                  ServiceReference httpSR) {
    log.debug("undeploySOAPService " + soapService);
   
    synchronized(servletRegistrations) {
      for(Iterator it = servletRegistrations.keySet().iterator(); it.hasNext(); ) {
        try {
          ServiceReference sr      = (ServiceReference)it.next();
          if(httpSR == null || httpSR.equals(sr)) {
            Object[]         v       = (Object[])servletRegistrations.get(sr);
            Axis2Servlet     servlet = (Axis2Servlet)v[1];

            AxisConfiguration axisConfig = servlet.getAxisConfigurator().getAxisConfiguration();
           
            soapService.undeploy(axisConfig);
          }
        } catch (Exception e) {
          log.warn("Failed to undeploy service " + soapService, e);
        }
      }
    }
  }

  void undeploySOAPServiceRegistration(ServiceReference sr,
                                       ServiceReference httpSR) {
    SOAPService  soapService = (SOAPService)soapServices.get(sr);
    String       serviceName = (String) sr.getProperty(Axis2Admin.SOAP_SERVICE_NAME);

    log.debug("undeploySOAPServiceRegistration " + serviceName);

    soapServices.remove(sr);
    undeploySOAPService(soapService, httpSR);
  }

  void deploySOAPServiceRegistration(ServiceReference sr) {
    String           serviceName    = (String)   sr.getProperty(Axis2Admin.SOAP_SERVICE_NAME);

    log.debug("deploySOAPServiceRegistration " +serviceName);
   
    // throws exception if name is invalid
    assertServiceName(serviceName);
   
    synchronized(soapServices) {
      SOAPService soapService = (SOAPService)soapServices.get(sr);
      if(soapService == null) {
        soapService = new SOAPService(sr);
        log.debug("created new " + soapService);
      } else {
        log.debug("reused " + soapService);
      }

      int count = deploySOAPService(soapService);
     
      log.debug("deployed in " + count  + " servlets");
      soapServices.put(sr, soapService);
    }
  }


  /**
   * Deploy a SOAPService in all found axis servlets.
   *
   * @return number of successful deployments
   */
  int  deploySOAPService(SOAPService soapService) {
    log.debug("deploySOAPService " +  soapService);

    int count = 0;
    synchronized(servletRegistrations) {
     
      for(Iterator it = servletRegistrations.keySet().iterator(); it.hasNext(); ) {
        try {
          ServiceReference sr      = (ServiceReference)it.next();
          Object[]         v       = (Object[])servletRegistrations.get(sr);
          Axis2Servlet     servlet = (Axis2Servlet)v[1];
         
          AxisConfiguration axisConfig = servlet.getAxisConfigurator().getAxisConfiguration();
                   
          soapService.deploy(axisConfig);
          count++;
        } catch (Exception e) {
          log.warn("Failed to deploy service " + soapService, e);
        }
      }
    }
    return count;
  }

 
  // Some chars we don't allow in soap service names
  static final String ILLEGAL_SERVICE_CHARS = "\r\n\t \\\"'!#%&/()=+{}[]?<>;";

  /**
   * Check if service name is OK for publishing as SOAP service.
   *
   * This incluced checking for previous registrations at the same name.
   *
   * @throws IllegalArgumentException if name is not valid
   */
  void assertServiceName(String serviceName) {
    if(serviceName == null) {
      throw new IllegalArgumentException("Service name cannot be null");
    }
    if("".equals(serviceName)) {
      throw new IllegalArgumentException("Service name cannot be empty string");
    }

    for(int i = 0; i < serviceName.length(); i++) {
      if(-1 != ILLEGAL_SERVICE_CHARS.indexOf(serviceName.charAt(i))) {
        throw new IllegalArgumentException("Service name " +
                                           "'" + serviceName + "'" +
                                           " cannot contain whitespace or special characters");
      }
    }

    synchronized(soapServices) {
      for(Iterator it = soapServices.keySet().iterator(); it.hasNext();) {
        ServiceReference sr          = (ServiceReference)it.next();
        SOAPService      soapService = (SOAPService)soapServices.get(sr);
        String           name        = (String)sr.getProperty(Axis2Admin.SOAP_SERVICE_NAME);
        if(soapService.getDeployCount() > 0 && name.equals(serviceName)) {
          throw new IllegalArgumentException("Service '" + name + "' is already deployed");
        }
      }
    }
  }
}
TOP

Related Classes of org.knopflerfish.axis2.impl.Axis2AdminImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.