Package ca.carleton.gcrc.couch.config

Source Code of ca.carleton.gcrc.couch.config.ConfigServlet

package ca.carleton.gcrc.couch.config;

import java.io.File;
import java.io.FileInputStream;
import java.util.List;
import java.util.Properties;
import java.util.Vector;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

import org.apache.log4j.Logger;

import ca.carleton.gcrc.couch.app.DesignDocumentPush;
import ca.carleton.gcrc.couch.client.CouchDb;
import ca.carleton.gcrc.couch.client.CouchDesignDocument;
import ca.carleton.gcrc.couch.client.CouchFactory;
import ca.carleton.gcrc.couch.client.CouchClient;
import ca.carleton.gcrc.couch.onUpload.UploadListener;
import ca.carleton.gcrc.couch.onUpload.UploadWorker;
import ca.carleton.gcrc.couch.onUpload.mail.MailNotification;
import ca.carleton.gcrc.couch.onUpload.mail.MailNotificationImpl;
import ca.carleton.gcrc.couch.onUpload.mail.MailNotificationNull;
import ca.carleton.gcrc.couch.config.listener.ConfigListener;
import ca.carleton.gcrc.couch.config.listener.ConfigListenerCollection;
import ca.carleton.gcrc.couch.config.listener.ConfigWorker;
import ca.carleton.gcrc.nunaliit2.couch.replication.ReplicationWorker;
import ca.carleton.gcrc.olkit.multimedia.utils.MultimediaConfiguration;
import ca.carleton.gcrc.upload.OnUploadedListenerSingleton;
import ca.carleton.gcrc.upload.UploadServlet;
import ca.carleton.gcrc.upload.UploadUtils;

@SuppressWarnings("serial")
public class ConfigServlet extends HttpServlet {

  final static public String ATLAS_DESIGN_SERVER = "server";
  final static public String USER_DESIGN_AUTH = "_auth";

  final protected Logger logger = Logger.getLogger(this.getClass());
 
  private CouchClient couchClient = null;
  private CouchDb couchDb = null;
  private CouchDesignDocument couchDd = null;
  private String couchReplicationUserName = null;
  private String couchReplicationPassword = null;
  private UploadWorker uploadWorker = null;
  private ReplicationWorker replicationWorker = null;
  private ConfigWorker configWorker = null;
  private File mediaDir = null;
  private MailNotification mailNotification = null;
 
  public ConfigServlet() {
   
  }

  public void init(ServletConfig config) throws ServletException {
    super.init(config);
   
    logger.info("Initializing Couch Configuration");
   
    // Instantiate CouchDb client
    try {
      initCouchDbClient(config);
    } catch(ServletException e) {
      logger.error("Error while initializing couch client",e);
      throw e;
    }
   
    // Upload design documents for atlas server
    try {
      initAtlasServerDesignDocument(config);
    } catch(ServletException e) {
      logger.error("Error while initializing design document for atlas server",e);
      throw e;
    }
   
    // Upload design documents for user auth
    try {
      initAuthDesignDocument(config);
    } catch(ServletException e) {
      logger.error("Error while initializing design document for user auth",e);
      throw e;
    }
   
    // Configure replication worker
    try {
      initReplicationWorker(config);
    } catch(ServletException e) {
      logger.error("Error while initializing replication worker",e);
      throw e;
    }
   
    // Configure config listeners
    try {
      initCouchConfigListener(config);
    } catch(ServletException e) {
      logger.error("Error while initializing couch config listener",e);
      throw e;
    }
   
    // Configure multimedia
    try {
      initMultimedia(config);
    } catch(ServletException e) {
      logger.error("Error while initializing multimedia",e);
      throw e;
    }

    // Configure mail notification
    try {
      initMail(config);
    } catch(ServletException e) {
      logger.error("Error while initializing mail notification",e);
      mailNotification = new MailNotificationNull();
    }
   
    mediaDir = UploadUtils.getMediaDir(config.getServletContext());
   
    UploadListener uploadListener = new UploadListener();
    uploadListener.setCouchDb(couchDb);
    config.getServletContext().setAttribute(UploadServlet.OnUploadedListenerAttributeName, uploadListener);
    OnUploadedListenerSingleton.configure(uploadListener);
   
    try {
      uploadWorker = new UploadWorker();
      uploadWorker.setDesignDocument(couchDd);
      uploadWorker.setMediaDir(mediaDir);
      uploadWorker.setMailNotification(mailNotification);
      uploadWorker.start();
    } catch (Exception e) {
      logger.error("Error starting upload worker",e);
      throw new ServletException("Error starting upload worker",e);
    }

    logger.info("Completed Couch Configuration");
  }
 
