@@ -3,6 +3,7 @@ package natsnodev1
33import (
44 "context"
55 "errors"
6+ "fmt"
67 "time"
78
89 "connectrpc.com/connect"
@@ -13,18 +14,23 @@ import (
1314 sdkv2betalib "github.com/openecosystems/ecosystem/go/oeco-sdk/v2beta"
1415 zaploggerv1 "github.com/openecosystems/ecosystem/go/oeco-sdk/v2beta/bindings/zap"
1516 specv2pb "github.com/openecosystems/ecosystem/go/oeco-sdk/v2beta/gen/platform/spec/v2"
17+ "google.golang.org/protobuf/types/known/timestamppb"
1618)
1719
1820// MultiplexCommandSync sends a command synchronously by publishing it to a NATS stream and awaiting a reply.
1921// Uses Nats Publish and Subscribe Pattern
20- func (b * Binding ) MultiplexCommandSync (ctx context.Context , s * specv2pb.Spec , command * SpecCommand ) (* nats.Msg , error ) {
22+ func (b * Binding ) MultiplexCommandSync (ctx context.Context , spec * specv2pb.Spec , command * SpecCommand ) (* nats.Msg , error ) {
2123 if command == nil {
2224 return nil , sdkv2betalib .ErrServerInternal .WithInternalErrorDetail (errors .New ("a SpecCommand object is required" ))
2325 }
2426
27+ if spec == nil {
28+ return nil , sdkv2betalib .ErrServerInternal .WithInternalErrorDetail (errors .New ("a Spec object is required" ))
29+ }
30+
2531 log := * zaploggerv1 .Bound .Logger
26- s .SpecEvent = command .CommandName
27- s .SpecType = command .EntityTypeName
32+ spec .SpecEvent = command .CommandName
33+ spec .SpecType = command .EntityTypeName
2834
2935 // Encrypt here
3036 //fmt.Println(command.Request.ProtoReflect())
@@ -41,77 +47,92 @@ func (b *Binding) MultiplexCommandSync(ctx context.Context, s *specv2pb.Spec, co
4147 return nil , sdkv2betalib .ErrServerInternal .WithInternalErrorDetail (errors .New ("internal error" ))
4248 }
4349
44- s .Data = data
50+ spec .Data = data
4551
46- specBytes , err := proto .Marshal (s )
52+ specBytes , err := proto .Marshal (spec )
4753 if err != nil {
4854 return nil , sdkv2betalib .ErrServerInternal .WithInternalErrorDetail (errors .New ("could not marshall spec" ))
4955 }
5056
5157 subject := GetMultiplexedRequestSubjectName (command .Stream .StreamPrefix (), command .CommandTopic , command .Procedure )
5258
53- log .Debug ("Issuing a multiplex command: " + command .Procedure + ", on channel: " + subject )
59+ fields := receivedFields (spec , subject )
60+ log .Info ("Issuing a multiplex command: " + command .Procedure , fields ... )
5461
55- return publish (b .Nats , subject , s , specBytes )
62+ return publish (b .Nats , subject , spec , specBytes )
5663}
5764
5865// MultiplexEventSync sends an event to a multiplexed stream and waits for the response or error within the specified timeout.
5966// Uses Nats Publish and Subscribe Pattern
60- func (b * Binding ) MultiplexEventSync (_ context.Context , s * specv2pb.Spec , event * SpecEvent ) (* nats.Msg , error ) {
67+ func (b * Binding ) MultiplexEventSync (_ context.Context , spec * specv2pb.Spec , event * SpecEvent ) (* nats.Msg , error ) {
6168 if event == nil {
6269 return nil , sdkv2betalib .ErrServerInternal .WithInternalErrorDetail (errors .New ("a SpecEvent object is required" ))
6370 }
6471
72+ if spec == nil {
73+ return nil , sdkv2betalib .ErrServerInternal .WithInternalErrorDetail (errors .New ("a Spec object is required" ))
74+ }
75+
6576 log := * zaploggerv1 .Bound .Logger
66- s .SpecEvent = event .EventName
67- s .SpecType = event .EntityTypeName
77+ spec .SpecEvent = event .EventName
78+ spec .SpecType = event .EntityTypeName
6879
6980 data , err := anypb .New (event .Request )
7081 if err != nil {
7182 return nil , sdkv2betalib .ErrServerInternal .WithInternalErrorDetail (errors .New ("internal error" ))
7283 }
7384
74- s .Data = data
85+ spec .Data = data
7586
76- specBytes , err := proto .Marshal (s )
87+ specBytes , err := proto .Marshal (spec )
7788 if err != nil {
7889 return nil , sdkv2betalib .ErrServerInternal .WithInternalErrorDetail (errors .New ("could not marshall spec" ))
7990 }
8091
8192 subject := GetMultiplexedRequestSubjectName (event .Stream .StreamPrefix (), event .EventTopic , event .Procedure )
8293
83- log .Debug ("Issuing a multiplex event: " + event .Procedure + ", on channel: " + subject )
94+ fields := receivedFields (spec , subject )
95+ log .Info ("Issuing a multiplex event: " + event .Procedure , fields ... )
8496
85- return publish (b .Nats , subject , s , specBytes )
97+ return publish (b .Nats , subject , spec , specBytes )
8698}
8799
88- func publish (n * nats.Conn , subject string , s * specv2pb.Spec , specBytes []byte ) (* nats.Msg , error ) {
100+ func publish (n * nats.Conn , subject string , spec * specv2pb.Spec , specBytes []byte ) (* nats.Msg , error ) {
101+ log := * zaploggerv1 .Bound .Logger
89102 reply , err := n .RequestMsg (& nats.Msg {
90103 Subject : subject ,
91104 Data : specBytes ,
92105 }, 10 * time .Second )
93106 if err != nil {
94107 switch {
95108 case errors .Is (err , nats .ErrTimeout ):
96- return nil , ErrTimeout .WithSpecDetail (s )
109+ return nil , ErrTimeout .WithSpecDetail (spec ). WithInternalErrorDetail ( err )
97110 case errors .Is (err , nats .ErrNoResponders ):
98111 // no responders
99- return nil , ErrNoResponders .WithSpecDetail (s )
112+ return nil , ErrNoResponders .WithSpecDetail (spec ). WithInternalErrorDetail ( err )
100113 case errors .Is (err , nats .ErrConnectionClosed ):
101114 // NATS connection was closed
102- return nil , sdkv2betalib .ErrServerInternal .WithSpecDetail (s ).WithInternalErrorDetail (err )
115+ return nil , sdkv2betalib .ErrServerInternal .WithSpecDetail (spec ).WithInternalErrorDetail (err )
103116 case errors .Is (err , nats .ErrBadSubscription ):
104117 // something wrong with the sub
105- return nil , sdkv2betalib .ErrServerInternal .WithSpecDetail (s ).WithInternalErrorDetail (err )
118+ return nil , sdkv2betalib .ErrServerInternal .WithSpecDetail (spec ).WithInternalErrorDetail (err )
106119 default :
107120 // unknown or generic error
108- return nil , sdkv2betalib .ErrServerInternal .WithSpecDetail (s ).WithInternalErrorDetail (errors .New ("unhandled NATS error" ), err )
121+ return nil , sdkv2betalib .ErrServerInternal .WithSpecDetail (spec ).WithInternalErrorDetail (errors .New ("unhandled NATS error" ), err )
109122 }
110123 }
111124
112125 if reply == nil {
113- return nil , sdkv2betalib .ErrServerInternal .WithSpecDetail (s ).WithInternalErrorDetail (errors .New ("received nil reply from NATS responder" ))
126+ return nil , sdkv2betalib .ErrServerInternal .WithSpecDetail (spec ).WithInternalErrorDetail (errors .New ("received nil reply from NATS responder" ))
127+ }
128+
129+ spec .CompletedAt = timestamppb .Now ()
130+ fields := completedFields (spec , subject )
131+ var milliseconds int64
132+ if spec .CompletedAt != nil && spec .ReceivedAt != nil {
133+ milliseconds = spec .CompletedAt .AsTime ().Sub (spec .ReceivedAt .AsTime ()).Milliseconds ()
114134 }
135+ log .Info (fmt .Sprintf ("Completed multiplexed request in %d ms\n " , milliseconds ), fields ... )
115136
116137 return reply , err
117138}
0 commit comments