All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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