예제 #1
0
  /**
   * @param aConfiguration
   * @throws Exception
   */
  public ExtProcessPlugIn(PluginConfiguration aConfiguration) throws Exception {
    super(aConfiguration);
    if (mLog.isDebugEnabled()) {
      mLog.debug("Instantiating External Process plug-in...");
    }
    // specify default name space for file system plugin
    this.setNamespace(NS_EXTPROCESS);

    try {
      mBeanFactory = getConfigBeanFactory();
      if (null == mBeanFactory) {
        mLog.error(
            "No or invalid spring configuration for external process plug-in, some features may not be available.");
      } else {
        mSettings = (Settings) mBeanFactory.getBean("org.jwebsocket.plugins.extprocess.settings");
        // replace all alias values with environment variables
        Map<String, String> lAllowedProgs = mSettings.getAllowedProgs();
        for (Entry<String, String> lEntry : lAllowedProgs.entrySet()) {
          lEntry.setValue(Tools.expandEnvVarsAndProps(lEntry.getValue()));
        }
        if (mLog.isInfoEnabled()) {
          mLog.info("External Process plug-in successfully instantiated.");
        }
      }
    } catch (BeansException lEx) {
      mLog.error(Logging.getSimpleExceptionMessage(lEx, "instantiating ExtProcess plug-in"));
      throw lEx;
    }
  }
예제 #2
0
  /** @throws ServletException */
  @Override
  public void init() throws ServletException {
    if (JWebSocketInstance.STARTED == JWebSocketInstance.getStatus()) {
      mLog = Logging.getLogger();

      String lEngineId = getInitParameter(ServletUtils.SERVLET_ENGINE_CONFIG_KEY);
      if (null == lEngineId) {
        lEngineId = "http0";
      }
      mEngine = (HTTPEngine) JWebSocketFactory.getEngine(lEngineId);
      mConnectorsManager = mEngine.getConnectorsManager();

      super.init();
      if (mLog.isDebugEnabled()) {
        mLog.debug("Servlet successfully initialized.");
      }
    } else {
      if (!mServerStartupTimeoutConsumed) {
        try {
          // waiting 3 seconds for the server startup
          log(
              "The request has been paused because the jWebSocket server is not started."
                  + " Waiting for 3 seconds the jWebSocket server startup...");
          Thread.sleep(3000);
        } catch (InterruptedException lEx) {
          throw new ServletException(lEx);
        }
        mServerStartupTimeoutConsumed = true;
        init();
      }

      String lErrMsg =
          "The jWebSocket server startup is taking too long or has failed. "
              + "Request cannot be processed in this moment!";
      log(lErrMsg);
      throw new ServletException(lErrMsg);
    }
  }
/**
 * An object that does the process of loading configuration, initialization of the jWebSocket server
 * system.
 *
 * @author puran
 * @version $Id: JWebSocketLoader.java 345 2010-04-10 20:03:48Z fivefeetfurther$
 */
public final class JWebSocketLoader {

  private static Logger mLog = Logging.getLogger();;
  private JWebSocketConfigHandler mConfigHandler = new JWebSocketConfigHandler();

  /**
   * Initialize the jWebSocket Server system
   *
   * @param aConfigPath the overridden path to xml config file
   * @return the initializer object
   * @throws WebSocketException if there's an exception while initialization
   */
  public final WebSocketInitializer initialize(String aConfigPath) throws WebSocketException {
    String lConfigPath;
    if (aConfigPath != null && !"".equals(aConfigPath)) {
      lConfigPath = Tools.expandEnvVarsAndProps(aConfigPath);
      if (mLog.isDebugEnabled()) {
        mLog.debug("Initializing: Using config file '" + aConfigPath + "'...");
      }
    } else {
      lConfigPath = JWebSocketConfig.getConfigPath();
    }
    if (lConfigPath == null) {
      throw new WebSocketException(
          "Either "
              + JWebSocketServerConstants.JWEBSOCKET_HOME
              + " variable is not set"
              + " or jWebSocket.xml file does neither exist at ${"
              + JWebSocketServerConstants.JWEBSOCKET_HOME
              + "}/conf nor at ${CLASSPATH}/conf.");
    }
    // load the entire settings from the configuration xml file
    JWebSocketConfig lConfig = loadConfiguration(lConfigPath);

    // initialize security by using config settings
    SecurityFactory.initFromConfig(lConfig);
    WebSocketInitializer lInitializer = new JWebSocketXmlConfigInitializer(lConfig);
    return lInitializer;
  }

