Package railo.runtime.gateway

Source Code of railo.runtime.gateway.GatewayEngineImpl

package railo.runtime.gateway;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;

import railo.commons.io.DevNullOutputStream;
import railo.commons.io.log.Log;
import railo.commons.lang.ClassException;
import railo.commons.lang.Md5;
import railo.commons.lang.Pair;
import railo.loader.util.Util;
import railo.runtime.CFMLFactory;
import railo.runtime.Component;
import railo.runtime.ComponentPage;
import railo.runtime.PageContext;
import railo.runtime.PageContextImpl;
import railo.runtime.config.Config;
import railo.runtime.config.ConfigWeb;
import railo.runtime.config.ConfigWebImpl;
import railo.runtime.engine.ThreadLocalPageContext;
import railo.runtime.exp.ExpressionException;
import railo.runtime.exp.PageException;
import railo.runtime.exp.PageRuntimeException;
import railo.runtime.op.Caster;
import railo.runtime.thread.ThreadUtil;
import railo.runtime.type.Collection;
import railo.runtime.type.KeyImpl;
import railo.runtime.type.Struct;
import railo.runtime.type.StructImpl;
import railo.runtime.type.util.KeyConstants;

public class GatewayEngineImpl implements GatewayEnginePro {

  private static final Object OBJ = new Object();

  private static final Collection.Key AMF_FORWARD = KeyImpl.init("AMF-Forward");

  private Map<String,GatewayEntry> entries=new HashMap<String,GatewayEntry>();
  private ConfigWeb config;
  private Log log;

 
  public GatewayEngineImpl(ConfigWeb config){
    this.config=config;
    this.log=((ConfigWebImpl)config).getGatewayLogger();
   
  }
 
  public void addEntries(Config config,Map<String, GatewayEntry> entries) throws ClassException, PageException,IOException {
    Iterator<Entry<String, GatewayEntry>> it = entries.entrySet().iterator();
    while(it.hasNext()){
      addEntry(config,it.next().getValue());
    }
  }

  public void addEntry(Config config,GatewayEntry ge) throws ClassException, PageException,IOException {
    String id=ge.getId().toLowerCase().trim();
    GatewayEntry existing=entries.get(id);
    GatewayPro g=null;
   
    // does not exist
    if(existing==null) {
      entries.put(id,load(config,ge));
    }
    // exist but changed
    else if(!existing.equals(ge)){
      g=existing.getGateway();
      if(g.getState()==GatewayPro.RUNNING) g.doStop();
      entries.put(id,load(config,ge));
    }
    // not changed
    //else print.out("untouched:"+id);
  }

  private GatewayEntry load(Config config,GatewayEntry ge) throws ClassException,PageException {
    ge.createGateway(config);
    return ge;
  }

  /**
   * @return the entries
   */
  public Map<String,GatewayEntry> getEntries() {
    return entries;
  }

  public void remove(GatewayEntry ge) {
    String id=ge.getId().toLowerCase().trim();
    GatewayEntry existing=entries.remove(id);
    GatewayPro g=null;
   
    // does not exist
    if(existing!=null) {
      g=existing.getGateway();
      try{
        if(g.getState()==GatewayPro.RUNNING) g.doStop();
      }
      catch(Throwable t){}
    }
  }

  /**
   * get the state of gateway
   * @param gatewayId
   * @return
   * @throws PageException
   */
  public int getState(String gatewayId) throws PageException {
    return getGateway(gatewayId).getState();
  }
 
  /**
   * get helper object
   * @param gatewayId
   * @return
   * @throws PageException
   */
  public Object getHelper(String gatewayId) throws PageException {
    return getGateway(gatewayId).getHelper();
  }

  /**
   * send the message to the gateway
   * @param gatewayId
   * @param data
   * @return
   * @throws PageException
   */
  public String sendMessage(String gatewayId, Struct data) throws PageException,IOException {
    GatewayPro g = getGateway(gatewayId);
    if(g.getState()!=GatewayPro.RUNNING) throw new GatewayException("Gateway ["+gatewayId+"] is not running");
    return g.sendMessage(data);
  }
 
  /**
   * start the gateway
   * @param gatewayId
   * @throws PageException
   */
  public void start(String gatewayId) throws PageException {
    executeThread(gatewayId,GatewayThread.START);
  }
  private void start(GatewayPro gateway) {
    executeThread(gateway,GatewayThread.START);
  }

  /**
   * stop the gateway
   * @param gatewayId
   * @throws PageException
   */
  public void stop(String gatewayId) throws PageException {
    executeThread(gatewayId,GatewayThread.STOP);
  }
  private void stop(GatewayPro gateway) {
    executeThread(gateway,GatewayThread.STOP);
  }
 
 


