package center.app.common;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Map;
import java.util.Set;
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.io.ByteMsg;
import ru.vassaev.core.io.CloseableOutputStream;
import ru.vassaev.core.thread.PoolThread;
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.system.msg.SAMsg;
import center.task.AProcessor;
import center.task.Context;
import center.task.State;
import center.task.TaskException;
public class SAMsgQueryProcessor extends AProcessor {
private static String toHexString(int ch) {
String r = Integer.toHexString(ch);
if (r.length() == 1)
r = "0" + r;
return r;
}
private final Object sync = new Object();
private PoolThread prcs;
private String msg_grp_in;
private String msg_grp_out;
private String host;
private int port;
private long timeout;
/**
* Чтение параметров и проверка параметров
*
* @param cntx - текущий контекст
* @throws SysException - в случае недостатка параметров или невалидных значений
*/
public State paramsValidateAndPrepare(Context cntx) throws SysException {
// Имя пула потоков исполнения
boolean need_send = Strings.parseBoolean(cntx.getPrmNvl("need_send", "true"));
if (!need_send)
return State.DONE_OK;
String poolProcessName = cntx.getPrmString("process_pool");
if (Null.equ(poolProcessName))
throw new SysException("Parameter process_pool isn't set");
prcs = (PoolThread) ApplicationManager.getPoolByName(poolProcessName, Process.class);
// Определение пула контейнеров сообщений
String poolMessageName = cntx.getPrmString("message_pool");
if (Null.equ(poolMessageName))
throw new SysException("Parameter message_pool isn't set");
msg_grp_in = cntx.getPrmNvl("msg_grp_in", "in");
msg_grp_out = cntx.getPrmNvl("msg_grp_out", "out");
host = cntx.getPrmString("host");
port = Integer.parseInt(cntx.getPrmString("port"));
String timeout_s = cntx.getPrmNvl("timeout", "30000");
if (timeout_s.length() > 0) {
try {
timeout = Long.parseLong(timeout_s);
} catch (NumberFormatException ex) {
throw new SysException(ex);
}
} else
timeout = 30000;
return null;
}
private class ReadMsg implements Processed<InputStream> {
private final ByteMsg msg;
private ByteMsg rmsg;
public ReadMsg(ByteMsg msg) {
super();
this.msg = msg;
}
public void processing(InputStream is) throws Throwable {
ByteMsg.receiveMsg(is, msg);
synchronized(ReadMsg.this) {
rmsg = msg;
}
synchronized(sync) {
sync.notifyAll();
}
}
public ByteMsg getResultMsg() {
synchronized(ReadMsg.this) {
return rmsg;
}
}
}
public State process(Context cntx) throws TaskException, SysException,
InterruptedException {
State st = paramsValidateAndPrepare(cntx);
if (st != null)
return st;
Socket s = null;
try {
Map<String, Object> prms = cntx.getGroupParams(msg_grp_in);
SAMsg q = new SAMsg();
PrmInterface prmi;
{
prmi = q.getPrmInterface();
for(Map.Entry<String, Object> prm : prms.entrySet()) {
String key = prm.getKey();
String[] fn = cntx.getFullName(key);
prmi.setField(fn[1], Strings.getString(cntx.getPrmString(key)));
}
}
s = new Socket(host, port);
System.out.println("Opened link " + Sockets.getNameLink(s));
InputStream is = s.getInputStream();
OutputStream os = s.getOutputStream();
SAMsg in = new SAMsg();
SAMsg result = new SAMsg();
int enq = is.read();
System.out.print("<-- " + toHexString(enq));
if (enq != SAMsg.ENQ)
throw new TaskException(State.DONE_ERR, "Incorrect the first signal from host");
q.sendTo(s.getOutputStream());
System.out.print("\n-->");
q.printTo(System.out);
System.out.println();
String v;
for (String n : prmi.getFieldNames()) {
v = prmi.getField(n);
System.out.println(n + " = " + v);
}
int ch;
PrmInterface inpi = in.getPrmInterface();
CloseableOutputStream osc = in.getOutputStream();
System.out.print("\n<--");
boolean end = false;
while (!end && (ch = is.read()) != -1) {
System.out.print(" ");
System.out.print(toHexString(ch));
osc.write(ch);
if (osc.isClosed()) {
switch(Integer.parseInt(inpi.getField("type"))) {
case SAMsg.STX:
System.out.println();
PrmInterface rpi = result.getPrmInterface();
for (String n : inpi.getFieldNames()) {
v = inpi.getField(n);
rpi.setField(n, v);
System.out.println(n + " = " + v);
}
end = true;
break;
case SAMsg.ACK:
System.out.print("\n<--");
break;
case SAMsg.ENQ:
System.out.print("\n<--");
break;
default:
System.out.print("\n<--");
throw new TaskException(State.DONE_ERR, "Incorrect response from host");
}
in.reset();
osc = in.getOutputStream();
}
}
os.write(SAMsg.ACK);
System.out.print("\n--> " + toHexString(SAMsg.ACK));
os.write(SAMsg.EOT);
System.out.println("\n--> " + toHexString(SAMsg.EOT));
PrmInterface rpi = result.getPrmInterface();
StringList flds = rpi.getFieldNames();
for (String fld : flds) {
cntx.setPrmByFullName(msg_grp_out + "/" + fld, rpi.getField(fld), false);
}
} catch (UnknownHostException e) {
throw new TaskException(State.DONE_ERR, e);
} catch (IOException e) {
throw new TaskException(State.DONE_ERR, e);
} finally {
ru.vassaev.core.util.Sockets.close(s);
}
return State.DONE_OK;
}
@Override
public Set<String> dependentOn() {
// TODO Auto-generated method stub
return null;
}
@Override
public Set<String> loopDependentOn() {
// TODO Auto-generated method stub
return null;
}
}