  /**
   * Load all the configurations based on jWebSocket.xml file at the given <tt>configFilePath</tt>
   * location.
   *
   * @param aConfigPath the path to jWebSocket.xml file
   * @return the web socket config object with all the configuration
   * @throws WebSocketException if there's any while loading configuration
   */
  public JWebSocketConfig loadConfiguration(final String aConfigPath) throws WebSocketException {
    JWebSocketConfig lConfig = null;
    String lMsg;
    try {
      InputStream lIS;
      if (JWebSocketConfig.isLoadConfigFromResource()) {
        if (mLog.isDebugEnabled()) {
          mLog.debug("Loading configuration from resource '" + aConfigPath + "...");
        }
        lIS = this.getClass().getResourceAsStream("/" + aConfigPath);
      } else {
        if (mLog.isDebugEnabled()) {
          mLog.debug("Loading configuration from file '" + aConfigPath + "...");
        }
        File lFile = new File(aConfigPath);
        lIS = new FileInputStream(lFile);
      }
      XMLInputFactory lFactory = XMLInputFactory.newInstance();
      XMLStreamReader lStreamReader = null;
      lStreamReader = lFactory.createXMLStreamReader(lIS);
      lConfig = (JWebSocketConfig) mConfigHandler.processConfig(lStreamReader);
      if (mLog.isInfoEnabled()) {
        mLog.info("Configuration successfully loaded from '" + aConfigPath + "'.");
      }
    } catch (XMLStreamException lEx) {
      lMsg =
          lEx.getClass().getSimpleName()
              + " occurred while creating XML stream ("
              + aConfigPath
              + "): "
              + lEx.getMessage()
              + ".";
      throw new WebSocketException(lMsg);
    } catch (FileNotFoundException lEx) {
      lMsg =
          "jWebSocket config file not found while creating XML stream ("
              + aConfigPath
              + "): "
              + lEx.getMessage()
              + ".";
      throw new WebSocketException(lMsg);
    }
    return lConfig;
  }
}
예제 #4
0
/** @author Osvaldo Aguilar Lauzurique */
public abstract class BaseQuota implements IQuota {

  /** */
  protected static Logger mLog = Logging.getLogger();

  /** */
  protected IQuotaStorage mQuotaStorage;

  /** */
  protected String mQuotaType;

  /** */
  protected String mQuotaIdentifier;

  /** */
  protected long mDefaultReduceValue;

  /** */
  protected long mDefaultIncrease;

  @Override
  public long getDefaultReduceValue() {
    return mDefaultReduceValue;
  }

  /** @return */
  public long getDefaultIncrease() {
    return mDefaultIncrease;
  }

  /** @param aDefaultReduceValue */
  public void setDefaultReduceValue(long aDefaultReduceValue) {
    this.mDefaultReduceValue = aDefaultReduceValue;
  }

  /** @param mQuotaIdentifier */
  public void setQuotaIdentifier(String mQuotaIdentifier) {
    this.mQuotaIdentifier = mQuotaIdentifier;
  }

  /** @param aDefaultIncrease */
  public void setDefaultIncreaseValue(long aDefaultIncrease) {
    this.mDefaultIncrease = aDefaultIncrease;
  }

  /** @param aQuotaType */
  public void setQuotaType(String aQuotaType) {
    this.mQuotaType = aQuotaType;
  }

  @Override
  public IQuotaStorage getStorage() {
    return mQuotaStorage;
  }

  @Override
  public String getType() {
    return mQuotaType;
  }

  @Override
  public void setStorage(IQuotaStorage aQuotaStorage) {
    this.mQuotaStorage = aQuotaStorage;
    try {
      this.mQuotaStorage.initialize();
    } catch (Exception aExp) {
      mLog.error(
          "Error to initialize the quota storage, the following"
              + " error was capture on the server: "
              + aExp.getMessage());
    }
  }

  /**
   * @param aInstance
   * @param aNameSpace
   * @param aInstanceType
   * @param aActions
   * @return
   */
  @Override
  public IQuotaSingleInstance getQuota(
      String aInstance, String aNameSpace, String aInstanceType, String aActions) {

    IQuotaSingleInstance lQResult;
    String lUuid;
    try {
      lUuid = getQuotaUuid(mQuotaIdentifier, aNameSpace, aInstance, aInstanceType, aActions);
    } catch (Exception e) {
      lUuid = "not-found";
    }

    // Asking if the user has as part of a group quota that belong to a group.
    if (lUuid.equals("not-found") && aInstanceType.equals("User")) {

      List<IQuotaSingleInstance> lQuotasGroup =
          mQuotaStorage.getQuotasByIdentifierNSInstanceType(mQuotaIdentifier, aNameSpace, "Group");
      lQResult = findQuotaByInstance(lQuotasGroup, aInstance, aActions);

      if (lQResult == null) {
        List<IQuotaSingleInstance> lQuotasUser =
            mQuotaStorage.getQuotasByIdentifierNSInstanceType(mQuotaIdentifier, aNameSpace, "User");
        lQResult = findQuotaByInstance(lQuotasUser, aInstance, aActions);
      }
      return lQResult;
    } else {
      return getQuota(lUuid);
    }
  }

