Package org.xmlBlaster.contrib.jmx

Source Code of org.xmlBlaster.contrib.jmx.MX4JAdaptor

/*------------------------------------------------------------------------------
Name:      MX4JAdaptor.java
Project:   xmlBlaster.org
Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
------------------------------------------------------------------------------*/

package org.xmlBlaster.contrib.jmx;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.logging.Logger;

import javax.management.MBeanServer;
import javax.management.ObjectName;

import mx4j.tools.adaptor.http.HttpAdaptor;
import mx4j.tools.adaptor.http.HttpInputStream;
import mx4j.tools.adaptor.http.HttpOutputStream;
import mx4j.tools.adaptor.http.XSLTProcessor;
import mx4j.util.Base64Codec;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xmlBlaster.contrib.GlobalInfo;
import org.xmlBlaster.contrib.InfoHelper;
import org.xmlBlaster.util.Global;
import org.xmlBlaster.util.XmlBlasterException;
import org.xmlBlaster.util.admin.extern.JmxWrapper;
import org.xmlBlaster.util.context.ContextNode;
import org.xmlBlaster.util.def.ErrorCode;
import org.xmlBlaster.util.plugin.PluginInfo;

/**
* MX4JAdaptor
* @author <a href="mailto:michele@laghi.eu">Michele Laghi</a>
*/
public class MX4JAdaptor extends GlobalInfo {

   public class XblHttpAdaptor extends HttpAdaptor {
      public XblHttpAdaptor() {
         super();
      }
   }
  
   private static Logger log = Logger.getLogger(MX4JAdaptor.class.getName());
   private final static String USER_ROLE = "user";
   private final static String ADMIN_ROLE = "admin";
   private final static String INITIATOR_ROLE = "initiator";

   private ObjectName name;
   private Map roles;
   private String authMethod;
   private HttpAdaptor adaptor;
  
   public class ContribXsltProcessor extends XSLTProcessor {
     
      private String prefix;
      private Set warnings;
      private String authMethod;
      private Map roles;
     
      public ContribXsltProcessor(Map roles, String authMethod) {
         super();
         this.warnings = new HashSet();
         this.roles = roles;
         this.authMethod = authMethod;
      }
     
      public void setFile(String prefix) {
         this.prefix = prefix;
      }
     
      public String getFile(){
         return this.prefix;
      }
     
      private boolean isPathAbsolute(String path) {
         if (path == null)
            return false;
         File test = new File(path.trim());
         return test.isAbsolute();
      }
     
      /**
       *
       * Note on the classpath: to find a resource it has to be according to java nomenclature,
       * it will not find a document specified with '\'.
       * @param path
       * @param cl
       * @param fixFileSeparator
       * @return
       */
      private InputStream getInputStream(String path, ClassLoader cl, boolean fixFileSeparator) {

         log.fine("using classloader '" + cl.getClass().getName() + "'");
         if (path == null)
            log.severe("ContribXsltProcessor.getInputStream: no filename specified");
         // path = this.prefix + File.separatorChar + path;
         log.fine("Requesting path '" + path + "'");
         if (!path.startsWith(File.separator) && !path.startsWith("/"))
         // if (!isPathAbsolute(path))
            // path = File.separator + path;
            path = "/" + path;
              
         path = this.prefix + path;
         if (fixFileSeparator)
            path = path.replace('/', File.separatorChar);

         log.fine("Requesting path (after cleaning) '" + path + "'");
        
         InputStream ret = null;
         try {
            Enumeration enm = cl.getResources(path);
            if(enm.hasMoreElements()) {
               URL url = (URL)enm.nextElement();
               String urlTxt = "loading file '" + url.getFile() + "'";
               log.fine(urlTxt);
               try {
                  ret = url.openStream();
               }
               catch(IOException ex) {
                  log.warning("init: could not read properties from '" + url.getFile() + "' : " + ex.getMessage());
               }
               while(enm.hasMoreElements() && !this.warnings.contains(path)) {
                  this.warnings.add(path);
                  url = (URL)enm.nextElement();
                  log.warning(urlTxt + ". An additional matching file has been found in the classpath at '"
                     + url.getFile() + "' please check that the correct one has been loaded (see info above)."
                  );
               }
            }
            else {
               StringBuffer buf = new StringBuffer();
               if (cl instanceof URLClassLoader) {
                  URL[] urls = ((URLClassLoader)cl).getURLs();
                  for (int i=0; i < urls.length; i++)
                     buf.append(urls[i].toString()).append("\n");
               }
               else {
                  buf.append(" not an URLClassLoader (can not get list of files found) ");
               }
               log.warning("no file found with the name '" + path + "'" /*+ "' : " + (buf.length() > 0 ? " classpath: " + buf.toString() : ""*/);
               log.fine("no file found with the name '" + path + "'" + " classpath: '" + buf.toString() + "'");
            }
         }
         catch(IOException e) {
            log.severe("an IOException occured when trying to load property file '" + name + "'" + e.getMessage());
         }
         return ret;
      }

