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

org.bdware.doip.event.verified.VerifiedPublisher Maven / Gradle / Ivy

The newest version!
package org.bdware.doip.event.verified;

import com.google.gson.*;
import org.bdware.doip.RocksDBUtil;
import org.bdware.doip.audit.AuditDoaClient;
import org.bdware.doip.audit.client.AuditDoipClient;
import org.bdware.doip.codec.doipMessage.DoipMessage;
import org.bdware.doip.codec.doipMessage.DoipMessageFactory;
import org.bdware.doip.codec.doipMessage.DoipResponseCode;
import org.bdware.doip.codec.operations.BasicOperations;
import org.bdware.doip.endpoint.event.PublishMessageType;
import org.bdware.doip.endpoint.event.Publisher;

import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.Set;

public class VerifiedPublisher implements Publisher {
    private static final Gson GSON = new Gson();
    // key 是topicId,仅支持1种topicId, value是[subscriber1,subscriber2,...]
    // 待发布的内容存储的格式为
    // topicId:pub 保存一个数组,数组内容为[hash1,hash2,...]
    // hash1-->待发布的EventDoipMessage的body
    // EventDoipMessage的格式为 {header: order:xx,hash:xxx,topic:xx,publisher:xx,  body:Json字符串}
    RocksDBUtil storageManager;
    AuditDoaClient client;
    String publisherId;


    //要有默克尔树?
    public VerifiedPublisher(RocksDBUtil storageManager, AuditDoaClient client, String publisherId) {
        this.storageManager = storageManager;
        this.client = client;
        this.publisherId = publisherId;
    }

    synchronized private void addSubscribers(String topicId, String subscriberId) {
        JsonArray subscribers = getAsJson(topicId, new JsonArray()).getAsJsonArray();
        JsonPrimitive sid = new JsonPrimitive(subscriberId);
        if (!subscribers.contains(sid)) {
            subscribers.add(sid);
            storageManager.put(topicId, subscribers.toString());
        }
    }

    synchronized private void removeSubscribers(String topicId, String subscriberId) {
        JsonArray subscribers = getAsJson(topicId, new JsonArray()).getAsJsonArray();
        JsonPrimitive sid = new JsonPrimitive(subscriberId);
        if (subscribers.contains(sid)) {
            subscribers.remove(sid);
            storageManager.put(topicId, subscribers.toString());
        }
    }

