gitee.com/liuxuezhan/go-micro-v1.18.0@v1.0.0/api/handler/cloudevents/cloudevents.go (about)

     1  // Package cloudevents provides a cloudevents handler publishing the event using the go-micro/client
     2  package cloudevents
     3  
     4  import (
     5  	"net/http"
     6  	"path"
     7  	"regexp"
     8  	"strings"
     9  
    10  	"gitee.com/liuxuezhan/go-micro-v1.18.0/api/handler"
    11  	"gitee.com/liuxuezhan/go-micro-v1.18.0/util/ctx"
    12  )
    13  
    14  type event struct {
    15  	options handler.Options
    16  }
    17  
    18  var (
    19  	Handler   = "cloudevents"
    20  	versionRe = regexp.MustCompilePOSIX("^v[0-9]+$")
    21  )
    22  
    23  func eventName(parts []string) string {
    24  	return strings.Join(parts, ".")
    25  }
    26  
    27  func evRoute(ns, p string) (string, string) {
    28  	p = path.Clean(p)
    29  	p = strings.TrimPrefix(p, "/")
    30  
    31  	if len(p) == 0 {
    32  		return ns, "event"
    33  	}
    34  
    35  	parts := strings.Split(p, "/")
    36  
    37  	// no path
    38  	if len(parts) == 0 {
    39  		// topic: namespace
    40  		// action: event
    41  		return strings.Trim(ns, "."), "event"
    42  	}
    43  
    44  	// Treat /v[0-9]+ as versioning
    45  	// /v1/foo/bar => topic: v1.foo action: bar
    46  	if len(parts) >= 2 && versionRe.Match([]byte(parts[0])) {
    47  		topic := ns + "." + strings.Join(parts[:2], ".")
    48  		action := eventName(parts[1:])
    49  		return topic, action
    50  	}
    51  
    52  	// /foo => topic: ns.foo action: foo
    53  	// /foo/bar => topic: ns.foo action: bar
    54  	topic := ns + "." + strings.Join(parts[:1], ".")
    55  	action := eventName(parts[1:])
    56  
    57  	return topic, action
    58  }
    59  
    60  func (e *event) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    61  	// request to topic:event
    62  	// create event
    63  	// publish to topic
    64  	topic, _ := evRoute(e.options.Namespace, r.URL.Path)
    65  
    66  	// create event
    67  	ev, err := FromRequest(r)
    68  	if err != nil {
    69  		http.Error(w, err.Error(), 500)
    70  		return
    71  	}
    72  
    73  	// get client
    74  	c := e.options.Service.Client()
    75  
    76  	// create publication
    77  	p := c.NewMessage(topic, ev)
    78  
    79  	// publish event
    80  	if err := c.Publish(ctx.FromRequest(r), p); err != nil {
    81  		http.Error(w, err.Error(), 500)
    82  		return
    83  	}
    84  }
    85  
    86  func (e *event) String() string {
    87  	return "cloudevents"
    88  }
    89  
    90  func NewHandler(opts ...handler.Option) handler.Handler {
    91  	return &event{
    92  		options: handler.NewOptions(opts...),
    93  	}
    94  }