  /**
   * @param aInstance
   * @param aNameSpace
   * @param aInstanceType
   * @return
   */
  @Override
  public List<IQuotaSingleInstance> getQuotas(
      String aInstance, String aNameSpace, String aInstanceType) {
    List<IQuotaSingleInstance> lQuotasNs =
        mQuotaStorage.getQuotasByNs(mQuotaIdentifier, aNameSpace);

    // if there is not quota for this namespace, there will not exists a quota for the instance
    if (lQuotasNs.isEmpty()) {
      return lQuotasNs;
    }

    return (FastList<IQuotaSingleInstance>) findQuotasByInstance(lQuotasNs, aInstance);
  }

  /**
   * get a IQuotaSingleInstance list and an string with the instance and return all quotas about
   * belong to this instance.
   *
   * @return
   */
  private List<IQuotaSingleInstance> findQuotasByInstance(
      List<IQuotaSingleInstance> aQuotas, String aInstance) {

    List<IQuotaSingleInstance> lQResult = new FastList<IQuotaSingleInstance>();

    if (aQuotas.size() > 0) {
      IQuotaSingleInstance lQtmp = null;
      for (Iterator<IQuotaSingleInstance> it = aQuotas.iterator(); it.hasNext(); ) {
        IQuotaSingleInstance lQuotaSingle = it.next();
        QuotaChildSI lChild;
        lChild = lQuotaSingle.getChildQuota(aInstance);
        if (null != lChild) {
          if (lQuotaSingle.getInstanceType().equals("Group")) {

            lQtmp =
                QuotaHelper.factorySingleInstance(
                    lChild.getValue(),
                    lChild.getInstance(),
                    lChild.getUuid(),
                    lQuotaSingle.getNamespace(),
                    lQuotaSingle.getQuotaType(),
                    lQuotaSingle.getQuotaIdentifier(),
                    lChild.getInstanceType(),
                    lQuotaSingle.getActions());
          }

          if (lQuotaSingle.getInstanceType().equals("User")) {

            lQtmp =
                QuotaHelper.factorySingleInstance(
                    lQuotaSingle.getvalue(),
                    lChild.getInstance(),
                    lChild.getUuid(),
                    lQuotaSingle.getNamespace(),
                    lQuotaSingle.getQuotaType(),
                    lQuotaSingle.getQuotaIdentifier(),
                    lChild.getInstanceType(),
                    lQuotaSingle.getActions());
          }

          if (lQtmp != null) {
            lQResult.add(lQtmp);
          }
        }
      }
    }
    return lQResult;
  }

  /**
   * get a IQuotaSingleInstance list and an string with the instanceType and return the
   * IQuotaSingleInstance.
   *
   * @return
   */
  private IQuotaSingleInstance findQuotaByInstance(
      List<IQuotaSingleInstance> aQuotas, String aInstance, String aActions) {

    IQuotaSingleInstance lQResult = null;

    for (Iterator<IQuotaSingleInstance> it = aQuotas.iterator(); it.hasNext(); ) {
      IQuotaSingleInstance lQuotaSingle = it.next();
      QuotaChildSI lChild;
      lChild = lQuotaSingle.getChildQuota(aInstance);
      if (null != lChild) {
        if (!lQuotaSingle.getActions().equals(aActions)) {
          continue;
        }
        if (lQuotaSingle.getInstanceType().equals("Group")) {

          lQResult =
              QuotaHelper.factorySingleInstance(
                  lChild.getValue(),
                  lChild.getInstance(),
                  lChild.getUuid(),
                  lQuotaSingle.getNamespace(),
                  lQuotaSingle.getQuotaType(),
                  lQuotaSingle.getQuotaIdentifier(),
                  lChild.getInstanceType(),
                  lQuotaSingle.getActions());
        }

        if (lQuotaSingle.getInstanceType().equals("User")) {

          lQResult =
              QuotaHelper.factorySingleInstance(
                  lQuotaSingle.getvalue(),
                  lChild.getInstance(),
                  lChild.getUuid(),
                  lQuotaSingle.getNamespace(),
                  lQuotaSingle.getQuotaType(),
                  lQuotaSingle.getQuotaIdentifier(),
                  lChild.getInstanceType(),
                  lQuotaSingle.getActions());
        }

        return lQResult;
      }
    }
    return null;
  }

  /**
   * @param aUuid
   * @return
   */
  @Override
  public IQuotaSingleInstance getQuota(String aUuid) {

    IQuotaSingleInstance lQuotaInstance =
        (IQuotaSingleInstance) mQuotaStorage.getQuotaByUuid(aUuid);
    return lQuotaInstance;
  }

  /**
   * @param aUuid
   * @param aInstance
   * @return
   */
  @Override
  public IQuotaSingleInstance getQuota(String aUuid, String aInstance) {

    IQuotaSingleInstance lQuotaInstance =
        (IQuotaSingleInstance) mQuotaStorage.getQuotaByUuid(aUuid);

    if (lQuotaInstance.getInstance().equals(aInstance)) {
      return lQuotaInstance;
    } else {

      QuotaChildSI lQuotaChild = lQuotaInstance.getChildQuota(aInstance);
      if (null != lQuotaChild) {

        IQuotaSingleInstance lSingle =
            new QuotaBaseInstance(
                lQuotaChild.getValue(),
                aInstance,
                aUuid,
                lQuotaInstance.getNamespace(),
                lQuotaInstance.getQuotaType(),
                lQuotaInstance.getQuotaIdentifier(),
                lQuotaChild.getInstanceType(),
                lQuotaInstance.getActions());

        return lSingle;
      }
    }
    return null;
  }

