github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/service/broker/handler/handler.go (about) 1 package handler 2 3 import ( 4 "context" 5 6 pb "github.com/tickoalcantara12/micro/v3/proto/broker" 7 "github.com/tickoalcantara12/micro/v3/service/auth" 8 "github.com/tickoalcantara12/micro/v3/service/broker" 9 "github.com/tickoalcantara12/micro/v3/service/context/metadata" 10 "github.com/tickoalcantara12/micro/v3/service/errors" 11 "github.com/tickoalcantara12/micro/v3/service/logger" 12 authns "github.com/tickoalcantara12/micro/v3/util/auth/namespace" 13 ) 14 15 type Broker struct{} 16 17 func (h *Broker) Publish(ctx context.Context, req *pb.PublishRequest, rsp *pb.Empty) error { 18 // authorize the request 19 acc, ok := auth.AccountFromContext(ctx) 20 if !ok { 21 return errors.Unauthorized("broker.Broker.Publish", authns.ErrForbidden.Error()) 22 } 23 24 // validate the request 25 if req.Message == nil { 26 return errors.BadRequest("broker.Broker.Publish", "Missing message") 27 } 28 29 // ensure the header is not nil 30 if req.Message.Header == nil { 31 req.Message.Header = map[string]string{} 32 } 33 34 // set any headers which aren't already set 35 if md, ok := metadata.FromContext(ctx); ok { 36 for k, v := range md { 37 if _, ok := req.Message.Header[k]; !ok { 38 req.Message.Header[k] = v 39 } 40 } 41 } 42 43 logger.Debugf("Publishing message to %s topic in the %v namespace", req.Topic, acc.Issuer) 44 err := broker.DefaultBroker.Publish(acc.Issuer+"."+req.Topic, &broker.Message{ 45 Header: req.Message.Header, 46 Body: req.Message.Body, 47 }) 48 logger.Debugf("Published message to %s topic in the %v namespace", req.Topic, acc.Issuer) 49 if err != nil { 50 return errors.InternalServerError("broker.Broker.Publish", err.Error()) 51 } 52 return nil 53 } 54 55 func (h *Broker) Subscribe(ctx context.Context, req *pb.SubscribeRequest, stream pb.Broker_SubscribeStream) error { 56 // authorize the request 57 acc, ok := auth.AccountFromContext(ctx) 58 if !ok { 59 return errors.Unauthorized("broker.Broker.Subscribe", authns.ErrForbidden.Error()) 60 } 61 ns := acc.Issuer 62 63 if len(req.Topic) == 0 { 64 return errors.BadRequest("broker.Broker.Subscribe", "Missing topic") 65 } 66 errChan := make(chan error, 1) 67 68 // message Broker to stream back messages from broker 69 Broker := func(m *broker.Message) error { 70 if err := stream.Send(&pb.Message{ 71 Header: m.Header, 72 Body: m.Body, 73 }); err != nil { 74 select { 75 case errChan <- err: 76 return err 77 default: 78 return err 79 } 80 } 81 return nil 82 } 83 84 logger.Debugf("Subscribing to %s topic in namespace %v", req.Topic, ns) 85 opts := []broker.SubscribeOption{} 86 if len(req.Queue) > 0 { 87 opts = append(opts, broker.Queue(req.Queue)) 88 } 89 sub, err := broker.DefaultBroker.Subscribe(ns+"."+req.Topic, Broker, opts...) 90 if err != nil { 91 return errors.InternalServerError("broker.Broker.Subscribe", err.Error()) 92 } 93 defer func() { 94 logger.Debugf("Unsubscribing from topic %s in namespace %v", req.Topic, ns) 95 sub.Unsubscribe() 96 }() 97 98 select { 99 case <-ctx.Done(): 100 logger.Debugf("Context done for subscription to topic %s", req.Topic) 101 return nil 102 case err := <-errChan: 103 logger.Debugf("Subscription error for topic %s: %v", req.Topic, err) 104 return err 105 } 106 }