Package org.atomojo.server

Source Code of org.atomojo.server.WebComponent

/*
* WebComponent.java
*
* Created on March 26, 2007, 6:04 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package org.atomojo.server;

import java.net.URI;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Level;
import org.atomojo.app.client.Entry;
import org.atomojo.app.client.FeedClient;
import org.atomojo.app.client.FeedDestination;
import org.atomojo.app.client.Link;
import org.atomojo.app.client.Ontology;
import org.atomojo.app.client.Text;
import org.infoset.xml.Document;
import org.infoset.xml.Element;
import org.infoset.xml.Name;
import org.infoset.xml.XMLException;
import org.restlet.Client;
import org.restlet.Component;
import org.restlet.Context;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.Restlet;
import org.restlet.Server;
import org.restlet.data.Protocol;
import org.restlet.data.Reference;
import org.restlet.data.Status;

/**
*
* @author alex
*/
public class WebComponent extends Component {

   static final URI HOST_TERM = Ontology.getDefaultInstance().find(ConfiguredHost.T_BASE,"host").getURI();
   static final Name VIEWPORT = Name.create("{http://www.w3.org/2007/03/xproc}viewport");
   static final Name XSLT = Name.create("{http://www.w3.org/2007/03/xproc}xslt");
   static final Name INPUT = Name.create("{http://www.w3.org/2007/03/xproc}input");
   static final Name INLINE = Name.create("{http://www.w3.org/2007/03/xproc}inline");
   public static final String LINKS_ATTR = "org.atomojo.www.app.links";

   class AutoConfiguration {

      Configuration.Server serverConf;
      Link link;
      Map<String, ConfiguredHost> hosts;
      Map<String, ConfiguredHost> confHosts;
      boolean changes;
      Client webClient;

      AutoConfiguration(Configuration.Server serverConf, Link link) {
         this.serverConf = serverConf;
         this.link = link;
         this.hosts = new TreeMap<String, ConfiguredHost>();
         this.confHosts = ifaceHosts.get(serverConf.getKey());
         this.webClient = getContext().getClientDispatcher();
      }