  /** @return */
  @Override
  public String getIdentifier() {
    return mQuotaIdentifier;
  }

  /**
   * @param aUuid
   * @param aAmount
   * @return
   */
  @Override
  public abstract long reduceQuota(String aUuid, long aAmount);

  /**
   * @param aInstance
   * @param aNameSpace
   * @param aInstanceType
   * @param aActions
   * @param aAmount
   * @return
   */
  @Override
  public long reduceQuota(
      String aInstance, String aNameSpace, String aInstanceType, String aActions, long aAmount) {

    IQuotaSingleInstance lQSingle = getQuota(aInstance, aNameSpace, aInstanceType, aActions);
    long lResult = -1;
    if (lQSingle != null) {
      long lReduce = lQSingle.getvalue() - aAmount;
      if (lReduce <= -1) {
        lReduce = -1;
      }

      lResult =
          setQuota(
              lQSingle.getInstance(), aNameSpace, lQSingle.getInstanceType(), aActions, lReduce);
    }
    return lResult;
  }

  /**
   * @param aUuid
   * @return
   */
  @Override
  public long reduceQuota(String aUuid) {
    return reduceQuota(aUuid, mDefaultReduceValue);
  }

  /**
   * @param aUuid
   * @return
   */
  @Override
  public String getActions(String aUuid) {
    String lActions = this.getStorage().getActions(aUuid);
    return lActions;
  }

  /**
   * @param aInstance
   * @param aNameSpace
   * @param aInstanceType
   * @param aActions
   * @param aAmount
   * @return
   */
  @Override
  public long increaseQuota(
      String aInstance, String aNameSpace, String aInstanceType, String aActions, long aAmount) {
    IQuotaSingleInstance lQSingle = getQuota(aInstance, aNameSpace, aInstanceType, aActions);
    long lResult = -1;
    if (lQSingle != null) {
      long lReduce = lQSingle.getvalue() + aAmount;
      lResult =
          setQuota(
              lQSingle.getInstance(), aNameSpace, lQSingle.getInstanceType(), aActions, lReduce);
    }
    return lResult;
  }

  /**
   * @param aUuid
   * @param aAmount
   * @return
   */
  @Override
  public long increaseQuota(String aUuid, long aAmount) {
    long lValue = getQuota(aUuid).getvalue();
    return getStorage().update(aUuid, lValue + aAmount);
  }

  /**
   * @param aInstance
   * @param aNameSpace
   * @param aInstanceType
   * @param aActions
   * @param aAmount
   * @return
   */
  @Override
  public long setQuota(
      String aInstance, String aNameSpace, String aInstanceType, String aActions, long aAmount) {

    IQuotaSingleInstance lQSingle = getQuota(aInstance, aNameSpace, aInstanceType, aActions);
    // if the instanceType request is Group then update the father quota.
    if (lQSingle.getInstanceType().equals("Group") && aInstanceType.equals("Group")) {
      return setQuota(lQSingle.getUuid(), aAmount);
    }

    /**
     * if the quota type of the getQuota method is User, it is possible that this quota be part of a
     * father quota.
     */
    if (lQSingle.getInstanceType().equals("User")) {
      if (mQuotaStorage.quotaExist(
          aNameSpace, mQuotaIdentifier, lQSingle.getInstance(), lQSingle.getActions())) {
        return setQuota(lQSingle.getUuid(), aAmount);
      } else {
        IQuotaSingleInstance lSingleInstance = mQuotaStorage.getQuotaByUuid(lQSingle.getUuid());
        QuotaChildSI lQChild = lSingleInstance.getChildQuota(lQSingle.getInstance());
        lQChild.setValue(aAmount);

        if (lSingleInstance.getInstanceType().equals("User")) {
          return mQuotaStorage.update(lSingleInstance.getUuid(), lQChild.getValue());
        }
        return mQuotaStorage.update(lQChild);
      }
    } else {
      return -1;
    }
  }

  /**
   * @param aUuid
   * @param aAmount
   * @return
   */
  @Override
  public long setQuota(String aUuid, long aAmount) {
    return getStorage().update(aUuid, aAmount);
  }

