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

org.bdware.doip.ClassicalBroker Maven / Gradle / Ivy

There is a newer version: 1.5.4
Show newest version
package org.bdware.doip;

import com.google.gson.*;
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.endpoint.event.EventBroker;
import org.bdware.irp.crypto.Base64JavaUtilsImpl;
import org.zz.gmhelper.SM3Util;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.Set;

public class ClassicalBroker implements EventBroker {
    private static final Gson GSON = new Gson();
    RocksDBUtil storageManager;
    AuditDoaClient client;

    public ClassicalBroker(String path, AuditDoaClient client) {
        this.storageManager = RocksDBUtil.loadDB(path, false);
        this.client = client;
    }

    @Override
    public DoipMessage publish(DoipMessage request) {
        try {
            String topicId = request.header.parameters.attributes.get("topicId").getAsString();
            savePublishedEvents(request, topicId);
            JsonArray subscribers = getAsJson(topicId, new JsonArray()).getAsJsonArray();
            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();
            DoipMessageFactory.DoipMessageBuilder builder = new DoipMessageFactory.DoipMessageBuilder();
            builder.createResponse(DoipResponseCode.Success, request).setBody(request.body.getEncodedData());
            return builder.create();
        } catch (Exception e) {
            ByteArrayOutputStream bo = new ByteArrayOutputStream();
            e.printStackTrace(new PrintStream(bo));
            DoipMessageFactory.DoipMessageBuilder builder = new DoipMessageFactory.DoipMessageBuilder();
            builder.createResponse(DoipResponseCode.UnKnownError, request);
            builder.setBody(bo.toByteArray());
            return builder.create();
        }
    }

    @Override
    public DoipMessage subscribe(DoipMessage request) {
        String topicId = request.header.parameters.attributes.get("topicId").getAsString();
        String subscriberId = request.header.parameters.attributes.get("subscriberId").getAsString();
        boolean isSubscribe = request.header.parameters.attributes.has("subscribe") &&
                request.header.parameters.attributes.get("subscribe").getAsBoolean();
        boolean isReplay = request.header.parameters.attributes.has("replay") &&
                request.header.parameters.attributes.get("replay").getAsBoolean();
        addOrRemoveSubscribers(topicId, subscriberId, isSubscribe);
        byte[] body = null;
        if (isSubscribe) {
            JsonArray publishedEvents = getAsJson(getEventListKey(topicId), new JsonArray()).getAsJsonArray();
            if (isReplay) {
                new Thread(() -> {
                    AuditDoipClient client = getOrCreateConnection(subscriberId);
                    try {
                        publishedEvents.forEach(jsonElement -> {
                            String eventId = jsonElement.getAsString();
                            DoipMessage message = GSON.fromJson(storageManager.get(eventId), DoipMessage.class);
                            client.sendMessage(message, null);
                        });
                    } catch (Exception ignored) {
                    }
                }).start();
            }
            body = publishedEvents.toString().getBytes(StandardCharsets.UTF_8);
        }
        DoipMessageFactory.DoipMessageBuilder builder = new DoipMessageFactory.DoipMessageBuilder();
        builder.createResponse(DoipResponseCode.Success, request).setBody(body);
        return builder.create();
    }

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

    synchronized private void savePublishedEvents(DoipMessage doipMessage, String topicId) {
        String key = getEventListKey(topicId);
        String eventContent = GSON.toJson(doipMessage);
        String hash =
                new Base64JavaUtilsImpl().encodeToString(SM3Util.hash(eventContent.getBytes(StandardCharsets.UTF_8)));
        storageManager.put(hash, eventContent);
        JsonArray eventList = getAsJson(key, new JsonArray()).getAsJsonArray();
        eventList.add(hash);
        storageManager.put(key, eventList.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);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy