Repository: nats-io/nats-server
Pull request #3823 (2023-01-27 11:37:17)

Mappings breaking changes
This undoes some breaking changes made in https://github.com/nats-io/nats-server/pull/3814

/cc @nats-io/core



Patch:
diff --git a/server/accounts.go b/server/accounts.go
index 5bd07472..1b9c5873 100644
--- a/server/accounts.go
+++ b/server/accounts.go
@@ -619,7 +619,7 @@ func (a *Account) AddWeightedMappings(src string, dests ...*MapDest) error {
 		if err != nil {
 			return err
 		}
-		tr, err := newSubjectTransform(src, d.Subject)
+		tr, err := NewSubjectTransform(src, d.Subject)
 		if err != nil {
 			return err
 		}
@@ -650,7 +650,7 @@ func (a *Account) AddWeightedMappings(src string, dests ...*MapDest) error {
 				// We need to make the appropriate markers for the wildcards etc.
 				dest = transformTokenize(dest)
 			}
-			tr, err := newSubjectTransform(src, dest)
+			tr, err := NewSubjectTransform(src, dest)
 			if err != nil {
 				return nil, err
 			}
@@ -1828,7 +1828,7 @@ func (a *Account) addServiceImport(dest *Account, from, to string, claim *jwt.Im
 		} else {
 			to, _ = transformUntokenize(to)
 			// Create a transform. Do so in reverse such that $ symbols only exist in to
-			if tr, err = newSubjectTransform(to, transformTokenize(from)); err != nil {
+			if tr, err = NewSubjectTransform(to, transformTokenize(from)); err != nil {
 				a.mu.Unlock()
 				return nil, fmt.Errorf("failed to create mapping transform for service import subject %q to %q: %v",
 					from, to, err)
@@ -2375,7 +2375,7 @@ func (a *Account) AddMappedStreamImportWithClaim(account *Account, from, to stri
 			usePub = true
 		} else {
 			// Create a transform
-			if tr, err = newSubjectTransform(from, transformTokenize(to)); err != nil {
+			if tr, err = NewSubjectTransform(from, transformTokenize(to)); err != nil {
 				return fmt.Errorf("failed to create mapping transform for stream import subject %q to %q: %v",
 					from, to, err)
 			}
diff --git a/server/stream.go b/server/stream.go
index 5d4226d1..7081f699 100644
--- a/server/stream.go
+++ b/server/stream.go
@@ -427,7 +427,7 @@ func (a *Account) addStreamWithAssignment(config *StreamConfig, fsConfig *FileSt
 			ssi.setIndexName(i)
 			// check the transform, if any, is valid
 			if ssi.SubjectTransformDest != _EMPTY_ {
-				if _, err = newSubjectTransform(ssi.FilterSubject, ssi.SubjectTransformDest); err != nil {
+				if _, err = NewSubjectTransform(ssi.FilterSubject, ssi.SubjectTransformDest); err != nil {
 					jsa.mu.Unlock()
 					return nil, fmt.Errorf("subject transform for the source not valid %w", err)
 				}
@@ -480,7 +480,7 @@ func (a *Account) addStreamWithAssignment(config *StreamConfig, fsConfig *FileSt
 
 	// Check for input subject transform
 	if cfg.SubjectTransform != nil {
-		tr, err := newSubjectTransform(cfg.SubjectTransform.Source, cfg.SubjectTransform.Destination)
+		tr, err := NewSubjectTransform(cfg.SubjectTransform.Source, cfg.SubjectTransform.Destination)
 		if err != nil {
 			jsa.mu.Unlock()
 			return nil, fmt.Errorf("stream input subject transform not valid %w", err)
@@ -490,7 +490,7 @@ func (a *Account) addStreamWithAssignment(config *StreamConfig, fsConfig *FileSt
 
 	// Check for RePublish.
 	if cfg.RePublish != nil {
-		tr, err := newSubjectTransform(cfg.RePublish.Source, cfg.RePublish.Destination)
+		tr, err := NewSubjectTransform(cfg.RePublish.Source, cfg.RePublish.Destination)
 		if err != nil {
 			jsa.mu.Unlock()
 			return nil, fmt.Errorf("stream republish transform not valid %w", err)
@@ -1280,7 +1280,7 @@ func (s *Server) checkStreamCfg(config *StreamConfig, acc *Account) (StreamConfi
 		if formsCycle {
 			return StreamConfig{}, NewJSStreamInvalidConfigError(fmt.Errorf("stream configuration for republish destination forms a cycle"))
 		}
-		if _, err := newSubjectTransform(cfg.RePublish.Source, cfg.RePublish.Destination); err != nil {
+		if _, err := NewSubjectTransform(cfg.RePublish.Source, cfg.RePublish.Destination); err != nil {
 			return StreamConfig{}, NewJSStreamInvalidConfigError(fmt.Errorf("stream configuration for republish not valid"))
 		}
 	}
@@ -1511,7 +1511,7 @@ func (mset *stream) updateWithAdvisory(config *StreamConfig, sendAdvisory bool)
 					// Check for transform.
 					if s.SubjectTransformDest != _EMPTY_ {
 						var err error
-						if si.tr, err = newSubjectTransform(s.FilterSubject, s.SubjectTransformDest); err != nil {
+						if si.tr, err = NewSubjectTransform(s.FilterSubject, s.SubjectTransformDest); err != nil {
 							return err
 						}
 					}
@@ -1568,7 +1568,7 @@ func (mset *stream) updateWithAdvisory(config *StreamConfig, sendAdvisory bool)
 		if cfg.RePublish.Source == _EMPTY_ {
 			cfg.RePublish.Source = fwcs
 		}
-		tr, err := newSubjectTransform(cfg.RePublish.Source, cfg.RePublish.Destination)
+		tr, err := NewSubjectTransform(cfg.RePublish.Source, cfg.RePublish.Destination)
 		if err != nil {
 			jsa.mu.Unlock()
 			return fmt.Errorf("stream configuration for republish not valid")
@@ -2868,7 +2868,7 @@ func (mset *stream) startingSequenceForSources() {
 		si := &sourceInfo{name: ssi.Name, iname: ssi.iname, sf: ssi.FilterSubject}
 		// Check for transform.
 		if ssi.SubjectTransformDest != _EMPTY_ {
-			si.tr, _ = newSubjectTransform(ssi.FilterSubject, ssi.SubjectTransformDest) // can not return an error because validated in AddStream
+			si.tr, _ = NewSubjectTransform(ssi.FilterSubject, ssi.SubjectTransformDest) // can not return an error because validated in AddStream
 		}
 
 		mset.sources[ssi.iname] = si
diff --git a/server/subject_transform.go b/server/subject_transform.go
index 2dd553c4..a8c20d1e 100644
--- a/server/subject_transform.go
+++ b/server/subject_transform.go
@@ -56,17 +56,17 @@ type subjectTransform struct {
 	dtokmfstringargs     []string // destination token mapping function string arguments
 }
 
-// SubjectTransform transforms subjects using mappings
+// SubjectTransformer transforms subjects using mappings
 //
 // This API is not part of the public API and not subject to SemVer protections
-type SubjectTransform interface {
+type SubjectTransformer interface {
 	// TODO(dlc) - We could add in client here to allow for things like foo -> foo.$ACCOUNT
 	Match(string) (string, error)
 	TransformSubject(subject string) string
 	TransformTokenizedSubject(tokens []string) string
 }
 
-func newSubjectTransform(src, dest string) (*subjectTransform, error) {
+func NewSubjectTransform(src, dest string) (*subjectTransform, error) {
 	// No source given is equivalent to the source being ">"
 	if src == _EMPTY_ {
 		src = fwcs
@@ -493,7 +493,7 @@ func (tr *subjectTransform) TransformTokenizedSubject(tokens []string) string {
 // Reverse a subjectTransform.
 func (tr *subjectTransform) reverse() *subjectTransform {
 	if len(tr.dtokmftokindexesargs) == 0 {
-		rtr, _ := newSubjectTransform(tr.dest, tr.src)
+		rtr, _ := NewSubjectTransform(tr.dest, tr.src)
 		return rtr
 	}
 	// If we are here we need to dynamically get the correct reverse
@@ -513,6 +513,6 @@ func (tr *subjectTransform) reverse() *subjectTransform {
 		}
 	}
 	ndest := strings.Join(nda, tsep)
-	rtr, _ := newSubjectTransform(nsrc, ndest)
+	rtr, _ := NewSubjectTransform(nsrc, ndest)
 	return rtr
 }


Test patch:
diff --git a/server/subject_transform_test.go b/server/subject_transform_test.go
index 8ac9b6ca..3cb7a0ad 100644
--- a/server/subject_transform_test.go
+++ b/server/subject_transform_test.go
@@ -76,7 +76,7 @@ func TestPlaceHolderIndex(t *testing.T) {
 func TestSubjectTransforms(t *testing.T) {
 	shouldErr := func(src, dest string) {
 		t.Helper()
-		if _, err := newSubjectTransform(src, dest); err != ErrBadSubject && !errors.Is(err, ErrInvalidMappingDestination) {
+		if _, err := NewSubjectTransform(src, dest); err != ErrBadSubject && !errors.Is(err, ErrInvalidMappingDestination) {
 			t.Fatalf("Did not get an error for src=%q and dest=%q", src, dest)
 		}
 	}
@@ -107,7 +107,7 @@ func TestSubjectTransforms(t *testing.T) {
 
 	shouldBeOK := func(src, dest string) *subjectTransform {
 		t.Helper()
-		tr, err := newSubjectTransform(src, dest)
+		tr, err := NewSubjectTransform(src, dest)
 		if err != nil {
 			t.Fatalf("Got an error %v for src=%q and dest=%q", err, src, dest)
 		}