  /**
   * @param aUuid
   * @param aInstance
   * @param aInstanceType
   * @throws Exception
   */
  @Override
  public void register(String aUuid, String aInstance, String aInstanceType) throws Exception {

    if (!mQuotaStorage.quotaExist(aUuid)) {
      throw new ExceptionQuotaNotFound(aUuid);
    }
    // Creating the child Quota
    IQuotaSingleInstance lSingleInstance = mQuotaStorage.getQuotaByUuid(aUuid);

    if (lSingleInstance.getInstance().equals(aInstance)) {
      throw new ExceptionQuotaAlreadyExist(aInstance);
    }

    QuotaChildSI lChildQuota = new QuotaChildSI(aInstance, aUuid, aInstanceType);

    // if a register quota occur over a quota with InstanceType user
    // The quota is shared between the users of this quota, by this reason
    // The quota is register to the parent quota with 0 as their own value.
    if (lSingleInstance.getInstanceType().equals("User")) {
      lChildQuota.setValue(0);
    } else {
      lChildQuota.setValue(lSingleInstance.getvalue());
    }
    boolean lResult;

    lResult = lSingleInstance.addChildQuota(lChildQuota);

    if (lResult == true) {
      lResult = mQuotaStorage.save(lChildQuota);

    } else {
      throw new ExceptionQuotaAlreadyExist(aInstance);
    }
  }

  /**
   * @param aInstance
   * @param aNameSpace
   * @param aUuid
   * @param aAmount
   * @param aInstanceType
   * @param aQuotaType
   * @param aQuotaIdentifier
   * @param aActions
   * @throws Exception
   */
  @Override
  public void create(
      String aInstance,
      String aNameSpace,
      String aUuid,
      long aAmount,
      String aInstanceType,
      String aQuotaType,
      String aQuotaIdentifier,
      String aActions)
      throws Exception {

    if (mQuotaStorage.quotaExist(aNameSpace, aQuotaIdentifier, aInstance, aActions)) {

      throw new ExceptionQuotaAlreadyExist(
          mQuotaStorage.getUuid(aQuotaIdentifier, aNameSpace, aInstance, aInstanceType, aActions));
    }

    IQuotaSingleInstance lSingleQuota;
    lSingleQuota =
        new QuotaCountdownSI(
            aAmount,
            aInstance,
            aUuid,
            aNameSpace,
            aQuotaType,
            aQuotaIdentifier,
            aInstanceType,
            aActions);
    mQuotaStorage.save(lSingleQuota);
  }

  /**
   * @param aInstance
   * @param aUuid
   * @throws ExceptionQuotaNotFound
   */
  @Override
  public void unregister(String aInstance, String aUuid) throws ExceptionQuotaNotFound {

    if (!mQuotaStorage.quotaExist(aUuid)) {
      throw new ExceptionQuotaNotFound(aUuid);
    }
    IQuotaSingleInstance lQSingle = getQuota(aUuid);
    if (lQSingle.getInstance().equals(aInstance)) {
      mQuotaStorage.remove(aUuid, aInstance);
    } else {
      QuotaChildSI lChild = lQSingle.getChildQuota(aInstance);
      if (lChild != null) {
        mQuotaStorage.remove(lChild);
      }
    }
  }

  /**
   * @param aInstance
   * @param aNameSpace
   * @param aInstanceType
   * @param aActions
   * @throws ExceptionQuotaNotFound
   */
  @Override
  public void unregister(String aInstance, String aNameSpace, String aInstanceType, String aActions)
      throws ExceptionQuotaNotFound {

    String lUuid = getQuotaUuid(mQuotaIdentifier, aNameSpace, aInstance, aInstanceType, aActions);

    unregister(lUuid, aInstance);
  }

  /**
   * @param aNamespace
   * @param aId
   * @return
   */
  @Override
  public List<String> getRegisteredInstances(String aNamespace, String aId) {
    return new FastList<String>();
  }

  /**
   * @param aNamespace
   * @return
   */
  @Override
  public List<String> getRegisterdQuotas(String aNamespace) {
    return new FastList<String>();
  }

  /**
   * @param aQuotaIdentifier
   * @param aNamespace
   * @param aInstance
   * @param aInstanceType
   * @param aActions
   * @return
   */
  @Override
  public String getQuotaUuid(
      String aQuotaIdentifier,
      String aNamespace,
      String aInstance,
      String aInstanceType,
      String aActions) {

    try {
      return mQuotaStorage.getUuid(
          aQuotaIdentifier, aNamespace, aInstance, aInstanceType, aActions);
    } catch (ExceptionQuotaNotFound ex) {
      return "not-found";
    }
  }
}
/**
 * This works OK, the only pending question is that the write method of the native OutputStream
 * never gets locked as expected.
 *
 * <p>Advises: - Notify the connector stopped event in a thread pool instead of the same thread -
 * Check the connection state before send a packet
 *
 * @author Rolando Santamaria Maso
 * @author Alexander Schulze
 */
public class TimeoutOutputStreamNIOWriter {

