diff --git a/datamodel/low/base/schema_proxy.go b/datamodel/low/base/schema_proxy.go index 66290012..4c2614f6 100644 --- a/datamodel/low/base/schema_proxy.go +++ b/datamodel/low/base/schema_proxy.go @@ -333,6 +333,9 @@ func (sp *SchemaProxy) computeHash() uint64 { if !sp.IsReference() { return sch.Hash() } + if cfg := sp.getSpecConfig(); cfg != nil && cfg.UseSchemaQuickHash && !CheckSchemaProxyForCircularRefs(sp) { + return sch.QuickHash() + } return sp.hashReference() } diff --git a/datamodel/low/base/schema_proxy_test.go b/datamodel/low/base/schema_proxy_test.go index 99958f54..ffecbeb9 100644 --- a/datamodel/low/base/schema_proxy_test.go +++ b/datamodel/low/base/schema_proxy_test.go @@ -968,6 +968,22 @@ func TestSchemaProxy_QuickHash_BuildsOnMiss(t *testing.T) { assert.Equal(t, built.quickHashKey(), quickHashKeyOf(sp.idx, sp.idx, sp.vn)) } +func TestSchemaProxyQuickHashIndependentOfModelAccess(t *testing.T) { + ClearSchemaQuickHashMap() + defer ClearSchemaQuickHashMap() + for _, spec := range []string{"type: string\n", "type: integer\n"} { + cold := quickHashRefProxy(t, spec, &index.SpecIndexConfig{}) + warm := quickHashRefProxy(t, spec, &index.SpecIndexConfig{}) + require.NotNil(t, warm.Schema()) + assert.Equal(t, cold.Hash(), warm.Hash()) + } + left := quickHashRefProxy(t, "type: string\n", &index.SpecIndexConfig{}) + right := quickHashRefProxy(t, "type: integer\n", &index.SpecIndexConfig{}) + require.NotNil(t, left.Schema()) + require.NotNil(t, right.Schema()) + assert.NotEqual(t, left.Hash(), right.Hash()) +} + func TestSchemaProxy_CachedQuickHash_Declines(t *testing.T) { ClearSchemaQuickHashMap() defer ClearSchemaQuickHashMap() diff --git a/datamodel/spec_info.go b/datamodel/spec_info.go index 2b86d7d2..1a8a569b 100644 --- a/datamodel/spec_info.go +++ b/datamodel/spec_info.go @@ -365,8 +365,8 @@ func extractSpecInfoInternal(spec []byte, bypass bool, skipJSON bool) (*SpecInfo } parsed = true - // so far there is only 2 as a major release of AsyncAPI - if majorVersion > 2 { + // Detect supported AsyncAPI versions; model construction belongs to libasyncapi. + if majorVersion > 3 { if !bypass { specInfo.Error = errors.New("spec is defined as asyncapi, but has a major version that is invalid") return specInfo, specInfo.Error diff --git a/datamodel/spec_info_asyncapi3_test.go b/datamodel/spec_info_asyncapi3_test.go new file mode 100644 index 00000000..d7b93576 --- /dev/null +++ b/datamodel/spec_info_asyncapi3_test.go @@ -0,0 +1,18 @@ +package datamodel + +import ( + "github.com/pb33f/testify/require" + "testing" +) + +func TestExtractSpecInfoAsyncAPI3(t *testing.T) { + for _, spec := range []string{"asyncapi: 3.0.0\ninfo: {title: Events, version: 1.0.0}\n", `{"asyncapi":"3.0.0","info":{"title":"Events","version":"1.0.0"}}`} { + info, err := ExtractSpecInfo([]byte(spec)) + require.NoError(t, err) + require.Equal(t, "asyncapi", info.SpecType) + require.Equal(t, "3.0.0", info.Version) + require.NotNil(t, info.RootNode) + } + _, err := ExtractSpecInfo([]byte("asyncapi: 3.0.0\nasyncapi: 3.0.0\n")) + require.Error(t, err) +} diff --git a/datamodel/spec_info_test.go b/datamodel/spec_info_test.go index f4a613c3..9d781968 100644 --- a/datamodel/spec_info_test.go +++ b/datamodel/spec_info_test.go @@ -196,7 +196,7 @@ channels: type: string pattern: '^hello .+$'` -var AsyncAPISpecOdd = `asyncapi: 3.0.0 +var AsyncAPISpecOdd = `asyncapi: 4.0.0 info: title: Hello world application version: '0.1.0'`