  public void reset() {
    Iterator<Entry<String, GatewayEntry>> it = entries.entrySet().iterator();
    Entry<String, GatewayEntry> entry;
    GatewayEntry ge;
    GatewayPro g;
    while(it.hasNext()){
      entry = it.next();
      ge = entry.getValue();
      g=ge.getGateway();
      if(g.getState()==GatewayPro.RUNNING) {
        try {
          g.doStop();
        } catch (IOException e) {
          log(g, LOGLEVEL_ERROR, e.getMessage());
        }
      }
      if(ge.getStartupMode()==GatewayEntry.STARTUP_MODE_AUTOMATIC)
        start(g);
     
    }
  }

  public synchronized void clear() {
    Iterator<Entry<String, GatewayEntry>> it = entries.entrySet().iterator();
    Entry<String, GatewayEntry> entry;
    while(it.hasNext()){
      entry = it.next();
      if(entry.getValue().getGateway().getState()==GatewayPro.RUNNING)
        stop(entry.getValue().getGateway());
    }
    entries.clear();
  }
 
  /**
   * restart the gateway
   * @param gatewayId
   * @throws PageException
   */
  public void restart(String gatewayId) throws PageException {
    executeThread(gatewayId,GatewayThread.RESTART);
  }
 
  private GatewayPro getGateway(String gatewayId) throws PageException {
    return getGatewayEntry(gatewayId).getGateway();
  }
 
  private GatewayEntry getGatewayEntry(String gatewayId) throws PageException {
    String id=gatewayId.toLowerCase().trim();
    GatewayEntry ge=entries.get(id);
    if(ge!=null) return ge;
   
    // create list
    Iterator<String> it = entries.keySet().iterator();
    StringBuilder sb=new StringBuilder();
    while(it.hasNext()){
      if(sb.length()>0) sb.append(", ");
      sb.append(it.next());
    }
   
    throw new ExpressionException("there is no gateway instance with id ["+gatewayId+"], available gateway instances are ["+sb+"]");
  }
  private GatewayEntry getGatewayEntry(GatewayPro gateway)  {
    String gatewayId=gateway.getId();
    // it must exist, because it only can come from here
    return entries.get(gatewayId);
  }
 
  private void executeThread(String gatewayId, int action) throws PageException {
    new GatewayThread(this,getGateway(gatewayId),action).start();
  }

  private void executeThread(GatewayPro g, int action) {
    new GatewayThread(this,g,action).start();
  }
 
 
 

  public static int toIntState(String state, int defaultValue) {
    state=state.trim().toLowerCase();
    if("running".equals(state))  return GatewayPro.RUNNING;
    if("started".equals(state)) return GatewayPro.RUNNING;
    if("run".equals(state))   return GatewayPro.RUNNING;
   
    if("failed".equals(state))   return GatewayPro.FAILED;
    if("starting".equals(state))return GatewayPro.STARTING;
    if("stopped".equals(state)) return GatewayPro.STOPPED;
    if("stopping".equals(state))return GatewayPro.STOPPING;
   
    return defaultValue;
  }
 
