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

org.bdware.doip.audit.client.AuditDoipClient Maven / Gradle / Ivy

The newest version!
package org.bdware.doip.audit.client;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.doip.audit.writer.AuditConfig;
import org.bdware.doip.codec.digitalObject.DigitalObject;
import org.bdware.doip.codec.doipMessage.DoipMessage;
import org.bdware.doip.codec.doipMessage.DoipMessageFactory;
import org.bdware.doip.codec.doipMessage.DoipMessageSigner;
import org.bdware.doip.codec.doipMessage.DoipResponseCode;
import org.bdware.doip.codec.exception.DoipConnectException;
import org.bdware.doip.codec.metadata.SearchParameter;
import org.bdware.doip.codec.operations.BasicOperations;
import org.bdware.doip.endpoint.client.ClientConfig;
import org.bdware.doip.endpoint.client.DoipClient;
import org.bdware.doip.endpoint.client.DoipClientChannel;
import org.bdware.doip.endpoint.client.DoipMessageCallback;

import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicInteger;

public class AuditDoipClient implements DoipClient {
    private final DoipMessageSigner doipMessageSigner;
    private long timeout = 10000;
    DoipClientChannel doipChannel;
    String recipientID;
    String serverURL = null;
    private String version = null;

    Logger logger = LogManager.getLogger(AuditDoipClient.class);
    AuditConfig auditConfig;
    DoIdWrapper clientDoIdWrapper;
    DoIdWrapper serverDoIdWrapper;
    boolean enableAutoDelegate = true;
    public Semaphore rwLock = new Semaphore(1);

    public AuditDoipClient(AuditConfig config, DoipMessageSigner signer) {
        this(config, "unknown_client", signer);
    }

    public AuditDoipClient(AuditConfig config, String clientDoid, DoipMessageSigner signer) {
        auditConfig = config;
        doipMessageSigner = signer;
        this.clientDoIdWrapper = new DoIdWrapper(clientDoid);
        this.serverDoIdWrapper = new DoIdWrapper(null);
    }

    @Override
    public void hello(String id, DoipMessageCallback cb) {
        DoipMessage msg =
                new DoipMessageFactory.DoipMessageBuilder()
                        .createRequest(id, BasicOperations.Hello.getName())
                        .create();
        sendMessage(msg, cb);
    }

    public DoipMessage helloSync(String id) {
        DoipMessage msg =
                new DoipMessageFactory.DoipMessageBuilder()
                        .createRequest(id, BasicOperations.Hello.getName())
                        .create();
        return sendMessageSync(msg);
    }

    @Override
    public void listOperations(String id, DoipMessageCallback cb) {
        DoipMessage msg =
                new DoipMessageFactory.DoipMessageBuilder()
                        .createRequest(id, BasicOperations.ListOps.getName())
                        .create();
        sendMessage(msg, cb);
    }


    public DoipMessage listOperationsSync(String id) {
        DoipMessage msg =
                new DoipMessageFactory.DoipMessageBuilder()
                        .createRequest(id, BasicOperations.ListOps.getName())
                        .create();
        return sendMessageSync(msg);
    }

    @Override
    public void retrieve(String id, String element, boolean includeElementData, DoipMessageCallback cb) {
        DoipMessage msg =
                new DoipMessageFactory.DoipMessageBuilder()
                        .createRequest(id, BasicOperations.Retrieve.getName())
                        .create();
        if (element != null) msg.header.parameters.addAttribute("element", element);
        if (includeElementData) msg.header.parameters.addAttribute("includeElementData", "true");
        sendMessage(msg, cb);
    }

    public void setTimeout(long timeout) {
        this.timeout = timeout;
        doipChannel.setTimeoutSecond((int) (timeout / 1000L));
    }

    public DoipMessage retrieveSync(String id, String element, boolean includeElementData) {
        DoipMessage msg =
                new DoipMessageFactory.DoipMessageBuilder()
                        .createRequest(id, BasicOperations.Retrieve.getName())
                        .create();
        if (element != null) msg.header.parameters.addAttribute("element", element);
        if (includeElementData) msg.header.parameters.addAttribute("includeElementData", "true");
        return sendMessageSync(msg);
    }

