Skip to content

Commit

Permalink
Update the event-type cleanup logic (kyma-project#11007)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcobebway committed Apr 1, 2021
1 parent 45e0858 commit e446fcb
Show file tree
Hide file tree
Showing 11 changed files with 248 additions and 178 deletions.
21 changes: 19 additions & 2 deletions components/event-publisher-proxy/pkg/handler/http/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,16 @@ func (h *Handler) publishLegacyEventsAsCE(writer http.ResponseWriter, request *h
statusCode, dispatchTime, respBody := h.send(ctx, event)
// Change response as per old error codes
h.LegacyTransformer.TransformsCEResponseToLegacyResponse(writer, statusCode, event, string(respBody))
h.Logger.Infof("Event dispatched id:[%s] statusCode:[%d] duration:[%s] responseBody:[%s]", event.ID(), statusCode, dispatchTime, respBody)

h.Logger.WithFields(
logrus.Fields{
"id": event.ID(),
"source": event.Source(),
"type": event.Type(),
"statusCode": statusCode,
"duration": dispatchTime,
"responseBody": respBody,
}).Info("Event dispatched")
}

func (h *Handler) publishCloudEvents(writer http.ResponseWriter, request *http.Request) {
Expand Down Expand Up @@ -162,7 +171,15 @@ func (h *Handler) publishCloudEvents(writer http.ResponseWriter, request *http.R
statusCode, dispatchTime, respBody := h.send(ctx, event)
h.writeResponse(writer, statusCode, respBody)

h.Logger.Infof("Event dispatched id:[%s] statusCode:[%d] duration:[%s] responseBody:[%s]", event.ID(), statusCode, dispatchTime, respBody)
h.Logger.WithFields(
logrus.Fields{
"id": event.ID(),
"source": event.Source(),
"type": event.Type(),
"statusCode": statusCode,
"duration": dispatchTime,
"responseBody": respBody,
}).Info("Event dispatched")
}

// writeResponse writes the HTTP response given the status code and response body.
Expand Down
21 changes: 19 additions & 2 deletions components/event-publisher-proxy/pkg/handler/nats/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,16 @@ func (h *Handler) publishLegacyEventsAsCE(writer http.ResponseWriter, request *h
statusCode, dispatchTime, respBody := h.send(ctx, event)
// Change response as per old error codes
h.LegacyTransformer.TransformsCEResponseToLegacyResponse(writer, statusCode, event, string(respBody))
h.Logger.Infof("Event dispatched id:[%s] statusCode:[%d] duration:[%s] responseBody:[%s]", event.ID(), statusCode, dispatchTime, respBody)

h.Logger.WithFields(
logrus.Fields{
"id": event.ID(),
"source": event.Source(),
"type": event.Type(),
"statusCode": statusCode,
"duration": dispatchTime,
"responseBody": respBody,
}).Info("Event dispatched")
}

func (h *Handler) publishCloudEvents(writer http.ResponseWriter, request *http.Request) {
Expand Down Expand Up @@ -144,7 +153,15 @@ func (h *Handler) publishCloudEvents(writer http.ResponseWriter, request *http.R
statusCode, dispatchTime, respBody := h.send(ctx, event)
h.writeResponse(writer, statusCode, respBody)

h.Logger.Infof("Event dispatched id:[%s] statusCode:[%d] duration:[%s] responseBody:[%s]", event.ID(), statusCode, dispatchTime, respBody)
h.Logger.WithFields(
logrus.Fields{
"id": event.ID(),
"source": event.Source(),
"type": event.Type(),
"statusCode": statusCode,
"duration": dispatchTime,
"responseBody": respBody,
}).Info("Event dispatched")
}

// writeResponse writes the HTTP response given the status code and response body.
Expand Down
17 changes: 16 additions & 1 deletion components/event-publisher-proxy/pkg/legacy-events/legacy.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package legacy

import (
"encoding/json"
"fmt"
"net/http"
"regexp"
"strings"
"time"

cev2event "github.com/cloudevents/sdk-go/v2/event"
Expand Down Expand Up @@ -168,10 +170,23 @@ func (t Transformer) convertPublishRequestToCloudEvent(appName string, publishRe
event.SetID(uuid.New().String())
}

eventType := formatEventType4BEB(t.eventTypePrefix, appName, publishRequest.PublishrequestV1.EventType, publishRequest.PublishrequestV1.EventTypeVersion)
eventTypeCombined := combineEventTypeSegments(publishRequest.PublishrequestV1.EventType)
eventType := formatEventType4BEB(t.eventTypePrefix, appName, eventTypeCombined, publishRequest.PublishrequestV1.EventTypeVersion)
event.SetSource(t.bebNamespace)
event.SetType(eventType)
event.SetExtension(eventTypeVersionExtensionKey, publishRequest.PublishrequestV1.EventTypeVersion)
event.SetDataContentType(ContentTypeApplicationJSON)
return &event, nil
}

// combineEventTypeSegments returns an event-type with exactly two segments separated by "." if the given event-type
// has more than two segments separated by "." (e.g. "Account.Order.Created" becomes "AccountOrder.Created")
func combineEventTypeSegments(eventType string) string {
parts := strings.Split(eventType, ".")
if len(parts) > 2 {
businessObject := strings.Join(parts[0:len(parts)-1], "")
operation := parts[len(parts)-1]
eventType = fmt.Sprintf("%s.%s", businessObject, operation)
}
return eventType
}
37 changes: 34 additions & 3 deletions components/event-publisher-proxy/pkg/legacy-events/legacy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,27 @@ import (
. "github.com/kyma-project/kyma/components/event-publisher-proxy/testing"
)

const (
eventTypeMultiSegment = "Segment1.Segment2.Segment3.Segment4.Segment5"
eventTypeMultiSegmentCombined = "Segment1Segment2Segment3Segment4.Segment5"
)

func TestConvertPublishRequestToCloudEvent(t *testing.T) {
bebNs := MessagingNamespace
eventTypePrefix := MessagingEventTypePrefix
legacyTransformer := NewTransformer(bebNs, eventTypePrefix, nil)
eventID := EventID
appName := ApplicationName
legacyEventType := LegacyEventType
legacyEventVersion := LegacyEventTypeVersion
data := LegacyEventData
timeNow := time.Now()
expectedEventType := formatEventType4BEB(eventTypePrefix, appName, legacyEventType, legacyEventVersion)
expectedEventType := formatEventType4BEB(eventTypePrefix, appName, eventTypeMultiSegmentCombined, legacyEventVersion)
timeNowStr := timeNow.Format(time.RFC3339)
timeNowFormatted, _ := time.Parse(time.RFC3339, timeNowStr)
publishReqParams := &legacyapi.PublishEventParametersV1{
PublishrequestV1: legacyapi.PublishRequestV1{
EventID: eventID,
EventType: legacyEventType,
EventType: eventTypeMultiSegment,
EventTime: timeNowStr,
EventTypeVersion: legacyEventVersion,
Data: data,
Expand Down Expand Up @@ -63,3 +67,30 @@ func TestConvertPublishRequestToCloudEvent(t *testing.T) {
t.Errorf("incorrect eventtype extension, want: %s, got: %s", legacyEventVersion, gotExtension)
}
}

func TestCombineEventTypeSegments(t *testing.T) {
testCases := []struct {
name string
givenEventType string
wantEventType string
}{
{
name: "event-type with two segments",
givenEventType: LegacyEventType,
wantEventType: LegacyEventType,
},
{
name: "event-type with more than two segments",
givenEventType: eventTypeMultiSegment,
wantEventType: eventTypeMultiSegmentCombined,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
if gotEventType := combineEventTypeSegments(tc.givenEventType); tc.wantEventType != gotEventType {
t.Fatalf("invalid event-type want: %s, got: %s", tc.wantEventType, gotEventType)
}
})
}
}
5 changes: 0 additions & 5 deletions components/eventing-controller/pkg/application/clean.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,3 @@ func GetCleanTypeOrName(application *applicationv1alpha1.Application) string {
func GetCleanName(name string) string {
return invalidApplicationNameSegment.ReplaceAllString(name, "")
}

// IsCleanName returns true if the name contains alphanumeric characters only, otherwise returns false
func IsCleanName(name string) bool {
return !invalidApplicationNameSegment.MatchString(name)
}
20 changes: 0 additions & 20 deletions components/eventing-controller/pkg/application/clean_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,23 +54,3 @@ func TestCleanName(t *testing.T) {
}
}
}

func TestIsCleanName(t *testing.T) {
testCases := []struct {
givenName string
wantClean bool
}{
{givenName: "with.dot", wantClean: false},
{givenName: "with-dash", wantClean: false},
{givenName: "with_underscore", wantClean: false},
{givenName: "with#special$characters", wantClean: false},
{givenName: "alphabetical", wantClean: true},
{givenName: "alphanumeric0123", wantClean: true},
}

for _, tc := range testCases {
if gotClean := IsCleanName(tc.givenName); tc.wantClean != gotClean {
t.Errorf("Is clean application name:[%s] failed, want:[%v] but got:[%v]", tc.givenName, tc.wantClean, gotClean)
}
}
}
36 changes: 26 additions & 10 deletions components/eventing-controller/pkg/handlers/eventtype/clean.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
package eventtype

import (
"regexp"

"github.com/go-logr/logr"
"github.com/kyma-project/kyma/components/eventing-controller/pkg/application"
)

var (
// invalidEventTypeSegment used to match and replace none-alphanumeric characters in the event-type segments
// as per SAP Event spec https://github.tools.sap/CentralEngineering/sap-event-specification#type
invalidEventTypeSegment = regexp.MustCompile("[^a-zA-Z0-9.]")
)

type Cleaner interface {
Clean(eventType string) (string, error)
}
Expand All @@ -22,23 +30,31 @@ func NewCleaner(eventTypePrefix string, applicationLister *application.Lister, l
return &cleaner{eventTypePrefix: eventTypePrefix, applicationLister: applicationLister, logger: logger}
}

// Clean cleans the application name segment in the event-type from none-alphanumeric characters
// and returns the clean event-type, or returns an error if the event-type parsing failed
// Clean cleans the event-type from none-alphanumeric characters and returns it
// or returns an error if the event-type parsing failed
func (c cleaner) Clean(eventType string) (string, error) {
appName, event, version, err := parse(eventType, c.eventTypePrefix)
if err != nil {
c.logger.Error(err, "failed to parse event-type", "prefix", c.eventTypePrefix, "type", eventType)
return "", err
}

// handle existing applications
if appObj, err := c.applicationLister.Get(appName); err == nil {
eventType = build(c.eventTypePrefix, application.GetCleanTypeOrName(appObj), event, version)
return eventType, nil
// clean the application name
var eventTypeClean string
if appObj, err := c.applicationLister.Get(appName); err != nil {
c.logger.Info("cannot find application", "name", appName)
eventTypeClean = build(c.eventTypePrefix, application.GetCleanName(appName), event, version)
} else {
eventTypeClean = build(c.eventTypePrefix, application.GetCleanTypeOrName(appObj), event, version)
}

// handle non-existing applications
c.logger.Info("failed to get application", "name", appName)
eventType = build(c.eventTypePrefix, application.GetCleanName(appName), event, version)
return eventType, nil
// clean the event-type segments
eventTypeClean = cleanEventType(eventTypeClean)
c.logger.Info("clean event-type", "before", eventType, "after", eventTypeClean)

return eventTypeClean, nil
}

func cleanEventType(eventType string) string {
return invalidEventTypeSegment.ReplaceAllString(eventType, "")
}

0 comments on commit e446fcb

Please sign in to comment.