
org.bdware.irp2.client.IrpRouterClientImpl Maven / Gradle / Ivy
package org.bdware.irp2.client;
import com.google.gson.Gson;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.irp2.exception.IrpClientException;
import org.bdware.irp2.irpclient.IrpClientChannel;
import org.bdware.irp2.irpclient.IrpClientChannelGenerator;
import org.bdware.irp2.irpclient.IrpMessageCallback;
import org.bdware.irp2.irplib.exception.IrpConnectException;
import org.bdware.irp2.irplib.util.EncoderUtils;
import org.bdware.irp2.stateinfo.StateInfoBase;
import org.bdware.irp2.irplib.core.*;
import java.net.URISyntaxException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class IrpRouterClientImpl extends IrpClientImpl implements IrpRouterClient {
Logger logger = LogManager.getLogger(IrpRouterClientImpl.class);
Map cachedChannel = new ConcurrentHashMap<>();
IrpClientChannel irpChannel;
String serverURL = null;
ResponseCallback rcb;
ResponseContainer container;
IrpResponse res;
IrpRequestFactory factory = new IrpRequestFactory(null);
public IrpRouterClientImpl(String clientID, String LHSUrl, IrpMessageSigner signer) {
super(clientID, LHSUrl, signer);
this.serverURL = LHSUrl;
container = new ResponseContainer();
rcb = new ResponseCallback(container);
}
@Override
public String authInfoFromUpperRouter(String pubkey, String name, String signInfo) throws IrpClientException {
if (pubkey == null || name == null || signInfo == null) {
throw new IrpClientException("authinfo is null!");
}
IrpMessage req = IrpForRouterRequest.newVerifyRouterAuthRequest(pubkey, name, signInfo);
sendMessage(req, rcb);
IrpResponse res = waitForResponse();
if (res.header.responseCode != IrpMessageCode.RC_SUCCESS || !(res instanceof IrpForRouterResponse)) {
logger.error("Verify the router from upper router failed: " + res.getResponseMessage());
throw new IrpClientException("Verify the router from upper router failed!");
}
IrpForRouterResponse response = (IrpForRouterResponse) res;
ResponseInfo resInfo = new ResponseInfo(response.prefix, response.port, response.routerInfo);
return new Gson().toJson(resInfo);
}
@Override
public StateInfoBase resolve(String doid) throws IrpClientException {
if (doid == null) {
throw new IrpClientException("doid is null!");
}
//get the prefix and name(suffix) from the identifier
// StringTokenizer token = new StringTokenizer(doid, "/");
// if (token.countTokens() < 1 || token.countTokens() > 3) {
// throw new IrpClientException("Illegal doid identifier");
// }
// String prefix = token.nextToken();
// if (token.hasMoreTokens()) {
// prefix = prefix + '/' + token.nextToken();
// }
// logger.debug("Resolve the doid identifier: " + prefix);
String prefix = doid;
//resolve
boolean stopFlag = false;
String nextServerUrl = this.serverURL;
String doidInfo = null;
//query the next router until find the right one
while (!stopFlag) {
try {
setServerAddress(nextServerUrl);
reconnect();
IrpMessage req = factory.newIrsResolveRequest(prefix, null);
sendMessage(req, rcb);
res = waitForResponse();
logger.debug(res.toString());
} catch (Exception e) {
e.printStackTrace();
} finally {
}
if (res.header.responseCode == IrpMessageCode.RC_SUCCESS) {
//get the right one
StateInfoBase infoBase = new StateInfoBase();
infoBase.identifier = new String(res.doid);
infoBase.handleValues = res.getDoidValues();
return infoBase;
} else if (res.header.responseCode == IrpMessageCode.RC_NA_DELEGATE) {
//get the next router
if (res.delegateTargetURL != null) {
if (!res.delegateTargetURL.startsWith("tcp://"))
nextServerUrl = "tcp://" + res.delegateTargetURL;
else nextServerUrl = res.delegateTargetURL;
stopFlag = false;
} else {
throw new IrpClientException("The next router address is wrong:"
+ res.header.responseCode);
}
} else if (res.header.responseCode == IrpMessageCode.RC_ERROR) {
logger.info(EncoderUtils.decodeString(res.responseMessage));
stopFlag = true;
} else {
throw new IrpClientException("Unhandled response code:"
+ res.header.responseCode);
}
}
return null;
}
IrpResponse waitForResponse() {
container.response = null;
synchronized (rcb) {
try {
rcb.wait(5000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (container.response == null) {
container.response = IrpResponse.newErrorResponse(
IrpMessageCode.OC_RESERVED,
IrpMessageCode.RC_ERROR,
"Server response timeout!");
}
return container.response;
}
public void close() {
if (irpChannel != null) {
irpChannel.close();
irpChannel = null;
}
}
public void connect() {
try {
irpChannel = getOrCreateChannel(serverURL);
if (irpChannel == null) return;
if (!irpChannel.isConnected())
irpChannel.connect(serverURL);
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
private IrpClientChannel getOrCreateChannel(String serverURL) {
IrpClientChannel ret;
if (cachedChannel.containsKey(serverURL)) {
ret = cachedChannel.get(serverURL);
} else {
ret = IrpClientChannelGenerator.createIrpClientChannel(serverURL);
cachedChannel.put(serverURL, ret);
}
return ret;
}
public void setServerAddress(String newURL) {
this.serverURL = newURL;
}
public void reconnect() throws IrpConnectException {
if (serverURL == null) throw (new IrpConnectException("target URL not set, use .connect(url) first"));
if (irpChannel == null) {
irpChannel = getOrCreateChannel(serverURL);
}
if (irpChannel == null) return;
try {
if (!irpChannel.isConnected()) {
logger.debug("Reconnect the next router: " + serverURL);
irpChannel.connect(serverURL);
}
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
public boolean isConnected() {
return irpChannel != null && irpChannel.isConnected();
}
public void sendMessage(IrpMessage msg, IrpMessageCallback cb) {
connect();
if (irpChannel == null || !irpChannel.isConnected()) {
logger.warn("channel not connect yet!");
return;
}
//msg.setRecipientID(recipientID);
irpChannel.sendMessage(msg, cb);
}
;
class ResponseCallback implements IrpMessageCallback {
ResponseContainer responseContainer;
public ResponseCallback(ResponseContainer container) {
responseContainer = container;
}
@Override
public synchronized void onResult(IrpMessage msg) {
logger.debug("message header: " + msg.header.opCode);
responseContainer.response = (IrpResponse) msg;
this.notifyAll();
}
}
static class ResponseContainer {
IrpResponse response;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy