@@ -7,17 +7,17 @@ import (
77 "time"
88
99 "connectrpc.com/connect"
10- specv2pb "github.com/openecosystems/ecosystem/libs/protobuf/go/protobuf/gen/platform/spec/v2"
11-
12- zaploggerv1 "github.com/openecosystems/ecosystem/libs/partner/go/zap"
13-
1410 "github.com/nats-io/nats.go"
15- sdkv2alphalib "github.com/openecosystems/ecosystem/libs/public/go/sdk/v2alpha"
1611 "google.golang.org/protobuf/proto"
1712 "google.golang.org/protobuf/types/known/anypb"
13+
14+ zaploggerv1 "github.com/openecosystems/ecosystem/libs/partner/go/zap"
15+ specv2pb "github.com/openecosystems/ecosystem/libs/protobuf/go/protobuf/gen/platform/spec/v2"
16+ sdkv2alphalib "github.com/openecosystems/ecosystem/libs/public/go/sdk/v2alpha"
1817)
1918
2019// MultiplexCommandSync sends a command synchronously by publishing it to a NATS stream and awaiting a reply.
20+ // Uses Nats Publish and Subscribe Pattern
2121func (b * Binding ) MultiplexCommandSync (_ context.Context , s * specv2pb.Spec , command * SpecCommand ) (* nats.Msg , error ) {
2222 if command == nil {
2323 return nil , sdkv2alphalib .ErrServerInternal .WithInternalErrorDetail (errors .New ("a SpecCommand object is required" ))
@@ -60,7 +60,7 @@ func (b *Binding) MultiplexCommandSync(_ context.Context, s *specv2pb.Spec, comm
6060 reply , err := n .RequestMsg (& nats.Msg {
6161 Subject : subject ,
6262 Data : specBytes ,
63- }, 4 * time .Second )
63+ }, 10 * time .Second )
6464 if err != nil {
6565 fmt .Println (err )
6666 }
@@ -69,6 +69,7 @@ func (b *Binding) MultiplexCommandSync(_ context.Context, s *specv2pb.Spec, comm
6969}
7070
7171// MultiplexEventSync sends an event to a multiplexed stream and waits for the response or error within the specified timeout.
72+ // Uses Nats Publish and Subscribe Pattern
7273func (b * Binding ) MultiplexEventSync (_ context.Context , s * specv2pb.Spec , event * SpecEvent ) (* nats.Msg , error ) {
7374 if event == nil {
7475 return nil , sdkv2alphalib .ErrServerInternal .WithInternalErrorDetail (errors .New ("a SpecEvent object is required" ))
@@ -103,10 +104,75 @@ func (b *Binding) MultiplexEventSync(_ context.Context, s *specv2pb.Spec, event
103104 reply , err := n .RequestMsg (& nats.Msg {
104105 Subject : subject ,
105106 Data : specBytes ,
106- }, 4 * time .Second )
107+ }, 10 * time .Second )
107108 if err != nil {
108109 fmt .Println (err )
109110 }
110111
111112 return reply , err
112113}
114+
115+ // MultiplexEventStreamSync sends an event to a multiplexed stream and waits for the response or error within the specified timeout.
116+ // Uses Nats Sync Publish for streaming
117+ func MultiplexEventStreamSync [T any ](ctx context.Context , s * specv2pb.Spec , event * SpecStreamEvent , nats * nats.Conn , stream * connect.ServerStream [T ], convert func (* nats.Msg ) (* T , error )) error {
118+ if event == nil {
119+ return sdkv2alphalib .ErrServerInternal .WithInternalErrorDetail (errors .New ("a SpecEvent object is required" ))
120+ }
121+
122+ log := * zaploggerv1 .Bound .Logger
123+
124+ s .SpecEvent = event .EventName
125+ s .SpecType = event .EntityTypeName
126+
127+ data , err := anypb .New (event .Request )
128+ if err != nil {
129+ log .Error (err .Error ())
130+ return connect .NewError (connect .CodeInternal , errors .New ("internal error" ))
131+ }
132+
133+ s .Data = data
134+
135+ subject := GetMultiplexedRequestSubjectName (event .Stream .StreamPrefix (), event .EventTopic , event .Procedure )
136+ responseSubject := GetStreamResponseSubjectName (event .Stream .StreamPrefix (), event .EventTopic , event .Procedure , s .MessageId )
137+
138+ specBytes , err := proto .Marshal (s )
139+ if err != nil {
140+ return sdkv2alphalib .ErrServerInternal .WithInternalErrorDetail (errors .New ("could not marshall spec" ))
141+ }
142+
143+ // Encrypt here
144+
145+ log .Debug ("Publishing on " + subject )
146+ if err = nats .Publish (subject , specBytes ); err != nil {
147+ return sdkv2alphalib .ErrServerInternal .WithInternalErrorDetail (errors .New ("failed to publish" )).WithInternalErrorDetail (err )
148+ }
149+
150+ // Subscribe to streamed results
151+ log .Debug ("Waiting on results from " + responseSubject )
152+ sub , err := nats .SubscribeSync (responseSubject )
153+ if err != nil {
154+ return sdkv2alphalib .ErrServerInternal .WithInternalErrorDetail (errors .New ("could not subscribe stream sync to nats" )).WithInternalErrorDetail (err )
155+ }
156+
157+ defer sub .Unsubscribe ()
158+
159+ for {
160+ msg , err1 := sub .NextMsgWithContext (ctx )
161+ if err1 != nil {
162+ if errors .Is (err1 , context .Canceled ) {
163+ return nil
164+ }
165+ return sdkv2alphalib .ErrServerInternal .WithInternalErrorDetail (errors .New ("could not process additional events" )).WithInternalErrorDetail (err1 )
166+ }
167+
168+ converted , err1 := convert (msg )
169+ if err1 != nil {
170+ return sdkv2alphalib .ErrServerInternal .WithInternalErrorDetail (errors .New ("could not convert event" )).WithInternalErrorDetail (err1 )
171+ }
172+
173+ err1 = stream .Send (converted )
174+ if err != nil {
175+ return sdkv2alphalib .ErrServerInternal .WithInternalErrorDetail (errors .New ("could not stream event" )).WithInternalErrorDetail (err1 )
176+ }
177+ }
178+ }
0 commit comments