Package center.app.common

Source Code of center.app.common.ByteMsgResponseProcessor$SingleProccesor

package center.app.common;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.*;

import ru.vassaev.core.CallBackInterface;
import ru.vassaev.core.Pool;
import ru.vassaev.core.PrmInterface;
import ru.vassaev.core.base.Null;
import ru.vassaev.core.container.ApplicationManager;
import ru.vassaev.core.exception.SysException;
import ru.vassaev.core.exception.SysRuntimeException;
import ru.vassaev.core.io.ByteMsg;
import ru.vassaev.core.thread.Process;
import ru.vassaev.core.thread.Processed;
import ru.vassaev.core.types.StringList;
import ru.vassaev.core.util.Sockets;
import ru.vassaev.core.util.Strings;
import center.task.*;
import center.task.api.ITaskAPI;

/**
* Обработка запроса по протоколу ByteMsg
* Общая схема работы:
*   - Открывается порт на прием сообщения
*  - После приема сообщения в отдельном потоке:
*    - Создается задание Child с копированием параметров в группу
*      , заданную параметром [msg_grp_in] (по умолчанию in)
*    - Ожидается завершение задания Child
*    - Результат отсылается в том же соединении.
*      Параметры набираются из группы, заданной параметром [msg_grp_out] (по умолчанию out)
* @author Vassaev A.V.
* @version 1.0
*/
public class ByteMsgResponseProcessor extends AProcessor {
  private Pool<ByteMsg> poolmsg = null;

  private enum Type {
    CLIENT, SERVER
  }

  private Type type;

  public ByteMsg getMsg() {
    try {
      return poolmsg.occupyWait();
    } catch (SysRuntimeException e) {
      return null;
    }
  }

  public void freeMsg(ByteMsg m) {
    if (m != null) {
      m.reset();
      poolmsg.free(m);
    }
  }
 
  // Пул потоков для обработки формирования задания
  private String poolProcessName = null;
  private Pool<ru.vassaev.core.thread.Process> prcs = null;
  private Integer localport;
  private int maxlink;
  private String host;
  private String msg_grp_in = "in";
  private String msg_grp_out = "out";
  /**
   * Проверка установки параметров
   *
   * @param cntx
   * @throws SysException
   */
  public void paramsValidateAndPrepare(Context cntx) throws SysException {
    // Имя пула потоков исполнения
    poolProcessName = cntx.getPrmString("process_pool");
    if (Null.equ(poolProcessName))
      throw new SysException("Parameter process_pool isn't set");
    ru.vassaev.core.thread.Process prc = ru.vassaev.core.thread.Process
        .currentProcess();
    prcs = (Pool<Process>) ApplicationManager.getPoolByName(poolProcessName, Process.class);
    // Тип соединения tcp/ip (CLIENT / SERVER)
    String type_str = Strings.getString(cntx.getPrmByFullName("type"),
        "CLIENT");
    type = Type.valueOf(type_str);
    // Определение пула контейнеров сообщений
    String poolMessageName = cntx.getPrmString("message_pool");
    if (Null.equ(poolMessageName))
      throw new SysException("Parameter message_pool isn't set");
    poolmsg = (Pool<ByteMsg>) ApplicationManager.getPoolByName(poolMessageName, ByteMsg.class);

    localport = Strings.parseInteger(cntx.getPrmByFullName("localport"));

    if (Type.CLIENT.equals(type)) {
      host = cntx.getPrmString("host");
      if (Null.equ(host))
        throw new SysException("Parameter by name \"host\" isn't set");
    } else {
      if (Null.equ(localport))
        throw new SysException("Parameter by name \"localport\" isn't set");
      maxlink = Strings.parseIntegerNvl(cntx.getPrmByFullName("maxlink"), 50);
    }
    msg_grp_in = cntx.getPrmString("msg_grp_in");
    if (msg_grp_in == null)
      msg_grp_in = "in";
    msg_grp_out = cntx.getPrmString("msg_grp_out");
    if (msg_grp_out == null)
      msg_grp_out = "out";
  }

  private class Finish implements CallBackInterface<Process, Object> {
    public Object callBack(Process prc) {
      prcs.free(prc);
      return null;
    }
  }

  private Finish finish = new Finish();
  private ServerSocket ss;

  private void init_server() throws IOException {
    ss = new ServerSocket(localport, maxlink);
  }

  private void init_client() {

  }

  public ByteMsgResponseProcessor() {
  }

  private class Target implements Processed<Socket>,
      CallBackInterface<Object[], ByteMsg> {
    private String nameLink;
    private InputStream is = null;
    private OutputStream os = null;
    private synchronized void sendMsg(ByteMsg m) throws IOException {
      m.sendTo(os);
    }
    public void processing(Socket s) throws Throwable {
      nameLink = Sockets.getNameLink(s);
      try {
        System.out.println("Started link " + nameLink);
        is = s.getInputStream();
        os = s.getOutputStream();
        ByteMsg.processRead(is, this);
      } finally {
      }
    }

    public ByteMsg callBack(Object[] objs) {
      if (!Null.equ(objs) && objs.length > 1) {
        ByteMsg msg = (ByteMsg)objs[1];
        if (ByteMsg.ACTION.FREE.equals(objs[0])) {
          freeMsg(msg);
          System.out.println("Dropped link " + nameLink);
          try {
            os.close();
          } catch (IOException e) {
          }
          try {
            is.close();
          } catch (IOException e) {
          }
          return null;
        }
        //System.out.println("Recived message:");
        PrmInterface prm;
        /*
        try {
          prm = msg.getPrmInterface();
          StringList names = prm.getFieldNames();
          for (int j = 0; j < names.size(); j++) {
            System.out.println("\t" + names.get(j) + " = " + prm.getField(names.get(j)));
          }
        } catch (SysException e1) {
          e1.printStackTrace();
        }
        */
        Process tr;
        // Создать поток обработки
        tr = prcs.occupy();
        // старт обработки;
        try {
          SingleProccesor target = new SingleProccesor(msg, this);
          tr.setTarget(target);
          tr.start();
        } catch (RuntimeException e) {
          prcs.free(tr);
          freeMsg(msg);
          e.printStackTrace();
        } catch (SysException e) {
          prcs.free(tr);
          freeMsg(msg);
          e.printStackTrace();
        }
      }
      // Получить новый буфер для приёма
      return getMsg();
    }

  }