    private JsonElement getAsJson(String key, JsonElement defaultValue) {
        String content = storageManager.get(key);
        try {
            if (null != content && !content.isEmpty()) {
                return JsonParser.parseString(content);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return defaultValue;
    }

    private String getEventListKey(String topicId) {
        return topicId + ":pub";
    }

    private AuditDoipClient getOrCreateConnection(String subscriberId) {
        return client.convertDoidToRepo(subscriberId);
    }

    @Override
    public DoipMessage subscribe(String topicId, String subscriberId, boolean needReplay, DoipMessage request) {
        addSubscribers(topicId, subscriberId);
        if (needReplay) {
            new Thread(() -> {
                JsonArray publishedEvents = getAsJson(getEventListKey(topicId), new JsonArray()).getAsJsonArray();
                try {
                    for (int i = 0; i < publishedEvents.size(); i++) {
                        String hash = publishedEvents.get(i).getAsString();
                        String content = storageManager.get(hash);
                        DoipMessageFactory.DoipMessageBuilder builder = new DoipMessageFactory.DoipMessageBuilder();
                        builder.createRequest(subscriberId, BasicOperations.Publish.getName());
                        builder.addAttributes("order", i);
                        builder.addAttributes("hash", hash);
                        builder.addAttributes("publisherId", publisherId);
                        builder.addAttributes("topicId", topicId);
                        builder.addAttributes("publishType", PublishMessageType.DataAndHash.name());
                        builder.setBody(content.getBytes());
                        client.sendRawMessageSync(builder.create(), 5000);
                    }
                } catch (Exception ignored) {
                }
            }).start();
        }
        DoipMessageFactory.DoipMessageBuilder builder = new DoipMessageFactory.DoipMessageBuilder();
        builder.createResponse(DoipResponseCode.Success, request).setBody("success".getBytes());
        return builder.create();
    }

    @Override
    public DoipMessage unsubscribe(String topicId, String subscriberId, DoipMessage request) {
        removeSubscribers(topicId, subscriberId);
        DoipMessageFactory.DoipMessageBuilder builder = new DoipMessageFactory.DoipMessageBuilder();
        builder.createResponse(DoipResponseCode.Success, request).setBody("success".getBytes(StandardCharsets.UTF_8));
        return builder.create();
    }

    @Override
    public DoipMessage sendDataInRange(String topicId, String subscriberId, long offset, long count, DoipMessage request) {
        new Thread(() -> {
            JsonArray array = getAsJson(topicId + ":pub", new JsonArray()).getAsJsonArray();
            for (int i = (int) offset; i < (int) (offset + count); i++) {
                String hash = array.get(i).getAsString();
                int order = i;
                String content = storageManager.get(hash);
                DoipMessageFactory.DoipMessageBuilder builder = new DoipMessageFactory.DoipMessageBuilder();
                builder.createRequest(subscriberId, BasicOperations.Publish.getName());
                builder.addAttributes("order", order);
                builder.addAttributes("hash", hash);
                builder.addAttributes("publisherId", publisherId);
                builder.addAttributes("topicId", topicId);
                builder.addAttributes("publishType", PublishMessageType.DataAndHash.name());
                builder.setBody(content.getBytes());
                client.sendRawMessageSync(builder.create(), 5000);
            }
        }).start();
        DoipMessageFactory.DoipMessageBuilder builder = new DoipMessageFactory.DoipMessageBuilder();
        builder.createResponse(DoipResponseCode.Success, null);
        return builder.create();
    }

    @Override
    public DoipMessage sendDataInList(String topicId, String subscriberId, JsonArray indexList, DoipMessage request) {
        new Thread(() -> {
            JsonArray array = getAsJson(topicId + ":pub", new JsonArray()).getAsJsonArray();
            for (JsonElement index : indexList) {
                int i = index.getAsInt();
                String hash = array.get(i).getAsString();
                int order = i;
                String content = storageManager.get(hash);
                DoipMessageFactory.DoipMessageBuilder builder = new DoipMessageFactory.DoipMessageBuilder();
                builder.createRequest(subscriberId, BasicOperations.Publish.getName());
                builder.addAttributes("order", order);
                builder.addAttributes("hash", hash);
                builder.addAttributes("publisherId", publisherId);
                builder.addAttributes("topicId", topicId);
                builder.addAttributes("publishType", PublishMessageType.DataAndHash.name());
                builder.setBody(content.getBytes());
                client.sendRawMessageSync(builder.create(), 5000);
            }
        }).start();
        DoipMessageFactory.DoipMessageBuilder builder = new DoipMessageFactory.DoipMessageBuilder();
        builder.createResponse(DoipResponseCode.Success, null);
        return builder.create();

    }

    @Override
    public DoipMessage verifyMerkelInRange(String topicId, String subscriberId, DoipMessage request) {
        throw new IllegalStateException("unsupported message type");
    }

    @Override
    public DoipMessage sendMerkelInRange(String topicId, String subscriberId, DoipMessage request) {
        throw new IllegalStateException("unsupported message type");
    }

    @Override
    public synchronized void publish(String topicId, DoipMessage request) {
        String content = request.body.getDataAsJsonString();
        String hashValue = HashUtil.hash(request.body.getDataAsJsonString());
        JsonArray array = getAsJson(topicId + ":pub", new JsonArray()).getAsJsonArray();
        array.add(hashValue);
        storageManager.put(topicId + ":pub", array.toString());
        storageManager.put(hashValue, content);
        JsonArray subscribers = getAsJson(topicId, new JsonArray()).getAsJsonArray();
        request.header.parameters.attributes.addProperty("topicId", topicId);
        request.header.parameters.attributes.addProperty("order", array.size());
        request.header.parameters.attributes.addProperty("hash", hashValue);
        request.header.parameters.attributes.addProperty("publisherId", publisherId);
        request.header.parameters.attributes.addProperty("publishType", PublishMessageType.DataAndHash.name());
        new Thread(() -> {
            Set sent = new HashSet<>();
            subscribers.forEach(je -> {
                String id = je.getAsString();
                AuditDoipClient client = getOrCreateConnection(id);
                if (!sent.contains(id)) {
                    sent.add(id);
                    client.sendMessage(request, null);
                }
            });
        }).start();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy