Skip to content

Commit 46e722c

Browse files
authoredSep 28, 2023
Merge pull request #375 from theBeginner86/theBeginner86/chore/1
[chore] Improve MeshModels models retrieval
2 parents ddc03e0 + f6ed5a4 commit 46e722c

File tree

7 files changed

+121
-25
lines changed

7 files changed

+121
-25
lines changed
 

‎models/meshmodel/core/types/types.go

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const (
66
ComponentDefinition CapabilityType = "component"
77
PolicyDefinition CapabilityType = "policy"
88
RelationshipDefinition CapabilityType = "relationship"
9+
Model CapabilityType = "model"
910
)
1011

1112
// Each entity will have it's own Filter implementation via which it exposes the nobs and dials to fetch entities

‎models/meshmodel/core/v1alpha1/component.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -69,19 +69,20 @@ func emptySchemaCheck(schema string) (valid bool) {
6969
valid = true
7070
return
7171
}
72-
func CreateComponent(db *database.Handler, c ComponentDefinition) (uuid.UUID, error) {
72+
func CreateComponent(db *database.Handler, c ComponentDefinition) (uuid.UUID, uuid.UUID, error) {
7373
c.ID = uuid.New()
7474
mid, err := CreateModel(db, c.Model)
7575
if err != nil {
76-
return uuid.UUID{}, err
76+
return uuid.UUID{}, uuid.UUID{}, err
7777
}
78+
7879
if !emptySchemaCheck(c.Schema) {
7980
c.Metadata["hasInvalidSchema"] = true
8081
}
8182
cdb := c.GetComponentDefinitionDB()
8283
cdb.ModelID = mid
8384
err = db.Create(&cdb).Error
84-
return c.ID, err
85+
return c.ID, mid, err
8586
}
8687
func GetMeshModelComponents(db *database.Handler, f ComponentFilter) (c []ComponentDefinition, count int64, unique int) {
8788
type componentDefinitionWithModel struct {

‎models/meshmodel/core/v1alpha1/models.go

+8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
"github.com/google/uuid"
99
"github.com/layer5io/meshkit/database"
10+
"github.com/layer5io/meshkit/models/meshmodel/core/types"
1011
"gorm.io/gorm"
1112
)
1213

@@ -53,6 +54,13 @@ type ModelDB struct {
5354
Metadata []byte `json:"modelMetadata" gorm:"modelMetadata"`
5455
}
5556

57+
func (m Model) Type() types.CapabilityType {
58+
return types.Model
59+
}
60+
func (m Model) GetID() uuid.UUID {
61+
return m.ID
62+
}
63+
5664
func CreateModel(db *database.Handler, cmodel Model) (uuid.UUID, error) {
5765
byt, err := json.Marshal(cmodel)
5866
if err != nil {

‎models/meshmodel/core/v1alpha1/policy.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -96,19 +96,19 @@ func (pdb *PolicyDefinitionDB) GetPolicyDefinition(m Model) (p PolicyDefinition)
9696
return
9797
}
9898

99-
func CreatePolicy(db *database.Handler, p PolicyDefinition) (uuid.UUID, error) {
99+
func CreatePolicy(db *database.Handler, p PolicyDefinition) (uuid.UUID, uuid.UUID, error) {
100100
p.ID = uuid.New()
101101
mid, err := CreateModel(db, p.Model)
102102
if err != nil {
103-
return uuid.UUID{}, err
103+
return uuid.UUID{}, uuid.UUID{}, err
104104
}
105105
pdb := p.GetPolicyDefinitionDB()
106106
pdb.ModelID = mid
107107
err = db.Create(&pdb).Error
108108
if err != nil {
109-
return uuid.UUID{}, err
109+
return uuid.UUID{}, uuid.UUID{}, err
110110
}
111-
return pdb.ID, nil
111+
return pdb.ID, mid, nil
112112
}
113113

114114
func (p *PolicyDefinition) GetPolicyDefinitionDB() (pdb PolicyDefinitionDB) {

‎models/meshmodel/core/v1alpha1/relationship.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -137,19 +137,19 @@ func (r RelationshipDefinition) GetID() uuid.UUID {
137137
return r.ID
138138
}
139139

140-
func CreateRelationship(db *database.Handler, r RelationshipDefinition) (uuid.UUID, error) {
140+
func CreateRelationship(db *database.Handler, r RelationshipDefinition) (uuid.UUID, uuid.UUID, error) {
141141
r.ID = uuid.New()
142142
mid, err := CreateModel(db, r.Model)
143143
if err != nil {
144-
return uuid.UUID{}, err
144+
return uuid.UUID{}, uuid.UUID{}, err
145145
}
146146
rdb := r.GetRelationshipDefinitionDB()
147147
rdb.ModelID = mid
148148
err = db.Create(&rdb).Error
149149
if err != nil {
150-
return uuid.UUID{}, err
150+
return uuid.UUID{}, uuid.UUID{}, err
151151
}
152-
return r.ID, err
152+
return r.ID, mid, err
153153
}
154154

155155
func (r *RelationshipDefinition) GetRelationshipDefinitionDB() (rdb RelationshipDefinitionDB) {

‎models/meshmodel/registry/host.go

+31-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package registry
22

33
import (
4-
"errors"
4+
"encoding/json"
55
"fmt"
6+
"sync"
67
"time"
78

89
"github.com/google/uuid"
@@ -12,6 +13,8 @@ import (
1213
"gorm.io/gorm"
1314
)
1415

16+
var hostCreationLock sync.Mutex //Each entity will perform a check and if the host already doesn't exist, it will create a host. This lock will make sure that there are no race conditions.
17+
1518
type Host struct {
1619
ID uuid.UUID `json:"-"`
1720
Hostname string
@@ -23,9 +26,31 @@ type Host struct {
2326
}
2427

2528
func createHost(db *database.Handler, h Host) (uuid.UUID, error) {
26-
h.ID = uuid.New()
27-
err := db.Create(&h).Error
28-
return h.ID, err
29+
byt, err := json.Marshal(h)
30+
if err != nil {
31+
return uuid.UUID{}, err
32+
}
33+
hID := uuid.NewSHA1(uuid.UUID{}, byt)
34+
var host Host
35+
hostCreationLock.Lock()
36+
defer hostCreationLock.Unlock()
37+
err = db.First(&host, "id = ?", hID).Error // check if the host already exists
38+
if err != nil && err != gorm.ErrRecordNotFound {
39+
return uuid.UUID{}, err
40+
}
41+
42+
// if not exists then create a new host and return the id
43+
if err == gorm.ErrRecordNotFound {
44+
h.ID = hID
45+
err = db.Create(&h).Error
46+
if err != nil {
47+
return uuid.UUID{}, err
48+
}
49+
return h.ID, nil
50+
}
51+
52+
// else return the id of the existing host
53+
return host.ID, nil
2954
}
3055

3156
func (h *Host) AfterFind(tx *gorm.DB) error {
@@ -34,8 +59,8 @@ func (h *Host) AfterFind(tx *gorm.DB) error {
3459
h.IHost = ArtifactHub{}
3560
case "kubernetes":
3661
h.IHost = Kubernetes{}
37-
default:
38-
return ErrUnknownHost(errors.New("unable to find compatible host for the component"))
62+
default: // do nothing if the host is not pre-unknown. Currently adapters fall into this case.
63+
return nil
3964
}
4065
return nil
4166
}

‎models/meshmodel/registry/registry.go

+69-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package registry
22

33
import (
4+
"encoding/json"
45
"fmt"
56
"strings"
67
"time"
@@ -11,6 +12,7 @@ import (
1112
"github.com/layer5io/meshkit/models/meshmodel/core/v1alpha1"
1213
"golang.org/x/text/cases"
1314
"golang.org/x/text/language"
15+
"gorm.io/gorm"
1416
"gorm.io/gorm/clause"
1517
)
1618

@@ -47,6 +49,37 @@ type RegistryManager struct {
4749
db *database.Handler //This database handler will be used to perform queries inside the database
4850
}
4951

52+
// Registers models into registries table.
53+
func registerModel(db *database.Handler, regID, modelID uuid.UUID) error {
54+
entity := Registry{
55+
RegistrantID: regID,
56+
Entity: modelID,
57+
Type: types.Model,
58+
}
59+
60+
byt, err := json.Marshal(entity)
61+
if err != nil {
62+
return err
63+
}
64+
65+
entityID := uuid.NewSHA1(uuid.UUID{}, byt)
66+
var reg Registry
67+
err = db.First(&reg, "id = ?", entityID).Error
68+
if err != nil && err != gorm.ErrRecordNotFound {
69+
return err
70+
}
71+
72+
if err == gorm.ErrRecordNotFound {
73+
entity.ID = entityID
74+
err = db.Create(&entity).Error
75+
if err != nil {
76+
return err
77+
}
78+
}
79+
80+
return nil
81+
}
82+
5083
// NewRegistryManager initializes the registry manager by creating appropriate tables.
5184
// Any new entities that are added to the registry should be migrated here into the database
5285
func NewRegistryManager(db *database.Handler) (*RegistryManager, error) {
@@ -86,14 +119,22 @@ func (rm *RegistryManager) RegisterEntity(h Host, en Entity) error {
86119
if entity.Schema == "" { //For components with an empty schema, exit quietly
87120
return nil
88121
}
89-
componentID, err := v1alpha1.CreateComponent(rm.db, entity)
122+
123+
registrantID, err := createHost(rm.db, h)
90124
if err != nil {
91125
return err
92126
}
93-
registrantID, err := createHost(rm.db, h)
127+
128+
componentID, modelID, err := v1alpha1.CreateComponent(rm.db, entity)
94129
if err != nil {
95130
return err
96131
}
132+
133+
err = registerModel(rm.db, registrantID, modelID)
134+
if err != nil {
135+
return err
136+
}
137+
97138
entry := Registry{
98139
ID: uuid.New(),
99140
RegistrantID: registrantID,
@@ -104,14 +145,22 @@ func (rm *RegistryManager) RegisterEntity(h Host, en Entity) error {
104145
}
105146
return rm.db.Create(&entry).Error
106147
case v1alpha1.RelationshipDefinition:
107-
relationshipID, err := v1alpha1.CreateRelationship(rm.db, entity)
148+
149+
registrantID, err := createHost(rm.db, h)
108150
if err != nil {
109151
return err
110152
}
111-
registrantID, err := createHost(rm.db, h)
153+
154+
relationshipID, modelID, err := v1alpha1.CreateRelationship(rm.db, entity)
155+
if err != nil {
156+
return err
157+
}
158+
159+
err = registerModel(rm.db, registrantID, modelID)
112160
if err != nil {
113161
return err
114162
}
163+
115164
entry := Registry{
116165
ID: uuid.New(),
117166
RegistrantID: registrantID,
@@ -123,14 +172,21 @@ func (rm *RegistryManager) RegisterEntity(h Host, en Entity) error {
123172
return rm.db.Create(&entry).Error
124173
//Add logic for Policies and other entities below
125174
case v1alpha1.PolicyDefinition:
126-
policyID, err := v1alpha1.CreatePolicy(rm.db, entity)
175+
registrantID, err := createHost(rm.db, h)
127176
if err != nil {
128177
return err
129178
}
130-
registrantID, err := createHost(rm.db, h)
179+
180+
policyID, modelID, err := v1alpha1.CreatePolicy(rm.db, entity)
131181
if err != nil {
132182
return err
133183
}
184+
185+
err = registerModel(rm.db, registrantID, modelID)
186+
if err != nil {
187+
return err
188+
}
189+
134190
entry := Registry{
135191
ID: uuid.New(),
136192
RegistrantID: registrantID,
@@ -194,7 +250,7 @@ func (rm *RegistryManager) GetModels(db *database.Handler, f types.Filter) ([]v1
194250
var modelWithCategoriess []modelWithCategories
195251
finder := db.Model(&v1alpha1.ModelDB{}).
196252
Select("model_dbs.*, category_dbs.*").
197-
Joins("JOIN category_dbs ON model_dbs.category_id = category_dbs.id") //
253+
Joins("JOIN category_dbs ON model_dbs.category_id = category_dbs.id")
198254

199255
// total count before pagination
200256
var count int64
@@ -247,7 +303,12 @@ func (rm *RegistryManager) GetModels(db *database.Handler, f types.Filter) ([]v1
247303
}
248304

249305
for _, modelDB := range modelWithCategoriess {
250-
m = append(m, modelDB.ModelDB.GetModel(modelDB.GetCategory(db)))
306+
model := modelDB.ModelDB.GetModel(modelDB.GetCategory(db))
307+
host := rm.GetRegistrant(model)
308+
model.HostID = host.ID
309+
model.HostName = host.Hostname
310+
model.DisplayHostName = host.Hostname
311+
m = append(m, model)
251312
}
252313
return m, count, countUniqueModels(modelWithCategoriess)
253314
}

0 commit comments

Comments
 (0)
Please sign in to comment.