  private static final Logger mLog = Logging.getLogger();
  private static final int DEFAULT_TIME_OUT_TERMINATION_THREAD = 1000;
  /** Singleton Timer instance to control all timeout tasks */
  private static int mTimeout = DEFAULT_TIME_OUT_TERMINATION_THREAD;
  // can be set to "true" for heavy debugging purposes
  private static final boolean mIsDebug = false;
  // the size of this executor service should be adjusted to the maximum
  // of expected client send operations that concurrently might get
  // to a timeout case.
  private static ExecutorService mPool = null;
  private static final Object mPoolSync = new Object();
  private OutputStream mOut = null;
  private InputStream mIn = null;
  private WebSocketConnector mConnector = null;
  private static boolean mStarted = false;
  private static Timer mTimer;

  /**
   * @param aNumWorkers
   * @param aTimeout
   */
  public static void start(int aNumWorkers, int aTimeout) {
    mTimer = Tools.getTimer();
    mPool =
        Executors.newFixedThreadPool(
            aNumWorkers,
            new ThreadFactory() {
              @Override
              public Thread newThread(Runnable aRunnable) {
                return new Thread(aRunnable, "jWebSocket TCP-Engine NIO writer");
              }
            });
    mTimeout = aTimeout;
    mStarted = true;
  }

  /** */
  public static void stop() {
    synchronized (mPoolSync) {
      if (mStarted) {
        mPool.shutdownNow();
        mStarted = false;
      }
    }
  }

  /**
   * @param aConnector
   * @param aIn
   * @param aOut
   */
  public TimeoutOutputStreamNIOWriter(
      WebSocketConnector aConnector, InputStream aIn, OutputStream aOut) {
    mConnector = aConnector;
    mIn = aIn;
    mOut = aOut;
  }

  /** @return */
  public static ExecutorService getPool() {
    return mPool;
  }

  /** @param aTimeout */
  public static void setTimeout(int aTimeout) {
    mTimeout = aTimeout;
  }

  /** @return */
  public static int getTimeout() {
    return mTimeout;
  }

  /** Write operation thread to execute write operations in non-blocking mode. */
  class SendOperation implements Runnable {

    private final WebSocketPacket mPacket;
    private boolean mSent = false;

    public InputStream getIn() {
      return mIn;
    }

    public OutputStream getOut() {
      return mOut;
    }

    public boolean isDone() {
      return mSent;
    }

    public SendOperation(WebSocketPacket aDataPacket) {
      mPacket = aDataPacket;
    }

    @Override
    public void run() {
      // @TODO This always is being executed quickly even when the connector get's stopped
      // this sends the packet to the socket output stream
      if (mIsDebug && mLog.isDebugEnabled()) {
        mLog.debug(
            "Physically sending packet to '" + mConnector.getId() + "' under timeout control...");
      }

      // sending packet in blocking mode
      ((TCPConnector) mConnector)._sendPacket(mPacket);

      // this cancels the timeout task in case
      // the send operation did not block for the given timeout
      if (mIsDebug && mLog.isDebugEnabled()) {
        mLog.debug(
            "Cancelling timeout control for '"
                + mConnector.getId()
                + "' because packet had been sent properly...");
      }
      // setting the sent flag to true
      mSent = true;
    }
  }

  /**
   * Send a data packet with timeout control.
   *
   * @param aDataPacket
   */
  public void sendPacket(WebSocketPacket aDataPacket) {
    if (mIsDebug && mLog.isDebugEnabled()) {
      mLog.debug("Scheduling send operation to '" + mConnector.getId() + "'...");
    }

    synchronized (mPoolSync) {
      if (mPool.isTerminated() || mPool.isShutdown()) {
        mLog.warn("Sender thread pool is terminated or shutdown already, skipping send operation.");
        return;
      }

      // create a timer task to send the packet
      final SendOperation lSend = new SendOperation(aDataPacket);

      // create a timeout timer task to cancel the send operation in case of disconnection
      mTimer.schedule(
          new JWSTimerTask() {
            @Override
            public void runTask() {
              try {
                if (!lSend.isDone()) {
                  // close the outbound stream to fire exception
                  // timed out write operation
                  if (mIsDebug && mLog.isDebugEnabled()) {
                    mLog.debug(
                        "Closing stream to '"
                            + mConnector.getId()
                            + "' connector due to timeout...");
                  }
                  lSend.getIn().close();
                  lSend.getOut().close();
                }
              } catch (IOException lEx) {
                // TODO check this
              }
            }
          },
          mTimeout);

      // finally execute the send operation
      mPool.execute(lSend);
    }
  }
}
예제 #6
0
/** @author aschulze */
public class ExtProcessPlugIn extends TokenPlugIn {

  private static final Logger mLog = Logging.getLogger();
  /** */
  public static final String NS_EXTPROCESS =
      JWebSocketServerConstants.NS_BASE + ".plugins.extprocess";

  private static final String VERSION = "1.0.0";
  private static final String VENDOR = JWebSocketCommonConstants.VENDOR_CE;
  private static final String LABEL = "jWebSocket ExtProcessPlugIn";
  private static final String COPYRIGHT = JWebSocketCommonConstants.COPYRIGHT_CE;
  private static final String LICENSE = JWebSocketCommonConstants.LICENSE_CE;
  private static final String DESCRIPTION = "jWebSocket ExtProcessPlugIn - Community Edition";
  /** */
  protected ApplicationContext mBeanFactory;
  /** */
  protected Settings mSettings;

