如何使用Sawtooth Java SDK创建通道事件?

如何使用Sawtooth Java SDK创建通道事件?,java,events,hyperledger-sawtooth,Java,Events,Hyperledger Sawtooth,HyperLeger Sawtooth支持订阅事务处理器中的事件。但是,是否有一种方法可以在事务处理器中创建特定于应用程序的事件,如Python示例所示: ctx.addEvent( “协议/创建”, [[“名称”,“协议”], [“地址”,地址], [“买方名称”,协议.买方名称], [“卖方名称”,协议.卖方名称], ['house id',agreement.house id], ['creator',signer]], 空) 在当前的Sawtooth Java SDK v0.1.2中,

HyperLeger Sawtooth支持订阅事务处理器中的事件。但是,是否有一种方法可以在事务处理器中创建特定于应用程序的事件,如Python示例所示:

ctx.addEvent(
“协议/创建”,
[[“名称”,“协议”],
[“地址”,地址],
[“买方名称”,协议.买方名称],
[“卖方名称”,协议.卖方名称],
['house id',agreement.house id],
['creator',signer]],
空)
在当前的Sawtooth Java SDK v0.1.2中,唯一的覆盖是

apply(TpProcessRequest,状态)
没有上下文。但是,在此处的文档中:

addEvent(TpProcessRequest,上下文)
到目前为止,我已设法监听事件
sawtooth/state delta
,但这给了我该
tx系列的所有状态更改

