org.bdware.doip.event.NaivePublisher Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of doip-audit-tool Show documentation
Show all versions of doip-audit-tool Show documentation
doip audit tool developed by bdware
package org.bdware.doip.event;
import com.google.gson.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
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.endpoint.event.PublishMessageType;
import org.bdware.doip.endpoint.event.Publisher;
import org.rocksdb.RocksIterator;
import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
public class NaivePublisher implements Publisher {
private static final Gson GSON = new Gson();
// key 是topicId, value是[subscriber1,subscriber2,...]
// support only one topicId!
// key = pfe_0, pfe_1..., value是doipmessage
RocksDBUtil storageManager;
AuditDoaClient client;
AtomicInteger count;
static final String prefixOfEvent = "pfe_";
private AtomicBoolean initialized;
static Logger LOGGER = LogManager.getLogger(NaivePublisher.class);
public NaivePublisher(RocksDBUtil storageManager, AuditDoaClient client) {
this.storageManager = storageManager;
this.client = client;
new Thread(() -> {
initializeCount();
}).start();
}
private void initializeCount() {
count = new AtomicInteger(0);
initialized = new AtomicBoolean(false);
RocksIterator iter = storageManager.newIterator();
iter.seekToFirst();
for (; iter.isValid(); ) {
String key = new String(iter.key());
if (key.startsWith(prefixOfEvent)) {
count.incrementAndGet();
LOGGER.info("Value:" + new String(iter.value()));
}
iter.next();
}
initialized.set(true);
}
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 AuditDoipClient getOrCreateConnection(String subscriberId) {
return client.convertDoidToRepo(subscriberId);
}
@Override
public DoipMessage subscribe(String topicId, String subscriberId, boolean needReplay, DoipMessage request) {
addSubscribers(topicId, subscriberId);
int total = count.get();
if (needReplay) {
new Thread(() -> {
AuditDoipClient client = getOrCreateConnection(subscriberId);
try {
for (int i = 0; i < total; i++) {
String msg = storageManager.get(prefixOfEvent + i);
DoipMessage message = GSON.fromJson(msg, DoipMessage.class);
client.sendMessage(message, null);
}
} catch (Exception ignored) {
}
}).start();
}
DoipMessageFactory.DoipMessageBuilder builder = new DoipMessageFactory.DoipMessageBuilder();
builder.createResponse(DoipResponseCode.Success, request).setBody((total + "").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) {
throw new IllegalStateException("unsupported message type");
}
@Override
public DoipMessage sendDataInList(String topicId, String subscriberId, JsonArray indexList, DoipMessage request) {
throw new IllegalStateException("unsupported message type");
}
@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 void publish(String topicId, DoipMessage request) {
if (!initialized.get()) Thread.yield();
JsonArray subscribers = getAsJson(topicId, new JsonArray()).getAsJsonArray();
request.header.parameters.attributes.addProperty("topicId", topicId);
request.header.parameters.attributes.addProperty("publishType", PublishMessageType.Data.name());
String key = prefixOfEvent + count.getAndIncrement();
storageManager.put(key, GSON.toJson(request));
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();
}
}