Skip to content

Commit

Permalink
Merge pull request #375 from theBeginner86/theBeginner86/chore/1
Browse files Browse the repository at this point in the history
[chore] Improve MeshModels models retrieval
  • Loading branch information
theBeginner86 authored Sep 28, 2023
2 parents ddc03e0 + f6ed5a4 commit 46e722c
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 25 deletions.
1 change: 1 addition & 0 deletions models/meshmodel/core/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const (
ComponentDefinition CapabilityType = "component"
PolicyDefinition CapabilityType = "policy"
RelationshipDefinition CapabilityType = "relationship"
Model CapabilityType = "model"
)

// Each entity will have it's own Filter implementation via which it exposes the nobs and dials to fetch entities
Expand Down
7 changes: 4 additions & 3 deletions models/meshmodel/core/v1alpha1/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,19 +69,20 @@ func emptySchemaCheck(schema string) (valid bool) {
valid = true
return
}
func CreateComponent(db *database.Handler, c ComponentDefinition) (uuid.UUID, error) {
func CreateComponent(db *database.Handler, c ComponentDefinition) (uuid.UUID, uuid.UUID, error) {
c.ID = uuid.New()
mid, err := CreateModel(db, c.Model)
if err != nil {
return uuid.UUID{}, err
return uuid.UUID{}, uuid.UUID{}, err
}

if !emptySchemaCheck(c.Schema) {
c.Metadata["hasInvalidSchema"] = true
}
cdb := c.GetComponentDefinitionDB()
cdb.ModelID = mid
err = db.Create(&cdb).Error
return c.ID, err
return c.ID, mid, err
}
func GetMeshModelComponents(db *database.Handler, f ComponentFilter) (c []ComponentDefinition, count int64, unique int) {
type componentDefinitionWithModel struct {
Expand Down
8 changes: 8 additions & 0 deletions models/meshmodel/core/v1alpha1/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/google/uuid"
"github.com/layer5io/meshkit/database"
"github.com/layer5io/meshkit/models/meshmodel/core/types"
"gorm.io/gorm"
)

Expand Down Expand Up @@ -53,6 +54,13 @@ type ModelDB struct {
Metadata []byte `json:"modelMetadata" gorm:"modelMetadata"`
}

func (m Model) Type() types.CapabilityType {
return types.Model
}
func (m Model) GetID() uuid.UUID {
return m.ID
}

func CreateModel(db *database.Handler, cmodel Model) (uuid.UUID, error) {
byt, err := json.Marshal(cmodel)
if err != nil {
Expand Down
8 changes: 4 additions & 4 deletions models/meshmodel/core/v1alpha1/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,19 +96,19 @@ func (pdb *PolicyDefinitionDB) GetPolicyDefinition(m Model) (p PolicyDefinition)
return
}

func CreatePolicy(db *database.Handler, p PolicyDefinition) (uuid.UUID, error) {
func CreatePolicy(db *database.Handler, p PolicyDefinition) (uuid.UUID, uuid.UUID, error) {
p.ID = uuid.New()
mid, err := CreateModel(db, p.Model)
if err != nil {
return uuid.UUID{}, err
return uuid.UUID{}, uuid.UUID{}, err
}
pdb := p.GetPolicyDefinitionDB()
pdb.ModelID = mid
err = db.Create(&pdb).Error
if err != nil {
return uuid.UUID{}, err
return uuid.UUID{}, uuid.UUID{}, err
}
return pdb.ID, nil
return pdb.ID, mid, nil
}

func (p *PolicyDefinition) GetPolicyDefinitionDB() (pdb PolicyDefinitionDB) {
Expand Down
8 changes: 4 additions & 4 deletions models/meshmodel/core/v1alpha1/relationship.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,19 +137,19 @@ func (r RelationshipDefinition) GetID() uuid.UUID {
return r.ID
}

func CreateRelationship(db *database.Handler, r RelationshipDefinition) (uuid.UUID, error) {
func CreateRelationship(db *database.Handler, r RelationshipDefinition) (uuid.UUID, uuid.UUID, error) {
r.ID = uuid.New()
mid, err := CreateModel(db, r.Model)
if err != nil {
return uuid.UUID{}, err
return uuid.UUID{}, uuid.UUID{}, err
}
rdb := r.GetRelationshipDefinitionDB()
rdb.ModelID = mid
err = db.Create(&rdb).Error
if err != nil {
return uuid.UUID{}, err
return uuid.UUID{}, uuid.UUID{}, err
}
return r.ID, err
return r.ID, mid, err
}

func (r *RelationshipDefinition) GetRelationshipDefinitionDB() (rdb RelationshipDefinitionDB) {
Expand Down
37 changes: 31 additions & 6 deletions models/meshmodel/registry/host.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package registry

import (
"errors"
"encoding/json"
"fmt"
"sync"
"time"

"github.com/google/uuid"
Expand All @@ -12,6 +13,8 @@ import (
"gorm.io/gorm"
)

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.

type Host struct {
ID uuid.UUID `json:"-"`
Hostname string
Expand All @@ -23,9 +26,31 @@ type Host struct {
}

func createHost(db *database.Handler, h Host) (uuid.UUID, error) {
h.ID = uuid.New()
err := db.Create(&h).Error
return h.ID, err
byt, err := json.Marshal(h)
if err != nil {
return uuid.UUID{}, err
}
hID := uuid.NewSHA1(uuid.UUID{}, byt)
var host Host
hostCreationLock.Lock()
defer hostCreationLock.Unlock()
err = db.First(&host, "id = ?", hID).Error // check if the host already exists
if err != nil && err != gorm.ErrRecordNotFound {
return uuid.UUID{}, err
}

// if not exists then create a new host and return the id
if err == gorm.ErrRecordNotFound {
h.ID = hID
err = db.Create(&h).Error
if err != nil {
return uuid.UUID{}, err
}
return h.ID, nil
}

// else return the id of the existing host
return host.ID, nil
}

func (h *Host) AfterFind(tx *gorm.DB) error {
Expand All @@ -34,8 +59,8 @@ func (h *Host) AfterFind(tx *gorm.DB) error {
h.IHost = ArtifactHub{}
case "kubernetes":
h.IHost = Kubernetes{}
default:
return ErrUnknownHost(errors.New("unable to find compatible host for the component"))
default: // do nothing if the host is not pre-unknown. Currently adapters fall into this case.
return nil
}
return nil
}
Expand Down
77 changes: 69 additions & 8 deletions models/meshmodel/registry/registry.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package registry

import (
"encoding/json"
"fmt"
"strings"
"time"
Expand All @@ -11,6 +12,7 @@ import (
"github.com/layer5io/meshkit/models/meshmodel/core/v1alpha1"
"golang.org/x/text/cases"
"golang.org/x/text/language"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)

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

// Registers models into registries table.
func registerModel(db *database.Handler, regID, modelID uuid.UUID) error {
entity := Registry{
RegistrantID: regID,
Entity: modelID,
Type: types.Model,
}

byt, err := json.Marshal(entity)
if err != nil {
return err
}

entityID := uuid.NewSHA1(uuid.UUID{}, byt)
var reg Registry
err = db.First(&reg, "id = ?", entityID).Error
if err != nil && err != gorm.ErrRecordNotFound {
return err
}

if err == gorm.ErrRecordNotFound {
entity.ID = entityID
err = db.Create(&entity).Error
if err != nil {
return err
}
}

return nil
}

// NewRegistryManager initializes the registry manager by creating appropriate tables.
// Any new entities that are added to the registry should be migrated here into the database
func NewRegistryManager(db *database.Handler) (*RegistryManager, error) {
Expand Down Expand Up @@ -86,14 +119,22 @@ func (rm *RegistryManager) RegisterEntity(h Host, en Entity) error {
if entity.Schema == "" { //For components with an empty schema, exit quietly
return nil
}
componentID, err := v1alpha1.CreateComponent(rm.db, entity)

registrantID, err := createHost(rm.db, h)
if err != nil {
return err
}
registrantID, err := createHost(rm.db, h)

componentID, modelID, err := v1alpha1.CreateComponent(rm.db, entity)
if err != nil {
return err
}

err = registerModel(rm.db, registrantID, modelID)
if err != nil {
return err
}

entry := Registry{
ID: uuid.New(),
RegistrantID: registrantID,
Expand All @@ -104,14 +145,22 @@ func (rm *RegistryManager) RegisterEntity(h Host, en Entity) error {
}
return rm.db.Create(&entry).Error
case v1alpha1.RelationshipDefinition:
relationshipID, err := v1alpha1.CreateRelationship(rm.db, entity)

registrantID, err := createHost(rm.db, h)
if err != nil {
return err
}
registrantID, err := createHost(rm.db, h)

relationshipID, modelID, err := v1alpha1.CreateRelationship(rm.db, entity)
if err != nil {
return err
}

err = registerModel(rm.db, registrantID, modelID)
if err != nil {
return err
}

entry := Registry{
ID: uuid.New(),
RegistrantID: registrantID,
Expand All @@ -123,14 +172,21 @@ func (rm *RegistryManager) RegisterEntity(h Host, en Entity) error {
return rm.db.Create(&entry).Error
//Add logic for Policies and other entities below
case v1alpha1.PolicyDefinition:
policyID, err := v1alpha1.CreatePolicy(rm.db, entity)
registrantID, err := createHost(rm.db, h)
if err != nil {
return err
}
registrantID, err := createHost(rm.db, h)

policyID, modelID, err := v1alpha1.CreatePolicy(rm.db, entity)
if err != nil {
return err
}

err = registerModel(rm.db, registrantID, modelID)
if err != nil {
return err
}

entry := Registry{
ID: uuid.New(),
RegistrantID: registrantID,
Expand Down Expand Up @@ -194,7 +250,7 @@ func (rm *RegistryManager) GetModels(db *database.Handler, f types.Filter) ([]v1
var modelWithCategoriess []modelWithCategories
finder := db.Model(&v1alpha1.ModelDB{}).
Select("model_dbs.*, category_dbs.*").
Joins("JOIN category_dbs ON model_dbs.category_id = category_dbs.id") //
Joins("JOIN category_dbs ON model_dbs.category_id = category_dbs.id")

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

for _, modelDB := range modelWithCategoriess {
m = append(m, modelDB.ModelDB.GetModel(modelDB.GetCategory(db)))
model := modelDB.ModelDB.GetModel(modelDB.GetCategory(db))
host := rm.GetRegistrant(model)
model.HostID = host.ID
model.HostName = host.Hostname
model.DisplayHostName = host.Hostname
m = append(m, model)
}
return m, count, countUniqueModels(modelWithCategoriess)
}
Expand Down

0 comments on commit 46e722c

Please sign in to comment.