      protected InputStream getInputStream(String path) {
         boolean fixFileSeparator = false;
         InputStream ret = null;
         if (ret == null)
            ret = getInputStream(path, this.getClass().getClassLoader(), fixFileSeparator);
         /*
         if (ret == null)
            ret = getInputStream(path, ClassLoader.getSystemClassLoader(), fixFileSeparator);
         fixFileSeparator = true;
         */
         /*
         if (ret == null)
            ret = getInputStream(path, this.getClass().getClassLoader(), fixFileSeparator);
         if (ret == null)
            ret = getInputStream(path, ClassLoader.getSystemClassLoader(), fixFileSeparator);
         return ret;
         */
         return ret;
      }

      private String debug(HttpInputStream is) throws IOException {
         Map headers = is.getHeaders();
         Iterator iter = headers.entrySet().iterator();
         StringBuffer buf = new StringBuffer(1024);
         buf.append("headers: \n");
         while (iter.hasNext()) {
            Map.Entry entry = (Map.Entry)iter.next();
            String key = (String)entry.getKey();
            String val = (String)entry.getValue();
            buf.append("   ").append(key).append("\t: ").append(val).append("\n");
         }
         buf.append("\n");
         buf.append("method\t: ").append(is.getMethod()).append("\n");
         buf.append("path  \t: ").append(is.getPath()).append("\n");
         buf.append("query\t: ").append(is.getQueryString()).append("\n");
         buf.append("query\t: ").append(is.getQueryString()).append("\n");
         buf.append("query\t: ").append(is.getQueryString()).append("\n");
         Map variables  = is.getHeaders();
         iter = variables.entrySet().iterator();
         buf.append("variables: \n");
         while (iter.hasNext()) {
            Map.Entry entry = (Map.Entry)iter.next();
            String key = (String)entry.getKey();
            String val = (String)entry.getValue();
            buf.append("   ").append(key).append("\t: ").append(val).append("\n");
         }
         buf.append("\n");
         return buf.toString();
      }
   
      private String getTemplate(HttpInputStream is) {
         String query = is.getQueryString();
         if (query == null)
            return null;
         final String template = "template=";
         final int length = template.length();
         int pos = query.indexOf(template);
         if (pos < 0)
            return null;
         String end = query.substring(pos + length);
         pos = end.indexOf('&');
         if (pos < 0)
            return end;
         return end.substring(0, pos);
      }
     

      private String extractUserName(HttpInputStream is) throws IOException {
         String authentication = is.getHeader("authorization");
         if (authentication == null)
            return null;
        
         if (this.authMethod.equals("basic")) {
            authentication = authentication.substring(5, authentication.length());
            String decodeString = new String(Base64Codec.decodeBase64(authentication.getBytes()));
            if (decodeString.indexOf(":") > 0) {
               try {
                  StringTokenizer tokens = new StringTokenizer(decodeString, ":");
                  return tokens.nextToken(); // username
               }
               catch (Exception ex) {
                  ex.printStackTrace();
                  return null;
               }
            }
         }
         return null;
      }

     
      public void writeResponse(HttpOutputStream outputStream, HttpInputStream inputStream, Document doc) throws IOException {
         // log.severe(debug(inputStream));
         Element el = doc.getDocumentElement();

         Attr admin = doc.createAttribute(ADMIN_ROLE);
         Attr initiator = doc.createAttribute(INITIATOR_ROLE);
         Attr user = doc.createAttribute(USER_ROLE);
         if (this.authMethod != null) {
            String userName = extractUserName(inputStream);
            if (userName == null)
               userName = "";
            String roles = (String)this.roles.get(userName);
            if (roles == null) {
               admin.setValue("false");
               initiator.setValue("false");
               user.setValue("false");
            }
            else if (roles.indexOf(ADMIN_ROLE) > -1) {
               admin.setValue("true");
               initiator.setValue("true");
               user.setValue("true");
            }
            else if (roles.indexOf(INITIATOR_ROLE) > -1) {
               admin.setValue("false");
               initiator.setValue("true");
               user.setValue("true");
            }
            else {
               admin.setValue("false");
               initiator.setValue("false");
               user.setValue("true");
            }
         }
         else {
            admin.setValue("true");
            initiator.setValue("true");
            user.setValue("true");
         }
         el.setAttributeNode(admin);
         el.setAttributeNode(initiator);
         el.setAttributeNode(user);
         // outputStream.setHeader("Cache-Control", "no-cache");
         // outputStream.setHeader("Content-Type", "text/xml");
         super.writeResponse(outputStream, inputStream, doc);
      }
   }
  
   public MX4JAdaptor() {
      super((Set)null);
      this.roles = new HashMap();
   }
  