      public void configure() {
         FeedClient client = new FeedClient(webClient,new Reference(link.getLink()));
         client.setIdentity(link.getUsername(), link.getPassword());

         getContext().getLogger().info("Loading configuration for " + serverConf.getAddress() + ":" + serverConf.getPort() + " from " + link.getLink());

         changes = false;
         final Map<String, Boolean> found = new TreeMap<String, Boolean>();
         try {
            client.get(new FeedDestination() {

               public void onFeed(Document feedDoc) {
               }

               public void onEntry(Document entryDoc) {
                  Entry entry = new Entry(entryDoc);
                  entry.index();
                  if (entry.getTerm(HOST_TERM) == null) {
                     return;
                  }
                  Text text = entry.getContent();
                  if (text == null || !text.isXML()) {
                     getContext().getLogger().warning("Ignoring host entry with missing or has incorrectly typed content for configuration.");
                     return;
                  }
                  Element hostE = text.getContent();
                  if (hostE == null) {
                     getContext().getLogger().warning("Ignoring host entry with empty content.");
                     return;
                  }

                  Date edited = null;

                  try {
                     edited = entry.getEdited();
                     if (edited == null) {
                        edited = entry.getUpdated();
                     }
                  } catch (ParseException ex) {
                     getContext().getLogger().warning("Ignoring host entry with malformed date in updated or edited element: " + ex.getMessage());
                     return;
                  }

                  if (edited == null) {
                     getContext().getLogger().warning("Ignoring host entry without updated or edited element.");
                     return;
                  }

                  found.put(entry.getId(), Boolean.TRUE);

                  ConfiguredHost autoHost = hosts.get(entry.getId());
                  if (autoHost==null) {
                     getLogger().info("New host detected in entry "+entry.getId());
                  } else if (autoHost.edited.getTime() < edited.getTime()) {
                     // the entry has changed, so delete
                     getContext().getLogger().info("Entry changed for host " + autoHost.getVirtualHost().getHostDomain() + ", reconfiguring.");
                     getHosts().remove(autoHost.getVirtualHost());
                     autoHost = null;
                  }

                  if (autoHost != null) {
                     autoHost.check();
                     return;
                  }

                  // Create configuration
                  changes = true;

                  try {
                     Configuration.Host host = config.createHost(hostE);

                     String hostName = host.getName();
                     if (hostName == null) {
                        getLogger().severe("Host entry " + entry.getId() + " does not have a host name attribute.");
                        return;
                     }
                     getLogger().info("Auto-configuring host " + host.getName());


                     for (Map<String, ConfiguredHost> confHosts : ifaceHosts.values()) {
                        if (confHosts.get(host.getName()) != null) {
                           getLogger().warning("Ignoring duplicate host for " + host.getName() + " from auto-configuration.");
                           return;
                        }
                     }

                     Context hostContext = getContext().createChildContext();
                    
                     ConfiguredHost confHost = new ConfiguredHost(hostContext, getInternalRouter(),serverConf, host, edited, false);

                     // The auto host should not be in confHosts as it isn't static
                     //confHosts.put(host.getName(), confHost);
                     hosts.put(entry.getId(), confHost);

                     getHosts().add(confHost.getVirtualHost());

                  } catch (XMLException ex) {
                     getLogger().log(Level.SEVERE, "Cannot load host configuration.", ex);
                  }
               }
            });

            // remove all entries that have been deleted
            List<String> toRemove = new ArrayList<String>();
            for (String id : hosts.keySet()) {
               if (found.get(id) == null) {
                  ConfiguredHost autoHost = hosts.get(id);
                  getLogger().info("Removing host " + autoHost.getVirtualHost().getHostDomain());
                  changes = true;
                  toRemove.add(id);
                  getHosts().remove(autoHost.getVirtualHost());
                  confHosts.remove(autoHost.getVirtualHost().getHostDomain());
               }
            }
            for (String id : toRemove) {
               hosts.remove(id);
            }

            if (changes && WebComponent.this.isStarted()) {
               getLogger().info("Updating hosts...");
               WebComponent.this.updateHosts();
               /*
               restarting = true;
               stop();
               start();
               restarting = false;
                */
            }

         } catch (Exception ex) {
            getContext().getLogger().log(Level.SEVERE, "Fatal error while getting auto configuration feed at " + link.getLink(), ex);
         }
         getContext().getLogger().info("Configuration " + link.getLink() + " loaded.");
      }
   }

   class AutoConfProcess implements Runnable {

      boolean run = true;

      public void run() {
         while (run) {
            try {
               for (AutoConfiguration autoconf : autoconfs) {
                  autoconf.configure();
                  if (!run) {
                     break;
                  }
               }
               getLogger().info("Waiting " + (config.getAutoConfigurationCheckWait() / 1000) + "s to check configuration.");
               Thread.currentThread().sleep(config.getAutoConfigurationCheckWait());
               for (Map<String, ConfiguredHost> confHosts : ifaceHosts.values()) {
                  for (ConfiguredHost confHost : confHosts.values()) {
                     if (confHost.isStatic()) {
                        confHost.check();
                     }
                  }
               }
            } catch (InterruptedException ex) {

            }

         }
         getLogger().info("Auto configuration thread exiting.");
      }
   }
   static public String LOG_NAME = "org.atomojo.hosts";
   Configuration config;
   Map<String, Map<String, ConfiguredHost>> ifaceHosts;
   List<AutoConfiguration> autoconfs;
   AutoConfProcess autoconfProc;
   Thread autoconfThread;
   boolean restarting = false;
   boolean hasStaticAutoConf = false;