  public static String toStringState(int state, String defaultValue) {
    if(GatewayPro.RUNNING==statereturn "running";
    if(GatewayPro.FAILED==statereturn "failed";
    if(GatewayPro.STOPPED==statereturn "stopped";
    if(GatewayPro.STOPPING==statereturn "stopping";
    if(GatewayPro.STARTING==statereturn "starting";
     
    return defaultValue;
  }

  public boolean invokeListener(GatewayPro gateway, String method, Map data) {// FUTUTE add generic type to interface
    return invokeListener(gateway.getId(), method, data);
  }

  public boolean invokeListener(String gatewayId, String method, Map data) {// do not add this method to loade, it can be removed with Railo 5
    data=GatewayUtil.toCFML(data);
   
    GatewayEntry entry;
    try {
      entry = getGatewayEntry(gatewayId);
    }
    catch (PageException pe) {
      throw new PageRuntimeException(pe);
    }
    String cfcPath = entry.getListenerCfcPath();
    if(!Util.isEmpty(cfcPath,true)){
      try {
        if(!callOneWay(cfcPath,gatewayId, method, Caster.toStruct(data,null,false), false))
          log(gatewayId,LOGLEVEL_ERROR, "function ["+method+"] does not exist in cfc ["+toRequestURI(cfcPath)+"]");
        else
          return true;
      }
      catch (PageException e) {
        e.printStackTrace();
        log(gatewayId,LOGLEVEL_ERROR, e.getMessage());
      }
    }
    else
      log(gatewayId,LOGLEVEL_ERROR, "there is no listener cfc defined");
    return false;
  }
 
  public Object callEL(String cfcPath,String id,String functionName,Struct arguments, boolean cfcPeristent, Object defaultValue)  {
    try {
      return call(cfcPath,id,functionName, arguments,cfcPeristent, defaultValue);
    } catch (PageException e) {
      return defaultValue;
    }
  }
 
  public boolean callOneWay(String cfcPath,String id,String functionName,Struct arguments, boolean cfcPeristent) throws PageException {
    return call(cfcPath,id,functionName, arguments,cfcPeristent, OBJ)!=OBJ;
  }

  public Object getComponent(String cfcPath,String id) throws PageException  {
    String requestURI=toRequestURI(cfcPath);
   
    PageContext oldPC = ThreadLocalPageContext.get();
    PageContextImpl pc = createPageContext(requestURI,id, "init", null, false);
    try {
      ThreadLocalPageContext.register(pc);
      return getCFC(pc,requestURI);
    }
    finally{
      CFMLFactory f = config.getFactory();
      f.releasePageContext(pc);
      ThreadLocalPageContext.register(oldPC);
    }
  }

  public Object call(String cfcPath,String id,String functionName,Struct arguments, boolean cfcPeristent, Object defaultValue) throws PageException  {
    String requestURI=toRequestURI(cfcPath);
   
    PageContext oldPC = ThreadLocalPageContext.get();
    PageContextImpl pc=createPageContext(requestURI,id,functionName,arguments,cfcPeristent);
   
    try {
      ThreadLocalPageContext.register(pc);
      Component cfc=getCFC(pc,requestURI);
      if(cfc.containsKey(functionName)){
        pc.execute(requestURI, true,false);
        // Result
        return pc.variablesScope().get(AMF_FORWARD,null);
      }
    }
    finally{
      CFMLFactory f = config.getFactory();
      f.releasePageContext(pc);
      ThreadLocalPageContext.register(oldPC);
    }
    return defaultValue;
  }

  private Component getCFC(PageContextImpl pc,String requestURI) throws PageException  {
    HttpServletRequest req = pc.getHttpServletRequest();
    try {
      req.setAttribute("client", "railo-gateway-1-0");
      req.setAttribute("call-type", "store-only");
      pc.execute(requestURI, true,false);
      return (Component) req.getAttribute("component");
    }
    finally {
      req.removeAttribute("call-type");
      req.removeAttribute("component");
    }
  }
 
  private PageContextImpl createPageContext(String requestURI,String id,String functionName, Struct arguments, boolean cfcPeristent) throws PageException {
    Struct attrs=new StructImpl();
    String remotePersisId;
    try {
      remotePersisId=Md5.getDigestAsString(requestURI+id);
    } catch (IOException e) {
      throw Caster.toPageException(e);
    }
    PageContextImpl pc = ThreadUtil.createPageContext(
        config,
        DevNullOutputStream.DEV_NULL_OUTPUT_STREAM,
        "localhost",
        requestURI,
        "method="+functionName+(cfcPeristent?"&"+ComponentPage.REMOTE_PERSISTENT_ID+"="+remotePersisId:""),
        null,
        new Pair[]{new Pair<String,Object>("AMF-Forward","true")},
        null,
        attrs);
   
    pc.setRequestTimeout(999999999999999999L);
    pc.setGatewayContext(true);
    if(arguments!=null)attrs.setEL(KeyConstants._argumentCollection, arguments);
    attrs.setEL("client", "railo-gateway-1-0");
    return pc;
  }

  public String toRequestURI(String cfcPath) {
    return GatewayUtil.toRequestURI(cfcPath);
  }

  @Override
  public void log(GatewayPro gateway, int level, String message) {
    log(gateway.getId(), level, message);
  }
 
  public void log(String gatewayId, int level, String message) {
    int l=level;
    switch(level){
    case LOGLEVEL_INFO:l=Log.LEVEL_INFO;
    break;
    case LOGLEVEL_DEBUG:l=Log.LEVEL_DEBUG;
    break;
    case LOGLEVEL_ERROR:l=Log.LEVEL_ERROR;
    break;
    case LOGLEVEL_FATAL:l=Log.LEVEL_FATAL;
    break;
    case LOGLEVEL_WARN:l=Log.LEVEL_WARN;
    break;
    }
    log.log(l, "Gateway:"+gatewayId, message);
  }
 

  private Map<String, Component> persistentRemoteCFC;
  public Component getPersistentRemoteCFC(String id) {
    if(persistentRemoteCFC==null) persistentRemoteCFC=new HashMap<String,Component>();
    return persistentRemoteCFC.get(id);
  }
 
  public Component setPersistentRemoteCFC(String id, Component cfc) {
    if(persistentRemoteCFC==null) persistentRemoteCFC=new HashMap<String,Component>();
    return persistentRemoteCFC.put(id,cfc);
  }
}
  
TOP

Related Classes of railo.runtime.gateway.GatewayEngineImpl

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.