  private File getConfigurationDirectory(ServletConfig config) {
    File rootFile = null;

    // Check if already computed
    Object rootObj = config.getServletContext().getAttribute(UploadUtils.CONF_DIR_ATTRIBUTE);
    if( rootObj instanceof File ) {
      return (File)rootObj;
    }
   
    // Check /etc/nunaliit2/couch
    {
      File etcFile = new File("/etc/nunaliit2/couchdb/default");
      if( etcFile.exists() ) {
        if( etcFile.isDirectory() ) {
          rootFile = etcFile;
        }
      }
    }
   
    // Check WEB-INF directory
    if( null == rootFile ){
      ServletContext servletContext = config.getServletContext();
      if( null != servletContext ) {
        String realRootString = servletContext.getRealPath("./WEB-INF");
        File realRoot = new File(realRootString);
        if( realRoot.exists() ) {
          if( realRoot.isDirectory() ) {
            rootFile = realRoot;
          }
        }
      }
    }
   
    // Save it to not have to recompute
    if( null != rootFile ) {
      config.getServletContext().setAttribute(UploadUtils.CONF_DIR_ATTRIBUTE, rootFile);
    };
   
    return rootFile;
  }

  private void initCouchDbClient(ServletConfig config) throws ServletException {
    File rootFile = getConfigurationDirectory(config);
   
    // Load up configuration information
    Properties props = new Properties();
    {
      File propFile = null;
      if( null != rootFile ) {
        propFile = new File(rootFile, "couch.properties");
        if( false == propFile.exists() || false == propFile.isFile() ) {
          propFile = null;
        }
      }
      if( null != rootFile && null == propFile ) {
        propFile = new File(rootFile, "couch.properties.default");
        if( false == propFile.exists() || false == propFile.isFile() ) {
          propFile = null;
        }
      }
      if( null == propFile ) {
        logger.info("Couch Client property file location can not be determined");
      } else {
        logger.info("Reading Couch Client properties from "+propFile.getAbsolutePath());
        FileInputStream fis = null;
        try {
          fis = new FileInputStream(propFile);
          props.load(fis);
        } catch (Exception e) {
          logger.error("Unable to read properties from "+propFile.getAbsolutePath(),e);
        } finally {
          if( null != fis ) {
            try {
              fis.close();
            } catch (Exception e) {
              // Ignore
            }
          }
        }
      }
    }
   
    // Our user is the admin user
    if( props.containsKey("couchdb.admin.user") ) {
      props.setProperty("couchdb.user", props.getProperty("couchdb.admin.user"));
    }
    if( props.containsKey("couchdb.admin.password") ) {
      props.setProperty("couchdb.password", props.getProperty("couchdb.admin.password"));
    }
   
    // Read couch db replication information
    if( props.containsKey("couchdb.replication.user") ) {
      couchReplicationUserName = props.getProperty("couchdb.replication.user");
    }
    if( props.containsKey("couchdb.replication.password") ) {
      couchReplicationPassword = props.getProperty("couchdb.replication.password");
    }
   
    // Create Couch Server from properties
    CouchFactory factory = new CouchFactory();
    try {
      couchClient = factory.getClient(props);
     
    } catch(Exception e) {
      logger.error("Unable to get Couch Server",e);
      throw new ServletException("Unable to get Couch Server",e);
    }
   
    // Create database
    try {
      if( props.containsKey("couchdb.dbUrl") ) {
        couchDb = factory.getDb(couchClient, props.getProperty("couchdb.dbUrl"));
      } else if( props.containsKey("couchdb.dbName") ) {
        couchDb = couchClient.getDatabase(props.getProperty("couchdb.dbName"));
      } else {
        throw new Exception("dbUrl or dbName must be provided");
      }
    } catch(Exception e) {
      logger.error("Unable to build Couch Database",e);
      throw new ServletException("Unable to build Couch Database",e);
    }
    logger.info("CouchDb configured: "+couchDb.getUrl());
  }