  private void process_server() throws IOException {
    while (true) {
      Socket s = ss.accept();
      Process prc = prcs.occupy();
      prc.setCallBackOnEndProcess(finish);
      System.out.println("Created link " + Sockets.getNameLink(s));
      prc.setTarget(new Target());
      prc.start(s);
     
    }
  }

  private void process_client() throws UnknownHostException, IOException {
    Socket s = new Socket(host, localport);
    System.out.println("++++3+++PRCPOOL.BusySize = " + prcs.getBusySize());
    Process prc = prcs.occupy();
    prc.setCallBackOnEndProcess(finish);
    System.out.println("Created link " + Sockets.getNameLink(s));
    prc.setTarget(new Target());
    prc.start(s);
  }

  public State process(Context cntx) throws SysException, TaskException {
    paramsValidateAndPrepare(cntx);
    try {
      if (type.equals(Type.SERVER)) {
        init_server();
        process_server();
      } else {
        init_client();
        process_client();
      }
    } catch (IOException e) {
      throw new TaskException(State.DONE_ERR, e);
    }
    Object sync = new Object();
    while (true) {
      try {
        sync.wait(10000);// !!!Нужен параметр
      } catch (InterruptedException e) {
        break;
      }
    }
    return State.BROKEN;
  }

  private class SingleProccesor implements Processed {

    private ByteMsg in;
    private long id_task;
    private ITaskAPI ta;
    private NewTaskInfo child;
    private boolean need_reply = true;
    private Target tprcs;

    public SingleProccesor(ByteMsg in, Target prcs) throws SysException {
      super();
      init(in, prcs);
    }

    public void init(ByteMsg in, Target prcs) throws SysException {
      this.in = in;
      this.tprcs = prcs;
      ta = getTaskAPI();
      id_task = getTaskID();
      child = getChild();
    }

    public void processing(Object oprm) {
      PrmInterface prm;
      try {
        long id_processor = getProcessorID();
        prm = in.getPrmInterface();
        ArrayList<String> flds = prm.getFieldNames();
        for (String k : flds) {
          String v = prm.getField(k);
          Process.currentProcess().regResourceName(v, "msg." + k);
        }
        Context cntx = getContext();
        // Создать и подготовить для выполнения дочернюю задачу
        Context chld = child
            .createAndReadyTask(ta, cntx, id_processor, msg_grp_in, prm);

        need_reply = Strings.parseBooleanNvl(chld.getPrmByFullName("need_reply"), false);
        try {
          long wait = Strings.parseIntegerNvl(chld.getPrmByFullName("wait"), 120000);
          cntx.log(false, "Start waiting (", wait, ")");
          State r = chld.ta.waitFinished(chld.id_subject, chld.id_task, wait);
          cntx.log(false, "End waiting");
          need_reply = Strings.parseBooleanNvl(chld.getPrmByFullName("need_reply"), true);

          Map<String, Object> prms_out = chld.getGroupParams(msg_grp_out);
          Iterator<String> i = prms_out.keySet().iterator();
          prm = in.getPrmInterface();
          if ("true".equalsIgnoreCase(Strings.getString(chld.getPrmByFullName("clear"))))
            prm.clearFields();
          while (i.hasNext()) {
            String n = i.next();
            String[] fn = Context.getFullName(n);
            String o = Strings.getString(prms_out.get(n));
            //System.out.println("\t set " + n + " = " + o);
            prm.setField(fn[1], o);
//            ((ISO8583Msg)in).printStatusHeader();
          }
        } catch (SysException ex1) {
          ta.setTaskError(chld.id_task, ex1);
          chld.log(false, "The task was completed with errors");
          chld.log(false, ex1.getMessage());
          ta.setDoneErr(id_processor, chld.id_task);
        } finally {
          try {
            if (need_reply)
              tprcs.sendMsg(in);
            chld.log(false, "NEED_REPLY = ", need_reply);
          } catch (IOException ex1) {
            ta.setTaskError(chld.id_task, ex1);
            chld.log(false, "The task was completed with errors");
            chld.log(false, ex1.getMessage());
            ta.setDoneErr(id_processor, chld.id_task);
          }
          freeMsg(in);
        }
      } catch (SysException ex) {
        throw new RuntimeException(ex);
      } finally {
        freeMsg(in);
        prcs.free(Process.currentProcess());
      }
    }
  }
  public Set<String> dependentOn() {
    Set<String> s = new HashSet<String>();
    return s;
  }

  public Set<String> loopDependentOn() {
    Set<String> s = new HashSet<String>();
    return s;
  }
}
TOP

Related Classes of center.app.common.ByteMsgResponseProcessor$SingleProccesor

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.