package center.app.common;
import java.io.IOException;
import java.io.InputStream;
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.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.Strings;
import center.task.AProcessor;
import center.task.Context;
import center.task.State;
import center.task.TaskException;
public class ByteMessageQueryProcessor extends AProcessor {
private final Object sync = new Object();
private PoolThread prcs;
private Pool<ByteMsg> poolmsg;
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");
poolmsg = (Pool<ByteMsg>) ApplicationManager.getPoolByName(poolMessageName, ByteMsg.class);
if (poolmsg == null)
throw new SysException("There is no message pool by name '" + poolMessageName + "'");
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);
ByteMsg msg = poolmsg.occupyOrNew();
try {
PrmInterface prmi = msg.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);
msg.sendTo(s.getOutputStream());
} finally {
poolmsg.free(msg);
}
msg = poolmsg.getFactory().create();
poolmsg.getFactory().initialization(msg);
ReadMsg rm = new ReadMsg(msg);
ByteMsg result;
Process prc = null;
try {
synchronized(sync) {
prc = prcs.occupyWait();
prc.setTarget(rm);
prc.setName("READ_MSG_" + cntx.id_task);
prc.start(s.getInputStream());
sync.wait(timeout);
result = rm.getResultMsg();
if (result == null) {
prc.kill();
throw new TaskException(State.DONE_TOUT, "Timeout of receiving message");
}
}
} finally {
prcs.free(prc);
}
PrmInterface prmi = result.getPrmInterface();
StringList flds = prmi.getFieldNames();
for (String fld : flds) {
cntx.setPrmByFullName(msg_grp_out + "/" + fld, prmi.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;
}
}