  private void initAtlasServerDesignDocument(ServletConfig config) throws ServletException {
    // Find root directory for design document
    File ddDir = null;
    {
      File rootFile = null;
      {
        ServletContext servletContext = config.getServletContext();
        if( null != servletContext ) {
          String realRoot = servletContext.getRealPath(".");
          if( null != realRoot ) {
            rootFile = new File(realRoot);
          }
        }
      }
      if( null != rootFile ) {
        ddDir = new File(rootFile, "WEB-INF/uploadDesignDoc");
        if( false == ddDir.exists() || false == ddDir.isDirectory() ) {
          ddDir = null;
        }
      }
      if( null == ddDir ) {
        throw new ServletException("Unable to find design document source for upload");
      }
    }

    DesignDocumentPush ddPush = new DesignDocumentPush(couchDb, ATLAS_DESIGN_SERVER, ddDir);
    try {
      ddPush.push();
    } catch(Exception e) {
      throw new ServletException("Problem pushing design document: "+ATLAS_DESIGN_SERVER, e);
    }
   
    try {
      couchDd = couchDb.getDesignDocument(ATLAS_DESIGN_SERVER);
    } catch (Exception e) {
      throw new ServletException("Unable to get design document", e);
    }
  }

  private void initAuthDesignDocument(ServletConfig config) throws ServletException {
    // Find root directory for design document
    File ddDir = null;
    {
      File rootFile = null;
      {
        ServletContext servletContext = config.getServletContext();
        if( null != servletContext ) {
          String realRoot = servletContext.getRealPath(".");
          if( null != realRoot ) {
            rootFile = new File(realRoot);
          }
        }
      }
      if( null != rootFile ) {
        ddDir = new File(rootFile, "WEB-INF/userDesignAuth");
        if( false == ddDir.exists() || false == ddDir.isDirectory() ) {
          ddDir = null;
        }
      }
      if( null == ddDir ) {
        throw new ServletException("Unable to find design document source for user auth");
      }
    }
   
    try {
      CouchDb userDb = couchClient.getDatabase("_users");
      DesignDocumentPush ddPush = new DesignDocumentPush(userDb, USER_DESIGN_AUTH, ddDir);
      ddPush.push();
    } catch(Exception e) {
      throw new ServletException("Problem pushing design document: "+USER_DESIGN_AUTH, e);
    }
  }

  private void initReplicationWorker(ServletConfig config) throws ServletException {

    if( null == couchClient ) {
      throw new ServletException("Replication worker requires a CouchDb client");
    }
   
    try {
      replicationWorker = new ReplicationWorker();
      replicationWorker.setCouchClient(couchClient);
      replicationWorker.start();
     
    } catch (Exception e) {
      throw new ServletException("Error starting replication worker",e);
    }
  }

  private void initCouchConfigListener(ServletConfig config) throws ServletException {
    File rootFile = getConfigurationDirectory(config);
   
    // Load up configuration information
    Properties props = new Properties();
    {
      File propFile = null;
      if( null != rootFile ) {
        propFile = new File(rootFile, "config.properties");
        if( false == propFile.exists() || false == propFile.isFile() ) {
          propFile = null;
        }
      }
//      if( null != rootFile && null == propFile ) {
//        propFile = new File(rootFile, "config.properties.default");
//        if( false == propFile.exists() || false == propFile.isFile() ) {
//          propFile = null;
//        }
//      }
      if( null == propFile ) {
        logger.info("Config listener property file location can not be determined");
      } else {
        logger.info("Reading config listener properties from "+propFile.getAbsolutePath());
        FileInputStream fis = null;
        try {
          fis = new FileInputStream(propFile);
          props.load(fis);
        } catch (Exception e) {
          logger.error("Unable to read properties from "+propFile.getAbsolutePath(),e);
        } finally {
          if( null != fis ) {
            try {
              fis.close();
            } catch (Exception e) {
              // Ignore
            }
          }
        }
      }
    }
   
    // Interpret configuration
    String serverName = props.getProperty("config.serverName");
    String dbName = props.getProperty("config.dbName");

    if( null == serverName ) {
      throw new ServletException("Can not determine server name for querying configuration information");
    }
    if( null == dbName ) {
      throw new ServletException("Can not determine database name for querying configuration information");
    }
   
    logger.info("Server Name: "+serverName);
   
    try {
      CouchDb configDb = couchClient.getDatabase(dbName);
      CouchDesignDocument configDesign = configDb.getDesignDocument("config");
     
      ConfigListenerCollection configListener = new ConfigListenerCollection();
      List<ConfigListener> collection = new Vector<ConfigListener>();
      collection.add( new ReplicationConfigListener(
          couchReplicationUserName
          ,couchReplicationPassword
          ,replicationWorker
          ) );
      configListener.setCollection(collection);

      configWorker = new ConfigWorker();
      configWorker.setDesignDocument(configDesign);
      configWorker.setServerName(serverName);
      configWorker.setConfigListener(configListener);
      configWorker.start();
     
    } catch (Exception e) {
      throw new ServletException("Error starting config listener worker",e);
    }
   
    logger.info("CouchDb configured: "+couchDb.getUrl());
  }

  private void initMultimedia(ServletConfig config) throws ServletException {
    File rootFile = getConfigurationDirectory(config);
   
    // Load up configuration information
    Properties props = new Properties();
    {
      File propFile = null;
      if( null != rootFile ) {
        propFile = new File(rootFile, "multimedia.properties");
        if( false == propFile.exists() || false == propFile.isFile() ) {
          propFile = null;
        }
      }
      if( null != rootFile && null == propFile ) {
        propFile = new File(rootFile, "multimedia.properties.default");
        if( false == propFile.exists() || false == propFile.isFile() ) {
          propFile = null;
        }
      }
      if( null == propFile ) {
        logger.info("Multimedia property file location can not be determined");
      } else {
        logger.info("Reading multimedia properties from "+propFile.getAbsolutePath());
        FileInputStream fis = null;
        try {
          fis = new FileInputStream(propFile);
          props.load(fis);
        } catch (Exception e) {
          logger.error("Unable to read properties from "+propFile.getAbsolutePath(),e);
        } finally {
          if( null != fis ) {
            try {
              fis.close();
            } catch (Exception e) {
              // Ignore
            }
          }
        }
      }
    }
   
    MultimediaConfiguration.configureFromProperties(props);
  }

  private void initMail(ServletConfig config) throws ServletException {
    File rootFile = getConfigurationDirectory(config);
   
    // Load up configuration information
    Properties props = new Properties();
    {
      File propFile = null;
      if( null != rootFile ) {
        propFile = new File(rootFile, "mail.properties");
        if( false == propFile.exists() || false == propFile.isFile() ) {
          propFile = null;
        }
      }
      if( null == propFile ) {
        logger.info("Mail property file location can not be determined");
      } else {
        logger.info("Reading mail properties from "+propFile.getAbsolutePath());
        FileInputStream fis = null;
        try {
          fis = new FileInputStream(propFile);
          props.load(fis);
        } catch (Exception e) {
          logger.error("Unable to read properties from "+propFile.getAbsolutePath(),e);
        } finally {
          if( null != fis ) {
            try {
              fis.close();
            } catch (Exception e) {
              // Ignore
            }
          }
        }
      }
    }
   
    // Create mail notification
    MailNotificationImpl mail = null;
    try {
      mail = new MailNotificationImpl();
      mail.setMailProperties(props);
     
    } catch(Exception e) {
      logger.error("Unable to configure mail notification",e);
    }

    mailNotification = mail;
  }
 
  public void destroy() {
    try {
      uploadWorker.stopTimeoutMillis(5*1000); // 5 seconds
    } catch (Exception e) {
      logger.error("Unable to shutdown upload worker", e);
    }

    try {
      configWorker.stopTimeoutMillis(5*1000); // 5 seconds
    } catch (Exception e) {
      logger.error("Unable to shutdown config listener worker", e);
    }

    try {
      replicationWorker.stopTimeoutMillis(5*1000); // 5 seconds
    } catch (Exception e) {
      logger.error("Unable to shutdown replication worker", e);
    }
  }
}
TOP

Related Classes of ca.carleton.gcrc.couch.config.ConfigServlet

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.