    @Override
    public void create(String targetDOIPServiceID, DigitalObject digitalObject, DoipMessageCallback cb) {
        DoipMessage msg =
                new DoipMessageFactory.DoipMessageBuilder()
                        .createRequest(targetDOIPServiceID, BasicOperations.Create.getName())
                        .setBody(digitalObject)
                        .create();
        sendMessage(msg, cb);
    }


    public DoipMessage createSync(String targetDOIPServiceID, DigitalObject digitalObject) {
        DoipMessage msg =
                new DoipMessageFactory.DoipMessageBuilder()
                        .createRequest(targetDOIPServiceID, BasicOperations.Create.getName())
                        .setBody(digitalObject)
                        .create();
        return sendMessageSync(msg);
    }

    public DoipMessage createSync(String targetDOIPServiceID, byte[] body) {
        DoipMessage msg =
                new DoipMessageFactory.DoipMessageBuilder()
                        .createRequest(targetDOIPServiceID, BasicOperations.Create.getName())
                        .setBody(body)
                        .create();
        return sendMessageSync(msg);
    }

    @Override
    public void update(DigitalObject digitalObject, DoipMessageCallback cb) {
        DoipMessage msg =
                new DoipMessageFactory.DoipMessageBuilder()
                        .createRequest(digitalObject.id, BasicOperations.Update.getName())
                        .setBody(digitalObject)
                        .create();
        sendMessage(msg, cb);
    }

    public DoipMessage updateSync(DigitalObject digitalObject) {
        DoipMessage msg =
                new DoipMessageFactory.DoipMessageBuilder()
                        .createRequest(digitalObject.id, BasicOperations.Update.getName())
                        .setBody(digitalObject)
                        .create();
        return sendMessageSync(msg);
    }

    @Override
    public void delete(String id, DoipMessageCallback cb) {
        DoipMessage msg =
                new DoipMessageFactory.DoipMessageBuilder()
                        .createRequest(id, BasicOperations.Delete.getName())
                        .create();
        sendMessage(msg, cb);
    }

    public DoipMessage deleteSync(String id) {
        DoipMessage msg =
                new DoipMessageFactory.DoipMessageBuilder()
                        .createRequest(id, BasicOperations.Delete.getName())
                        .create();
        return sendMessageSync(msg);
    }


    @Override
    public void search(String id, SearchParameter sp, DoipMessageCallback cb) {
        DoipMessage msg =
                new DoipMessageFactory.DoipMessageBuilder()
                        .createRequest(id, BasicOperations.Search.getName())
                        .addAttributes("query", sp.query)
                        .addAttributes("pageNum", sp.pageNum)
                        .addAttributes("pageSize", sp.pageSize)
                        .addAttributes("type", sp.type)
                        .create();
        sendMessage(msg, cb);
    }

    public DoipMessage searchSync(String id, SearchParameter sp) {
        DoipMessage msg =
                new DoipMessageFactory.DoipMessageBuilder()
                        .createRequest(id, BasicOperations.Search.getName())
                        .addAttributes("query", sp.query)
                        .addAttributes("pageNum", sp.pageNum)
                        .addAttributes("pageSize", sp.pageSize)
                        .addAttributes("type", sp.type)
                        .create();
        return sendMessageSync(msg);
    }

    @Override
    public void sendRawMessage(DoipMessage msg, DoipMessageCallback cb) {
        sendMessage(msg, cb);
    }

    @Override
    public void close() {
        doipChannel.close();
    }