   private final HttpAdaptor instantiateAdaptor(Global global) throws Exception {
     
      int port = getInt("port", 9999);
      String host = get("host", "0.0.0.0");
      String adaptorName = get("adaptorName", "HttpAdaptorMX4J");
      MBeanServer server = global.getJmxWrapper().getMBeanServer();
      HttpAdaptor adapter = new HttpAdaptor();
      this.name = new ObjectName("Adaptor:name=" + adaptorName);
      server.registerMBean(adapter, name);
      adapter.setHost(host);
      adapter.setPort(port);
      this.authMethod = get("authenticationMethod", null);
      log.info("Authentication Method is '" + this.authMethod + "'");
      if (this.authMethod != null) {
         this.authMethod = this.authMethod.trim();
         if ("basic".equals(this.authMethod))
            adapter.setAuthenticationMethod(this.authMethod);
         else
            log.warning("Authentication method '" + authMethod + "' not recognized, will switch to 'basic'");
         log.info("Authentication Method is '" + this.authMethod + "'");
         Map users = InfoHelper.getPropertiesStartingWith("replication.monitor.user.", this, null);
         if (users != null && users.size() > 0) {
            Iterator iter = users.entrySet().iterator();
            while (iter.hasNext()) {
               Map.Entry entry = (Map.Entry)iter.next();
               String name = (String)entry.getKey();
               String val = (String)entry.getValue();
               log.fine("name='" + name + "' value='" + val + "'");
               int pos = val.indexOf(':');
               String pwd = null;
               String roles = USER_ROLE;
               if (pos > -1) {
                  pwd = val.substring(0, pos);
                  roles = val.substring(pos+1);
               }
               else
                  pwd = val;
               log.fine("registering monitor user '" + name + "' having roles : " + roles + "'");
               adapter.addAuthorization(name, pwd);
               this.roles.put(name, roles);
            }
         }
         else
            log.info("No Users found for the monitor");
      }
     
      String xsltProcessor = get("xsltProcessor", null);
      ObjectName processorName = null;
      if (xsltProcessor != null) {

         ContextNode contextNode = new ContextNode(ContextNode.CONTRIB_MARKER_TAG, "jmx" + ContextNode.SEP + xsltProcessor,
               this.global.getContextNode());
         processorName = new ObjectName(JmxWrapper.getObjectNameLiteral(this.global, contextNode));
        
         // XSLTProcessor processor = new XSLTProcessor();
         ContribXsltProcessor processor = new ContribXsltProcessor(this.roles, this.authMethod);
        
         server.registerMBean(processor, processorName);
        
         // set it to use a dir
         String xsltPath = get("xsltPath", null); // can be a directory or a jar file
         String xsltPathInJar = null;

         if (xsltPath != null) {
            processor.setFile(xsltPath);
         }
         boolean xsltCache = getBoolean("xsltCache", true);
         processor.setUseCache(xsltCache);
         // set not to use cache
         String xsltLocale = get("xsltLocale", null);
         if (xsltLocale != null) {
         }
         // adds a mime type
         // server.invoke(processorName, "addMimeType", new Object[] {".pdf", "application/pdf"}, new String[] {"java.lang.String", "java.lang.String"});
         log.info("Xslt Processor: " + xsltProcessor + "' on xsltPath='" + xsltPath + "' and xsltPathInJar='" + xsltPathInJar + "' and xsltCache='" + xsltCache + "' and xsltLocale='" + xsltLocale + "'");
         adapter.setProcessorName(processorName);
      }
     
      adapter.start();
      log.info("The adaptor '" + adaptorName + "' is running. You can access it at 'http://" + host + ":" + port + "'");
      return adapter;
   }

   private final void stopAdaptor() throws Exception {
      MBeanServer server = this.global.getJmxWrapper().getMBeanServer();
      server.unregisterMBean(this.name);
      this.adaptor.stop();
   }
  
   /**
    * @see org.xmlBlaster.contrib.GlobalInfo#doInit(org.xmlBlaster.util.Global, org.xmlBlaster.util.plugin.PluginInfo)
    */
   protected void doInit(Global global, PluginInfo pluginInfo)
         throws XmlBlasterException {
      try {
         this.adaptor = instantiateAdaptor(this.global);
      }
      catch (Throwable e) {
         e.printStackTrace();
         throw new XmlBlasterException(this.global, ErrorCode.RESOURCE_CONFIGURATION, "ReplManagerPlugin", "init failed", e);
      }
   }

   public void shutdown() throws XmlBlasterException {
      try {
         stopAdaptor();
      }
      catch (Throwable e) {
         throw new XmlBlasterException(this.global, ErrorCode.RESOURCE_CONFIGURATION, "ReplManagerPlugin", "shutdown failed", e);
      }
      super.shutdown();
   }
  
}
TOP

Related Classes of org.xmlBlaster.contrib.jmx.MX4JAdaptor

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.