导入sawtooth.sdk.protobuf.EventSubscription;
导入sawtooth.sdk.protobuf.EventFilter;
导入sawtooth.sdk.protobuf.clientEventsSubscriberRequest;
导入sawtooth.sdk.protobuf.clientEventsSubscriberResponse;
导入sawtooth.sdk.protobuf.clientEventsSubscribeRequest;
导入sawtooth.sdk.protobuf.Message;
EventFilter=EventFilter.newBuilder()
.setKey(“地址”)
.setMatchString(命名空间.concat(“.*))
.setFilterType(EventFilter.FilterType.REGEX_ANY)
.build();
EventSubscription=EventSubscription.newBuilder()
.setEventType(“锯齿形/状态增量”)
.addFilters(过滤器)
.build();
上下文=新的ZContext();
socket=context.createSocket(ZMQ.DEALER);
插座。连接(“tcp://sawtooth-rest:4004");
ClientEventsSubscriberRequest请求=ClientEventsSubscriberRequest.newBuilder()
.addSubscriptions(订阅)
.build();
message=message.newBuilder()
.setCorrelationId(“123”)
.setMessageType(Message.MessageType.CLIENT\u EVENTS\u SUBSCRIBE\u请求)
.setContent(request.toByteString())
.build();
send(message.toByteArray());
一旦注册了
Message.MessageType.CLIENT\u EVENTS\u SUBSCRIBE\u请求
,我就会在线程循环中获取消息

我希望在TransactionHandler中能够
addEvent()
或创建某种类型的事件,然后使用Java SDK订阅这些事件


还有人尝试过在Sawtooth上用JAVA创建自定义事件吗?

下面是一个在Python中添加事件的示例。Java也将是类似的。 在事务处理器中添加自定义命名事件:

context.add_事件(event_type=“cookiejar/bake”,attributes=[(“cookies baked”,amount)])

以下是用Python和Go编写的事件处理程序示例: Java也将是类似的。事件处理程序中的逻辑基本上是:

  • 订阅您想要收听的活动
  • 将请求发送到验证器
  • 读取并解析订阅响应
  • 在循环中,侦听循环中订阅的事件
  • 退出循环后(如果有),取消订阅rom事件

  • 对于那些试图使用java SDK发布/订阅事件的人,没有直接的API可用。至少我找不到它,我正在使用1.0 docker图像。 因此,要发布事件,需要直接发布到sawtooth rest api服务器。需要注意以下几点:

  • 您需要一个仅对每个请求有效的上下文id。您可以从apply()方法中的请求中获取此信息。(代码如下)。因此,请确保在事务发布期间(即在apply()方法的实现期间)发布事件
  • 事件结构将如文档中所述
  • 如果事务成功且块已提交,则在事件订阅服务器中获取事件,否则它不会显示
  • 创建订阅服务器时,您需要订阅
  • 锯齿/块提交

    事件并向您的事件类型添加附加订阅,例如“myNS/my event”

    事件发布代码示例:

    public void apply(TpProcessRequest request, State state) throws InvalidTransactionException, InternalError {
    
           ///process your trasaction first
    
            sawtooth.sdk.messaging.Stream eventStream = new Stream("tcp://localhost:4004"); // make this in the constructor of class NOT here
            List<Attribute> attrList = new ArrayList<>();
            Attribute attrs = Attribute.newBuilder().setKey("someKey").setValue("someValue").build();
    
            attrList.add(attrs);
    
            Event appEvent = Event.newBuilder().setEventType("myNS/my-event-type")
                    .setData( <some ByteString here>).addAllAttributes(attrList).build();
            TpEventAddRequest addEventRequest = TpEventAddRequest.newBuilder()
                    .setContextId(request.getContextId()).setEvent(appEvent).build();
            Future sawtoothSubsFuture = eventStream.send(MessageType.TP_EVENT_ADD_REQUEST, addEventRequest.toByteString());
    
            try {
                System.out.println(sawtoothSubsFuture.getResult());
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
        }
    

    我的问题不是如何,而是与当前的Sawtooth Java SDK v0.1.2有关。SDK的当前实现不发送
    上下文
    对象,而是发送
    状态
    对象。而在Sawtooth SDK Git上,源代码显示了
    context
    对象,该对象的接口是
    addEvent()
    ,与其他SDK(如Phyton/Go)保持一致。那么,我是否错过了v0.1.3或v0.1.2的最新版本,我现在只需要接受它,从锯齿
    上下文创建我自己的ZMQ消息,并在新Java SDK与当前GIT源代码对齐时使用它?您还可以提交JIRA通知单并报告错误。更好的是,提交一份带有修复程序的PR。JIRA:(登录或创建Linux基础ID登录,然后转到“锯齿”)PR:用GITHUB文件进行PR,有人发现这是针对java SDK的吗?我完全被困在这一点上了?apply()方法中没有可用的上下文。尽管TpProcessRequest对象中有一个getContextId()。
    
    try {
                
                
                EventFilter eventFilter = EventFilter.newBuilder().setKey("address")
                        .setMatchString(String.format("^%s.*", "myNamespace"))
                        .setFilterType(FilterType.REGEX_ANY).build();
    
                //subscribe to sawtooth/block-commit
                EventSubscription deltaSubscription = EventSubscription.newBuilder().setEventType("sawtooth/block-commit")
                        .addFilters(eventFilter)
                        .build();
    
                EventSubscription mySubscription = EventSubscription.newBuilder().setEventType("myNS/my-event-type")
                        .build(); //no filters added for my events.
                
                ClientEventsSubscribeRequest subsReq = ClientEventsSubscribeRequest.newBuilder()
                        .addLastKnownBlockIds("0000000000000000").addSubscriptions(deltaSubscription).addSubscriptions(mySubscription)
                        .build();
    
                Future sawtoothSubsFuture = eventStream.send(MessageType.CLIENT_EVENTS_SUBSCRIBE_REQUEST,
                        subsReq.toByteString());
    
                ClientEventsSubscribeResponse eventSubsResp = ClientEventsSubscribeResponse
                        .parseFrom(sawtoothSubsFuture.getResult());
    
                System.out.println("eventSubsResp.getStatus() :: " + eventSubsResp.getStatus());
                
                 if (eventSubsResp.getStatus().equals(ClientEventsSubscribeResponse.Status.UNKNOWN_BLOCK)) {
                     System.out.println("Unknown block ");
                     // retry connection if this happens by calling this same method
                     
                 }
                if(!eventSubsResp.getStatus().equals(ClientEventsSubscribeResponse.Status.OK)) {
                    System.out.println("Subscription failed with status " + eventSubsResp.getStatus());
                    throw new RuntimeException("cannot connect ");
                } else {
                    isActive = true;
                    System.out.println("Making active ");
                }
                
                
                while(isActive) {
                    Message eventMsg =  eventStream.receive();
                    EventList eventList = EventList.parseFrom(eventMsg.getContent());
                    for (Event event : eventList.getEventsList()) {                 
                        System.out.println("An event ::::");
                        System.out.println(event);
                    }
                    
                }
            } catch (Exception e) {
                e.printStackTrace();
            }