org.bdware.doip.event.verified.VerifiedPublisher 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
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();
}
}