  /**
   * @param aConfiguration
   * @throws Exception
   */
  public ExtProcessPlugIn(PluginConfiguration aConfiguration) throws Exception {
    super(aConfiguration);
    if (mLog.isDebugEnabled()) {
      mLog.debug("Instantiating External Process plug-in...");
    }
    // specify default name space for file system plugin
    this.setNamespace(NS_EXTPROCESS);

    try {
      mBeanFactory = getConfigBeanFactory();
      if (null == mBeanFactory) {
        mLog.error(
            "No or invalid spring configuration for external process plug-in, some features may not be available.");
      } else {
        mSettings = (Settings) mBeanFactory.getBean("org.jwebsocket.plugins.extprocess.settings");
        // replace all alias values with environment variables
        Map<String, String> lAllowedProgs = mSettings.getAllowedProgs();
        for (Entry<String, String> lEntry : lAllowedProgs.entrySet()) {
          lEntry.setValue(Tools.expandEnvVarsAndProps(lEntry.getValue()));
        }
        if (mLog.isInfoEnabled()) {
          mLog.info("External Process plug-in successfully instantiated.");
        }
      }
    } catch (BeansException lEx) {
      mLog.error(Logging.getSimpleExceptionMessage(lEx, "instantiating ExtProcess plug-in"));
      throw lEx;
    }
  }

  @Override
  public String getVersion() {
    return VERSION;
  }

  @Override
  public String getLabel() {
    return LABEL;
  }

  @Override
  public String getDescription() {
    return DESCRIPTION;
  }

  @Override
  public String getVendor() {
    return VENDOR;
  }

  @Override
  public String getCopyright() {
    return COPYRIGHT;
  }

  @Override
  public String getLicense() {
    return LICENSE;
  }

  @Override
  public String getNamespace() {
    return NS_EXTPROCESS;
  }

  @Override
  public synchronized void engineStarted(WebSocketEngine aEngine) {}

  @Override
  public synchronized void engineStopped(WebSocketEngine aEngine) {}

  @Override
  public void processToken(PlugInResponse aResponse, WebSocketConnector aConnector, Token aToken) {
    String lType = aToken.getType();
    String lNS = aToken.getNS();

    if (lType != null && getNamespace().equals(lNS)) {
      if (lType.equals("call")) {
        call(aConnector, aToken);
      }
    }
  }

  @Override
  public Token invoke(WebSocketConnector aConnector, Token aToken) {
    String lType = aToken.getType();
    String lNS = aToken.getNS();

    if (lType != null && getNamespace().equals(lNS)) {
      /*
      if (lType.equals("getFilelist")) {
      return getFilelist(aConnector.getUsername(), aToken);
      } else if (lType.equals("getAliasPath")) {
      String lTargetAlias = aToken.getString("alias");
      Token lToken = TokenFactory.createToken();
      lToken.setString("aliasPath", getAliasPath(aConnector, lTargetAlias));

      return lToken;
      }
      */
    }

    return null;
  }