   /** Creates a new instance of WebComponent */
   public WebComponent(Configuration config) {
      this.config = config;
      this.ifaceHosts = new TreeMap<String, Map<String, ConfiguredHost>>();
      this.autoconfs = new ArrayList<AutoConfiguration>();
      getLogService().setLoggerName(LOG_NAME);

      if (config.getKeyStorePath() != null) {
         getContext().getParameters().add("keystorePath", config.getKeyStorePath().getAbsolutePath());
         getContext().getParameters().add("keystorePassword", config.getKeyStorePassword());
         getContext().getParameters().add("keyPassword", config.getKeyStorePassword());
      }

      /*
      ScriptEngineManager manager = new ScriptEngineManager();
      for (ScriptEngineFactory factory : manager.getEngineFactories()) {
         StringBuilder w = new StringBuilder();
         w.append("\nLanguage Name: " + factory.getLanguageName());
         w.append("\nLanguage Version: " + factory.getLanguageVersion());
         w.append("\nEngine Name: " + factory.getEngineName());
         w.append("\nEngine Version: " + factory.getEngineVersion());
         w.append("\nExtensions:");
         for (String ext : factory.getExtensions()) {
            w.append(" " + ext);
         }
         w.append("\nMedia Types:");
         for (String type : factory.getMimeTypes()) {
            w.append(" " + type);
         }
         w.append("\n\n");
         getLogger().info("Script Engines: " + w.toString());
      }*/

      for (Configuration.Server serverConf : config.getServers()) {
         getContext().getLogger().info(serverConf.getProtocol().getName()+" listening on " + serverConf.getAddress() + ":" + serverConf.getPort());
         Server server = getServers().add(serverConf.getProtocol(), serverConf.getAddress().equals("*") ? null : serverConf.getAddress(), serverConf.getPort());
         if (serverConf.getProtocol().isConfidential()) {
            if (config.getKeyStorePath() != null) {
               server.getContext().getParameters().add("keystorePath", config.getKeyStorePath().getAbsolutePath());
               server.getContext().getParameters().add("keystorePassword", config.getKeyStorePassword());
               server.getContext().getParameters().add("keyPassword", config.getKeyStorePassword());
            }
         }

         Map<String, ConfiguredHost> confHosts = ifaceHosts.get(serverConf.getKey());
         if (confHosts == null) {
            confHosts = new TreeMap<String, ConfiguredHost>();
            ifaceHosts.put(serverConf.getKey(), confHosts);
         }
         // Configure static hosts
         for (String name : serverConf.getHosts().keySet()) {
            final Configuration.Host host = serverConf.getHosts().get(name);
            if (confHosts.get(host.getName()) != null) {
               getLogger().warning("Ignoring duplicate host name " + host.getName());
            } else {
               Context hostContext = getContext().createChildContext();
              
               ConfiguredHost confHost = new ConfiguredHost(hostContext, getInternalRouter(), serverConf, host, new Date(), true);
               confHosts.put(host.getName(), confHost);
               if (host.getLinks().get("autoconf") != null) {
                  hasStaticAutoConf = true;
               }

               getHosts().add(confHost.getVirtualHost());
            }

         }

         // Configure autoconf
         List<Link> autoFeeds = serverConf.getLinks().get("autoconf");
         if (autoFeeds != null) {
            for (Link link : autoFeeds) {
               addAutoConfiguration(serverConf, link);
            }
         }

      }
      this.getDefaultHost().attach(new Restlet() {

         public void handle(Request request, Response response) {
            response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
         }
      });

      // Add the clients
      for (Protocol client : config.getClients()) {
         getClients().add(client);
      }

      for (Server server : getServers()) {
         try {
            server.start();
         } catch (Exception ex) {
            getLogger().log(Level.SEVERE,"Cannot start server.",ex);
         }
      }

   }

   public void addAutoConfiguration(Configuration.Server server, Link link) {
      AutoConfiguration autoconf = new AutoConfiguration(server, link);
      autoconfs.add(autoconf);
   }

   public void start()
      throws Exception
   {
      super.start();
      if (!restarting) {
         if (autoconfs.size() > 0 || hasStaticAutoConf) {
            getLogger().info("Starting auto-configuration process...");
            autoconfProc = new AutoConfProcess();
            autoconfThread = new Thread(autoconfProc);
            autoconfThread.start();
            getLogger().info("...started.");
         } else {
            autoconfProc = null;
         }
      }
   }

   public void stop()
      throws Exception
   {
      if (!restarting) {
         if (autoconfProc != null) {
            getLogger().info("Stopping auto-configuration process...");
            autoconfProc.run = false;
            synchronized (autoconfThread) {
               autoconfThread.interrupt();
            }
            autoconfThread.join(2000);
            getLogger().info("...stopped.");
         }
      }
      super.stop();
   }
}
TOP

Related Classes of org.atomojo.server.WebComponent

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.