Package center.app.common

Source Code of center.app.common.QueryProcessor$Reader

package center.app.common;

import ru.vassaev.core.Pool;
import ru.vassaev.core.PrmInterface;
import ru.vassaev.core.io.CloseableOutputStream;
import ru.vassaev.core.types.StringList;
import ru.vassaev.core.xml.XMLMsg;
import ru.vassaev.core.exception.SysException;
import ru.vassaev.core.exception.SysRuntimeException;
import center.system.InfoBase;
import center.task.Context;
import center.task.AProcessor;
import center.task.State;
import center.task.TaskException;
import center.task.api.ITaskAPI;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;

import java.net.Socket;
import java.net.UnknownHostException;

import java.util.ArrayList;
import java.util.Map;
import java.util.Set;
import java.util.HashSet;

/**
* Процессор запросов к внешней системе
* <p/>
* Используюет протокол XML, соединение не сохраняет, соединение обрубает по достижении timeout.
* Параметры:
* Входные:    in.{name}*  - параметры сообщения (запроса)
* key         - ключ сообщения (если не задан, то формируется процессором)
* timeout     - время ожидания ответа в миллисекундах
* (0 или не задано - временем не ограничено)
* host        - host внешней системы
* port        - port на хосте внешней системы
* Результат:  out.{name}* - ответ
* ERR         - текст ошибки, если статус DONE_ERR
* ERR_EX      - дополнительный текст ошибки, если статус DONE_ERR
*
* @author Vassaev Andrey
* @version 1.0
*          Date: 26.12.2007
*          Time: 13:53:43
*/
public class QueryProcessor extends AProcessor {
  private static long id = 0;

  private static String getStan() {
    long stan = System.currentTimeMillis() << 4;
    stan = stan + ((id++) % 16);
    String stan_str = Long.toString(stan);
    return stan_str.substring(stan_str.length() - 6);
  }

  private static Pool<XMLMsg> pool = new Pool<XMLMsg>(XMLMsg.class);

  public static XMLMsg getMsg() {
    try {
      return pool.occupyWait();
    } catch (SysRuntimeException e) {
      return null;
    }
  }

  public static void freeMsg(XMLMsg m) {
    m.reset();
    pool.free(m);
  }

  private static class Reader extends Thread {
    public final InputStream is;
    public final String key;
    public final InfoBase<XMLMsg, XMLMsg> ib;
    public final XMLMsg m;
    public final long id_task;
    public final ITaskAPI ta;
    public boolean isRun = false;
    public boolean isWait = false;
    public Exception err = null;

    public Reader(InputStream is, InfoBase<XMLMsg, XMLMsg> ib, XMLMsg m, String key, ITaskAPI ta, long id_task) {
      this.is = is;
      this.key = key;
      this.ta = ta;
      this.id_task = id_task;
      this.ib = ib;
      this.m = m;
    }

    public void run() {
      XMLMsg r = null;
      try {
        CloseableOutputStream oss = m.getOutputStream();
        int b;
        while ((b = is.read()) != -1) {
          oss.write(b);
          if (oss.isClosed()) {
            String k = (m.isCalcKey()?m.getCalcKey():m.getKey());
            if (!key.equals(k))
              throw new SysException("An expected response is invalid");
            r = m;
            break;
          }
        }
      } catch (IOException ex) {
        err = ex;
      } catch (SysException ex) {
        err = ex;
      } finally {
        try {
          ib.giveResponse(r, key);
        } catch (SysException e) {
          err = e;
        }
      }
    }
  }

  public State process(Context cntx) throws SysException, TaskException {
    try {
      String host = cntx.getPrmString("host");
      int port = Integer.parseInt(cntx.getPrmString("port"));
      Socket s = new Socket(host, port);
      String timeout_s = cntx.getPrmString("timeout");
      long timeout = 0;
      if ((timeout_s != null) && (timeout_s.length() > 0)) {
        try {
          timeout = Long.parseLong(timeout_s);
        } catch (NumberFormatException ex) {
          throw new SysException(ex);
        }
      }
      //Socket s = new Socket("localhost", 8897);
      XMLMsg m = null;
      InputStream is = null;
      OutputStream os = s.getOutputStream();
      try {
        m = getMsg();
        String key = cntx.getPrmString("key");
        if ((key == null) || (key.length() == 0))
          key = getStan();
        m.setKey(key);
        cntx.ta.setParamObject(cntx.id_task, "key", key);

        String keyNames = cntx.getPrmString("keyNames");
        m.setKeyNames(keyNames);

        Map<String, Object> prms_in = cntx.getGroupParams("in");
        PrmInterface prm = m.getPrmInterface();
        for (String n : prms_in.keySet()) {
          Object v = prms_in.get(n);
          n = n.substring("in/".length());
          if (v != null)
            prm.setField(n, v.toString());
          else
            prm.setField(n, null);
        }
        boolean isCalcKey = m.isCalcKey();
        key = (isCalcKey ? m.getCalcKey() : m.getKey());
        cntx.ta.setParamObject(cntx.id_task, "calcKey", key);
        is = m.getInputStream();
        int b = -1;
        while ((b = is.read()) != -1)
          os.write(b);
        os.flush();
        is = s.getInputStream();
        InfoBase<XMLMsg, XMLMsg> ib = new InfoBase<XMLMsg, XMLMsg>();
        ib.makeQuery(m, key);
        m.reset();
        Reader th = new Reader(is, ib, m, key, cntx.ta, cntx.id_task);
        try {
          th.start();
//====================================
          cntx.log(false, "Start waiting (", timeout, ")");
          XMLMsg r = ib.takeResponseWithWait(key, timeout); //, id_task, ta, id_processor);
          cntx.log(false, "End waiting");

          if (r == null) {
            throw new TaskException(State.DONE_TOUT, "An expected response was not received on time");
          }
          PrmInterface r_prm = r.getPrmInterface();
          StringList flds = r_prm.getFieldNames();
          for (int j = 0; j < flds.size(); j++) {
            String k = flds.get(j).toString();
            cntx.ta.setParamObject(cntx.id_task, "out." + k, r_prm.getField(k));
          }
        } finally {
          th.interrupt();
        }
      } finally {
        if (is != null)
          is.close();
        s.close();
        freeMsg(m);
      }
      return State.DONE_OK;
    } catch (UnknownHostException e) {
      throw new TaskException(State.DONE_ERR, e);
    } catch (IOException e) {
      throw new TaskException(State.DONE_ERR, e);
    }
  }

  public Set<String> dependentOn() {
    return null;
  }

  public Set<String> loopDependentOn() {
    return null;
  }
}
TOP

Related Classes of center.app.common.QueryProcessor$Reader

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.