  private void call(WebSocketConnector aConnector, Token aToken) {
    TokenServer lServer = getServer();

    Token lResponse = createResponse(aToken);

    // check if user is allowed to run 'exists' command
    /*
    if (!hasAuthority(aConnector, NS_EXTPROCESS + ".call")) {
    if (mLog.isDebugEnabled()) {
    mLog.debug("Returning 'Access denied'...");
    }
    lServer.sendToken(aConnector, lServer.createAccessDenied(aToken));
    return;
    }
    */

    String lAlias = aToken.getString("alias");
    if (null == lAlias) {
      lResponse.setInteger("code", -1);
      lResponse.setString("msg", "No alias passed.");
      lServer.sendToken(aConnector, lResponse);
      return;
    }
    String lCmdLine = mSettings.getAllowedProgs().get(lAlias);
    if (null == lCmdLine) {
      lResponse.setInteger("code", -1);
      lResponse.setString("msg", "Alias '" + lAlias + "' not found.");
      lServer.sendToken(aConnector, lResponse);
      return;
    }
    List<?> lArgs = aToken.getList("args");

    if (mLog.isDebugEnabled()) {
      mLog.debug(
          "Processing 'call'"
              + " (alias: "
              + lAlias
              + ", args: "
              + StringUtils.collectionToDelimitedString(lArgs, ", ")
              + ")...");
    }
    String[] lCmdTokens = StringUtils.tokenizeToStringArray(lCmdLine, " ", true, false);
    List<String> lCmd = new ArrayList<String>();
    for (String lCmdToken : lCmdTokens) {
      for (int lArgIdx = 0; lArgIdx < lArgs.size(); lArgIdx++) {
        lCmdToken = lCmdToken.replace("${" + (lArgIdx + 1) + "}", lArgs.get(lArgIdx).toString());
      }
      lCmd.add(lCmdToken);
    }

    ProcessBuilder lProcBuilder = new ProcessBuilder(lCmd);
    // Map<String, String> lEnv = lProcBuilder.environment();
    lProcBuilder.directory(new File(System.getenv("temp")));

    try {
      if (mLog.isDebugEnabled()) {
        mLog.debug("Directory: " + System.getenv("temp"));
      }
      final Process process = lProcBuilder.start();
      InputStream lIS = process.getInputStream();
      InputStreamReader lISR = new InputStreamReader(lIS);
      BufferedReader lBR = new BufferedReader(lISR);
      String lLine;
      StringBuilder lStrBuf = new StringBuilder();
      while ((lLine = lBR.readLine()) != null) {
        Token lEventToken = TokenFactory.createToken(getNamespace(), "event");
        lEventToken.setString("line", lLine);
        lStrBuf.append(lLine).append("\n");
        lServer.sendToken(aConnector, lEventToken);
      }
      lResponse.setInteger("exitCode", process.exitValue());
      if (mLog.isDebugEnabled()) {
        mLog.debug("Sent '" + lStrBuf.toString().replace("\n", "\\n") + "'.");
      }
    } catch (IOException lEx) {
      lResponse.setInteger("code", -1);
      String lMsg = Logging.getSimpleExceptionMessage(lEx, "calling external process");
      lResponse.setString("msg", lMsg);
      mLog.error(lMsg);
    }

    lServer.sendToken(aConnector, lResponse);
  }
}
예제 #7
0
  private void call(WebSocketConnector aConnector, Token aToken) {
    TokenServer lServer = getServer();

    Token lResponse = createResponse(aToken);

    // check if user is allowed to run 'exists' command
    /*
    if (!hasAuthority(aConnector, NS_EXTPROCESS + ".call")) {
    if (mLog.isDebugEnabled()) {
    mLog.debug("Returning 'Access denied'...");
    }
    lServer.sendToken(aConnector, lServer.createAccessDenied(aToken));
    return;
    }
    */

    String lAlias = aToken.getString("alias");
    if (null == lAlias) {
      lResponse.setInteger("code", -1);
      lResponse.setString("msg", "No alias passed.");
      lServer.sendToken(aConnector, lResponse);
      return;
    }
    String lCmdLine = mSettings.getAllowedProgs().get(lAlias);
    if (null == lCmdLine) {
      lResponse.setInteger("code", -1);
      lResponse.setString("msg", "Alias '" + lAlias + "' not found.");
      lServer.sendToken(aConnector, lResponse);
      return;
    }
    List<?> lArgs = aToken.getList("args");

    if (mLog.isDebugEnabled()) {
      mLog.debug(
          "Processing 'call'"
              + " (alias: "
              + lAlias
              + ", args: "
              + StringUtils.collectionToDelimitedString(lArgs, ", ")
              + ")...");
    }
    String[] lCmdTokens = StringUtils.tokenizeToStringArray(lCmdLine, " ", true, false);
    List<String> lCmd = new ArrayList<String>();
    for (String lCmdToken : lCmdTokens) {
      for (int lArgIdx = 0; lArgIdx < lArgs.size(); lArgIdx++) {
        lCmdToken = lCmdToken.replace("${" + (lArgIdx + 1) + "}", lArgs.get(lArgIdx).toString());
      }
      lCmd.add(lCmdToken);
    }

    ProcessBuilder lProcBuilder = new ProcessBuilder(lCmd);
    // Map<String, String> lEnv = lProcBuilder.environment();
    lProcBuilder.directory(new File(System.getenv("temp")));

    try {
      if (mLog.isDebugEnabled()) {
        mLog.debug("Directory: " + System.getenv("temp"));
      }
      final Process process = lProcBuilder.start();
      InputStream lIS = process.getInputStream();
      InputStreamReader lISR = new InputStreamReader(lIS);
      BufferedReader lBR = new BufferedReader(lISR);
      String lLine;
      StringBuilder lStrBuf = new StringBuilder();
      while ((lLine = lBR.readLine()) != null) {
        Token lEventToken = TokenFactory.createToken(getNamespace(), "event");
        lEventToken.setString("line", lLine);
        lStrBuf.append(lLine).append("\n");
        lServer.sendToken(aConnector, lEventToken);
      }
      lResponse.setInteger("exitCode", process.exitValue());
      if (mLog.isDebugEnabled()) {
        mLog.debug("Sent '" + lStrBuf.toString().replace("\n", "\\n") + "'.");
      }
    } catch (IOException lEx) {
      lResponse.setInteger("code", -1);
      String lMsg = Logging.getSimpleExceptionMessage(lEx, "calling external process");
      lResponse.setString("msg", lMsg);
      mLog.error(lMsg);
    }

    lServer.sendToken(aConnector, lResponse);
  }