    @Override
    public void connect(ClientConfig config) {
        try {
            serverURL = config.url;
            this.version = config.protocolVersion;
            doipChannel = new AuditDoipTCPClientChannel(auditConfig, clientDoIdWrapper, serverDoIdWrapper);
            if (doipChannel == null)
                return;
            doipChannel.connect(serverURL);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void connect(String serverDoid, ClientConfig config) {
        this.serverDoIdWrapper.setDoId(serverDoid);
        connect(config);
    }


    @Override
    public void reconnect() throws DoipConnectException {
        if (serverURL == null) throw (new DoipConnectException("target URL not set, use .connect(url) first"));
        if (doipChannel == null)
            doipChannel = new AuditDoipTCPClientChannel(auditConfig, clientDoIdWrapper, serverDoIdWrapper);
        if (doipChannel == null) return;
        try {
            lastReconnect = System.currentTimeMillis();
            doipChannel.connect(serverURL);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @Override
    public String getRecipientID() {
        return recipientID;
    }

    @Override
    public void setRecipientID(String id) {
        recipientID = id;
    }

    @Override
    public boolean isConnected() {
        return doipChannel != null && doipChannel.isConnected();
    }

    static final Logger LOGGER = LogManager.getLogger(AuditDoipClient.class);


    public void sendMessage(DoipMessage msg, DoipMessageCallback cb) {
        if (doipChannel == null || !doipChannel.isConnected()) {
            if (!tryReconnect()) {
                logger.warn("sendMsgAsync, channel not connect yet! channel:" + (doipChannel == null) + " url:" + getRepoUrl());
                DoipMessage resp = DoipMessageFactory.createConnectFailedResponse(msg.requestID);
                cb.onResult(resp);
                return;
            } else sendMessageInternal(msg, cb);
        } else sendMessageInternal(msg, cb);

    }

    private boolean tryReconnect() {
        try {
            reconnect();
        } catch (DoipConnectException e) {
            throw new RuntimeException(e);
        }
        return isConnected();
    }

    private void sendMessageInternal(DoipMessage msg, DoipMessageCallback cb) {
        msg.setRecipientID(recipientID);
        if (doipMessageSigner != null) {
            doipMessageSigner.signMessage(msg);
            doipChannel.sendMessage(msg, doipMessage -> {
                if (doipMessageSigner.verifyMessage(doipMessage)) {
                    cb.onResult(doipMessage);
                } else {
                    DoipMessage ret = new DoipMessage(null, null);
                    ret.header.IsRequest = true;
                    ret.header.parameters.response = DoipResponseCode.Invalid;
                    ret.header.parameters.addAttribute("failed", "verify failed");
                    ret.requestID = doipMessage.requestID;
                    cb.onResult(ret);
                }
            });
        } else {
            doipChannel.sendMessage(msg, cb);
        }
    }

    public DoipMessage sendMessageSync(DoipMessage msg) {
        msg.setRecipientID(recipientID);
        DoipMessage[] result = new DoipMessage[1];
        DoipMessageCallback callback = new DoipMessageCallback() {
            @Override
            public void onResult(DoipMessage msg) {
                result[0] = msg;
                synchronized (result) {
                    result.notify();
                }
            }
        };
        sendMessage(msg, callback);
        synchronized (result) {
            try {
                result.wait(timeout);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        if (result[0] != null) return result[0];
        return DoipMessageFactory.createTimeoutResponse(msg.requestID, "[AuditDoipClient.sendMessageSync]");
    }

    public String getServerRepoId() {
        if (serverDoIdWrapper != null)
            return serverDoIdWrapper.doid;
        return "unknown";
    }

    public void setRepoUrl(String address) {
        serverURL = address;
    }

    public void disconnectAndSet(String address) {
        this.serverURL = address;
        LOGGER.info("========== disconnectAndSet:" + serverURL + " tid:" + Thread.currentThread().getId());
        doipChannel = null;
    }

    @Override
    public String getRepoUrl() {
        return serverURL;
    }

    public String getVersion() {
        return this.version;
    }

    AtomicInteger timeOutCount = new AtomicInteger(0);
    long lastReconnect = System.currentTimeMillis();

    public void decreaseTimeoutCount() {
        if (timeOutCount.get() >= 0)
            timeOutCount.decrementAndGet();
    }

    public int increaseTimeoutCount() {
        return timeOutCount.incrementAndGet();
    }

    public boolean needReconnect() {
        if (increaseTimeoutCount() == 10) {
            if (System.currentTimeMillis() - lastReconnect > 10000L) {
                lastReconnect = System.currentTimeMillis();
                timeOutCount.set(0);
                return true;
            }
            timeOutCount.set(0);
            return false;
        }
        return false;
    }

    public AuditConfig getAuditConfig() {
        return auditConfig;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy