diff --git a/opengin/core-api/cmd/server/service.go b/opengin/core-api/cmd/server/service.go index b0cd1cbd..91215d85 100644 --- a/opengin/core-api/cmd/server/service.go +++ b/opengin/core-api/cmd/server/service.go @@ -27,9 +27,10 @@ import ( // Server implements the COREService type Server struct { pb.UnimplementedCOREServiceServer - mongoRepo *mongorepository.MongoRepository - neo4jRepo *neo4jrepository.Neo4jRepository - postgresRepo *postgres.PostgresRepository + mongoRepo *mongorepository.MongoRepository + neo4jRepo *neo4jrepository.Neo4jRepository + postgresRepo *postgres.PostgresRepository + attributeProcessor *engine.EntityAttributeProcessor } // CreateEntity handles entity creation with relationships, metadata and attributes @@ -66,8 +67,7 @@ func (s *Server) CreateEntity(ctx context.Context, req *pb.Entity) (*pb.Entity, } // Handle attributes - processor := engine.NewEntityAttributeProcessor() - attributeResults := processor.ProcessEntityAttributes(ctx, req, "create", nil) + attributeResults := s.attributeProcessor.ProcessEntityAttributes(ctx, req, "create", nil) // Check if any attributes failed for attrName, result := range attributeResults { @@ -172,9 +172,6 @@ func (s *Server) ReadEntity(ctx context.Context, req *pb.ReadEntityRequest) (*pb log.Printf("[server.ReadEntity] Processing attributes for entity: %s, attributes: %+v", req.Entity.Id, req.Entity.Attributes) - // Use the EntityAttributeProcessor to read and process attributes - processor := engine.NewEntityAttributeProcessor() - // Extract fields and record filters from the request attributes based on storage type fields, recordFilters := extractFieldsFromAttributes(req.Entity.Attributes) log.Printf("Extracted fields from attributes: %v", fields) @@ -188,7 +185,7 @@ func (s *Server) ReadEntity(ctx context.Context, req *pb.ReadEntityRequest) (*pb readOptions := engine.NewReadOptions(filtersMap, fields...) // Process the entity with attributes to get the results map - attributeResults := processor.ProcessEntityAttributes(ctx, req.Entity, "read", readOptions) + attributeResults := s.attributeProcessor.ProcessEntityAttributes(ctx, req.Entity, "read", readOptions) log.Printf("[server.ReadEntity] Successfully processed attributes for entity: %s, results: %+v", req.Entity.Id, attributeResults) @@ -263,12 +260,11 @@ func (s *Server) UpdateEntity(ctx context.Context, req *pb.UpdateEntityRequest) } // Handle attributes - processor := engine.NewEntityAttributeProcessor() // Note that in the perspective of the attribute this is a creation operation // The entity is already there but here the attribute is set later. // There is no alignment of update operation with the attribute. // TODO: https://github.com/LDFLK/nexoan/issues/286 - attributeResults := processor.ProcessEntityAttributes(ctx, req.Entity, "create", nil) + attributeResults := s.attributeProcessor.ProcessEntityAttributes(ctx, req.Entity, "create", nil) // Check if any attributes failed for attrName, result := range attributeResults { @@ -620,6 +616,15 @@ func main() { } defer postgresRepo.Close() + attributeProcessor, err := engine.NewEntityAttributeProcessor(engine.ProcessorDependencies{ + PostgresRepo: postgresRepo, + Neo4jRepo: neo4jRepo, + MongoRepo: mongoRepo, + }) + if err != nil { + log.Fatalf("[service.main] Failed to create attribute processor: %v", err) + } + listener, err := net.Listen("tcp", host+":"+port) if err != nil { log.Fatalf("[service.main] Failed to listen: %v", err) @@ -627,9 +632,10 @@ func main() { grpcServer := grpc.NewServer() server := &Server{ - mongoRepo: mongoRepo, - neo4jRepo: neo4jRepo, - postgresRepo: postgresRepo, + mongoRepo: mongoRepo, + neo4jRepo: neo4jRepo, + postgresRepo: postgresRepo, + attributeProcessor: attributeProcessor, } pb.RegisterCOREServiceServer(grpcServer, server) diff --git a/opengin/core-api/commons/db/utils.go b/opengin/core-api/commons/db/utils.go index 3cb0815f..1c2219c1 100644 --- a/opengin/core-api/commons/db/utils.go +++ b/opengin/core-api/commons/db/utils.go @@ -32,7 +32,8 @@ func GetMongoConfig() *config.MongoConfig { } } -// GetNeo4jRepository retrieves a Neo4j repository +// GetNeo4jRepository retrieves a Neo4j repository. +// Prefer using the long-lived server-injected repository in request paths to avoid creating new clients per operation. func GetNeo4jRepository(ctx context.Context) (*neo4jrepository.Neo4jRepository, error) { cfg := GetNeo4jConfig() repo, err := neo4jrepository.NewNeo4jRepository(ctx, cfg) @@ -42,7 +43,8 @@ func GetNeo4jRepository(ctx context.Context) (*neo4jrepository.Neo4jRepository, return repo, nil } -// GetMongoRepository retrieves a Mongo repository +// GetMongoRepository retrieves a Mongo repository. +// Prefer using the long-lived server-injected repository in request paths to avoid creating new clients per operation. // TODO: Handle errors better func GetMongoRepository(ctx context.Context) *mongorepository.MongoRepository { cfg := GetMongoConfig() @@ -61,7 +63,8 @@ func GetPostgresConfig() postgresrepository.Config { } } -// GetPostgresRepository retrieves a Postgres repository +// GetPostgresRepository retrieves a Postgres repository. +// Prefer using the long-lived server-injected repository in request paths to avoid creating new pools per operation. func GetPostgresRepository(ctx context.Context) (*postgresrepository.PostgresRepository, error) { cfg := GetPostgresConfig() repo, err := postgresrepository.NewPostgresRepository(cfg) diff --git a/opengin/core-api/engine/attribute_resolver.go b/opengin/core-api/engine/attribute_resolver.go index 988c6894..457b8985 100644 --- a/opengin/core-api/engine/attribute_resolver.go +++ b/opengin/core-api/engine/attribute_resolver.go @@ -6,7 +6,9 @@ package engine import ( "context" "fmt" - dbcommons "lk/datafoundation/core-api/commons/db" + mongorepository "lk/datafoundation/core-api/db/repository/mongo" + neo4jrepository "lk/datafoundation/core-api/db/repository/neo4j" + postgresrepository "lk/datafoundation/core-api/db/repository/postgres" pb "lk/datafoundation/core-api/lk/datafoundation/core-api" schema "lk/datafoundation/core-api/pkg/schema" storageinference "lk/datafoundation/core-api/pkg/storageinference" @@ -54,16 +56,35 @@ type EntityAttributeProcessor struct { graphManager *GraphMetadataManager } -// NewEntityAttributeProcessor creates a new processor with all resolvers initialized -func NewEntityAttributeProcessor() *EntityAttributeProcessor { +// ProcessorDependencies contains database repositories used by the attribute processor. +type ProcessorDependencies struct { + PostgresRepo *postgresrepository.PostgresRepository + Neo4jRepo *neo4jrepository.Neo4jRepository + MongoRepo *mongorepository.MongoRepository +} + +// NewEntityAttributeProcessor creates a processor with explicit repository dependencies. +func NewEntityAttributeProcessor(deps ProcessorDependencies) (*EntityAttributeProcessor, error) { + if deps.PostgresRepo == nil { + return nil, fmt.Errorf("postgres repository is required") + } + if deps.Neo4jRepo == nil { + return nil, fmt.Errorf("neo4j repository is required") + } + if deps.MongoRepo == nil { + return nil, fmt.Errorf("mongo repository is required") + } + processor := &EntityAttributeProcessor{ resolvers: make(map[storageinference.StorageType]AttributeResolver), - graphManager: NewGraphMetadataManager(), + graphManager: NewGraphMetadataManager(deps.Neo4jRepo, deps.MongoRepo), } // Initialize all resolvers processor.resolvers[storageinference.GraphData] = &GraphAttributeResolver{} - processor.resolvers[storageinference.TabularData] = &TabularAttributeResolver{} + processor.resolvers[storageinference.TabularData] = &TabularAttributeResolver{ + repo: deps.PostgresRepo, + } processor.resolvers[storageinference.MapData] = &DocumentAttributeResolver{} // Initialize each resolver @@ -73,7 +94,7 @@ func NewEntityAttributeProcessor() *EntityAttributeProcessor { } } - return processor + return processor, nil } // GetResolver returns the resolver for a specific storage type @@ -445,6 +466,7 @@ func (r *GraphAttributeResolver) DeleteResolve(ctx context.Context, entityID, at // TabularAttributeResolver handles tabular data structures with columns and rows type TabularAttributeResolver struct { BaseAttributeResolver + repo *postgresrepository.PostgresRepository } func (r *TabularAttributeResolver) CreateResolve(ctx context.Context, entityID, attrName string, value *pb.TimeBasedValue) *Result { @@ -465,17 +487,16 @@ func (r *TabularAttributeResolver) CreateResolve(ctx context.Context, entityID, fmt.Printf("Creating tabular attribute %s for entity %s (validated as tabular) from %v to %v\n", attrName, entityID, startDate, endDate) - repo, err := dbcommons.GetPostgresRepository(ctx) - if err != nil { + if r.repo == nil { return &Result{ Data: nil, Success: false, - Error: fmt.Errorf("failed to get Postgres repository: %v", err), + Error: fmt.Errorf("postgres repository is not configured"), } } // Initialize database tables if they don't exist - if err := repo.InitializeTables(ctx); err != nil { + if err := r.repo.InitializeTables(ctx); err != nil { return &Result{ Data: nil, Success: false, @@ -492,7 +513,7 @@ func (r *TabularAttributeResolver) CreateResolve(ctx context.Context, entityID, } } - err = repo.HandleTabularData(ctx, entityID, attrName, value, schemaInfo) + err = r.repo.HandleTabularData(ctx, entityID, attrName, value, schemaInfo) if err != nil { return &Result{ Data: nil, @@ -515,19 +536,18 @@ func (r *TabularAttributeResolver) ReadResolve(ctx context.Context, entityID, at // - Return tabular structure fmt.Printf("[TabularAttributeResolver.ReadResolve] Reading tabular attribute %s for entity %s with filters: %+v and fields: %+v\n", attrName, entityID, filters, fields) - repo, err := dbcommons.GetPostgresRepository(ctx) - if err != nil { + if r.repo == nil { return &Result{ Data: nil, Success: false, - Error: fmt.Errorf("failed to get Postgres repository: %v", err), + Error: fmt.Errorf("postgres repository is not configured"), } } // Look up the actual table name from entity_attributes table // The table name is UUID-based and stored during create operation var tableName string - err = repo.DB().QueryRowContext(ctx, + err := r.repo.DB().QueryRowContext(ctx, `SELECT table_name FROM entity_attributes WHERE entity_id = $1 AND attribute_name = $2`, entityID, attrName).Scan(&tableName) if err != nil { @@ -540,7 +560,7 @@ func (r *TabularAttributeResolver) ReadResolve(ctx context.Context, entityID, at log.Printf("[TabularAttributeResolver.ReadResolve] Found tableName: %s", tableName) // Use the GetData method from the repository to retrieve data with filters and fields - anyData, err := repo.GetData(ctx, tableName, filters, fields...) + anyData, err := r.repo.GetData(ctx, tableName, filters, fields...) if err != nil { return &Result{ Data: nil, diff --git a/opengin/core-api/engine/attribute_resolver_test.go b/opengin/core-api/engine/attribute_resolver_test.go index a8478852..814ddc6a 100644 --- a/opengin/core-api/engine/attribute_resolver_test.go +++ b/opengin/core-api/engine/attribute_resolver_test.go @@ -6,11 +6,15 @@ package engine import ( "context" "fmt" + "os" "testing" "time" "lk/datafoundation/core-api/commons" dbcommons "lk/datafoundation/core-api/commons/db" + mongorepository "lk/datafoundation/core-api/db/repository/mongo" + neo4jrepository "lk/datafoundation/core-api/db/repository/neo4j" + postgresrepository "lk/datafoundation/core-api/db/repository/postgres" pb "lk/datafoundation/core-api/lk/datafoundation/core-api" "lk/datafoundation/core-api/pkg/schema" "lk/datafoundation/core-api/pkg/storageinference" @@ -18,6 +22,56 @@ import ( "github.com/stretchr/testify/assert" ) +var ( + testNeo4jRepo *neo4jrepository.Neo4jRepository + testMongoRepo *mongorepository.MongoRepository + testPostgresRepo *postgresrepository.PostgresRepository + testProcessor *EntityAttributeProcessor +) + +func TestMain(m *testing.M) { + ctx := context.Background() + + if os.Getenv("MONGO_URI") == "" { + fmt.Fprintln(os.Stderr, "MONGO_URI is required for engine tests") + os.Exit(1) + } + + var err error + testNeo4jRepo, err = dbcommons.GetNeo4jRepository(ctx) + if err != nil { + fmt.Fprintf(os.Stderr, "failed to initialize Neo4j repository: %v\n", err) + os.Exit(1) + } + + testPostgresRepo, err = dbcommons.GetPostgresRepository(ctx) + if err != nil { + fmt.Fprintf(os.Stderr, "failed to initialize Postgres repository: %v\n", err) + testNeo4jRepo.Close(ctx) + os.Exit(1) + } + + testMongoRepo = dbcommons.GetMongoRepository(ctx) + + testProcessor, err = NewEntityAttributeProcessor(ProcessorDependencies{ + PostgresRepo: testPostgresRepo, + Neo4jRepo: testNeo4jRepo, + MongoRepo: testMongoRepo, + }) + if err != nil { + fmt.Fprintf(os.Stderr, "failed to initialize attribute processor: %v\n", err) + _ = testPostgresRepo.Close() + testNeo4jRepo.Close(ctx) + os.Exit(1) + } + + exitCode := m.Run() + + _ = testPostgresRepo.Close() + testNeo4jRepo.Close(ctx) + os.Exit(exitCode) +} + // createTimeBasedValue creates a TimeBasedValue with the given JSON data func createTimeBasedValue(jsonStr string) (*pb.TimeBasedValue, error) { anyValue, err := schema.JSONToAny(jsonStr) @@ -60,12 +114,11 @@ func createEntityWithAttributes(entityID string, entityName string, attributes m } func saveEntityToDatabase(ctx context.Context, entity *pb.Entity) error { - neo4jRepository, err := dbcommons.GetNeo4jRepository(ctx) - if err != nil { - return fmt.Errorf("failed to get Neo4j repository: %w", err) + if testNeo4jRepo == nil { + return fmt.Errorf("neo4j repository is not initialized") } - success, err := neo4jRepository.HandleGraphEntityCreation(ctx, entity) + success, err := testNeo4jRepo.HandleGraphEntityCreation(ctx, entity) if !success { return fmt.Errorf("failed to save entity: %w", err) } @@ -112,7 +165,7 @@ func TestEntityWithGraphDataOnly(t *testing.T) { err = saveEntityToDatabase(ctx, entity) assert.NoError(t, err) - processor := NewEntityAttributeProcessor() + processor := testProcessor // Test all CORE operations // create test merely checks if the ProcessEntityAttributes function is working @@ -154,7 +207,7 @@ func TestEntityWithTabularDataOnly(t *testing.T) { err = saveEntityToDatabase(ctx, entity) assert.NoError(t, err) - processor := NewEntityAttributeProcessor() + processor := testProcessor // Test all CORE operations // TODO: "read", "update", "delete" @@ -205,7 +258,7 @@ func TestEntityWithDocumentDataOnly(t *testing.T) { err = saveEntityToDatabase(ctx, entity) assert.NoError(t, err) - processor := NewEntityAttributeProcessor() + processor := testProcessor // Test all CORE operations operations := []string{"create", "read", "update", "delete"} @@ -264,7 +317,7 @@ func TestEntityWithMixedDataTypes(t *testing.T) { err = saveEntityToDatabase(ctx, entity) assert.NoError(t, err) - processor := NewEntityAttributeProcessor() + processor := testProcessor // Test all CORE operations // TODO: "read", "update", "delete" @@ -310,7 +363,7 @@ func TestComplexGraphEntity(t *testing.T) { }) assert.NoError(t, err) - processor := NewEntityAttributeProcessor() + processor := testProcessor ctx := context.Background() // save parent entity to the database @@ -353,7 +406,7 @@ func TestComplexTabularEntity(t *testing.T) { }) assert.NoError(t, err) - processor := NewEntityAttributeProcessor() + processor := testProcessor ctx := context.Background() // save parent entity to the database @@ -423,7 +476,7 @@ func TestComplexDocumentEntity(t *testing.T) { }) assert.NoError(t, err) - processor := NewEntityAttributeProcessor() + processor := testProcessor ctx := context.Background() // save parent entity to the database @@ -487,7 +540,7 @@ func TestEntityWithMultipleAttributesOfSameType(t *testing.T) { }) assert.NoError(t, err) - processor := NewEntityAttributeProcessor() + processor := testProcessor ctx := context.Background() // save parent entity to the database @@ -549,7 +602,7 @@ func TestStorageTypeDetection(t *testing.T) { }, } - processor := NewEntityAttributeProcessor() + processor := testProcessor for testName, testCase := range testCases { t.Run(testName, func(t *testing.T) { @@ -575,7 +628,7 @@ func TestEmptyEntity(t *testing.T) { Attributes: make(map[string]*pb.TimeBasedValueList), } - processor := NewEntityAttributeProcessor() + processor := testProcessor ctx := context.Background() // Test all CORE operations @@ -596,7 +649,7 @@ func TestEmptyEntity(t *testing.T) { // TestNilEntity tests handling of nil entity func TestNilEntity(t *testing.T) { - processor := NewEntityAttributeProcessor() + processor := testProcessor ctx := context.Background() // Test all CORE operations @@ -628,7 +681,7 @@ func TestInvalidOperation(t *testing.T) { }) assert.NoError(t, err) - processor := NewEntityAttributeProcessor() + processor := testProcessor ctx := context.Background() options := getOptionsForOperation("invalid_operation") @@ -654,7 +707,7 @@ func TestUnsupportedStorageType(t *testing.T) { }) assert.NoError(t, err) - processor := NewEntityAttributeProcessor() + processor := testProcessor ctx := context.Background() // save parent entity to the database @@ -683,7 +736,7 @@ func TestUnsupportedStorageType(t *testing.T) { // TestBasicFunctionality tests basic functionality of the attribute resolver func TestBasicFunctionality(t *testing.T) { // Test that we can create a processor - processor := NewEntityAttributeProcessor() + processor := testProcessor assert.NotNil(t, processor) assert.NotNil(t, processor.resolvers) diff --git a/opengin/core-api/engine/graph_metadata_manager.go b/opengin/core-api/engine/graph_metadata_manager.go index 62305b7c..5b73c41f 100644 --- a/opengin/core-api/engine/graph_metadata_manager.go +++ b/opengin/core-api/engine/graph_metadata_manager.go @@ -11,7 +11,8 @@ import ( "time" "lk/datafoundation/core-api/commons" - dbcommons "lk/datafoundation/core-api/commons/db" + mongorepository "lk/datafoundation/core-api/db/repository/mongo" + neo4jrepository "lk/datafoundation/core-api/db/repository/neo4j" pb "lk/datafoundation/core-api/lk/datafoundation/core-api" "lk/datafoundation/core-api/pkg/storageinference" @@ -38,13 +39,30 @@ const IS_ATTRIBUTE_RELATIONSHIP_DIRECTION = "OUTGOING" // GraphMetadataManager handles the reference graph for tracking attributes type GraphMetadataManager struct { - // This would typically connect to Neo4j or another graph database - // For now, we'll define the interface and structure + neo4jRepository *neo4jrepository.Neo4jRepository + mongoRepository *mongorepository.MongoRepository } -// NewGraphMetadataManager creates a new graph metadata manager -func NewGraphMetadataManager() *GraphMetadataManager { - return &GraphMetadataManager{} +// NewGraphMetadataManager creates a new graph metadata manager. +func NewGraphMetadataManager(neo4jRepo *neo4jrepository.Neo4jRepository, mongoRepo *mongorepository.MongoRepository) *GraphMetadataManager { + return &GraphMetadataManager{ + neo4jRepository: neo4jRepo, + mongoRepository: mongoRepo, + } +} + +func (g *GraphMetadataManager) requireNeo4jRepository() (*neo4jrepository.Neo4jRepository, error) { + if g.neo4jRepository == nil { + return nil, fmt.Errorf("neo4j repository is not configured") + } + return g.neo4jRepository, nil +} + +func (g *GraphMetadataManager) requireMongoRepository() (*mongorepository.MongoRepository, error) { + if g.mongoRepository == nil { + return nil, fmt.Errorf("mongo repository is not configured") + } + return g.mongoRepository, nil } // AttributeMetadata represents metadata for an attribute in the graph @@ -153,7 +171,7 @@ func (g *GraphMetadataManager) createAttributeLookUpGraph(ctx context.Context, m }, } - neo4jRepository, err := dbcommons.GetNeo4jRepository(ctx) + neo4jRepository, err := g.requireNeo4jRepository() if err != nil { log.Printf("[GraphMetadataManager.CreateAttribute] Error getting Neo4j repository: %v", err) return err @@ -187,7 +205,11 @@ func (g *GraphMetadataManager) createAttributeLookUpGraph(ctx context.Context, m // create the attribute metadata in the mongo database // stored parameters: attribute_id, attribute_name, storage_type, storage_path, updated, schema - mongoRepository := dbcommons.GetMongoRepository(ctx) + mongoRepository, err := g.requireMongoRepository() + if err != nil { + log.Printf("[GraphMetadataManager.CreateAttribute] Error getting Mongo repository: %v", err) + return err + } // Check if the attribute metadata already exists existingMetadata, err := mongoRepository.ReadEntity(ctx, metadata.AttributeID) @@ -248,7 +270,7 @@ func MakeRelationshipFromAttributeMetadata(metadata *AttributeMetadata) *pb.Rela func (g *GraphMetadataManager) GetAttribute(ctx context.Context, entityID string, attributeName string, startTime time.Time) (*AttributeMetadata, error) { fmt.Printf("Getting attribute metadata: EntityID=%s, AttributeName=%s\n", entityID, attributeName) - neo4jRepository, err := dbcommons.GetNeo4jRepository(ctx) + neo4jRepository, err := g.requireNeo4jRepository() if err != nil { log.Printf("[GraphMetadataManager.GetAttribute] Error getting Neo4j repository: %v", err) return nil, err @@ -302,7 +324,11 @@ func (g *GraphMetadataManager) GetAttribute(ctx context.Context, entityID string } // Get the attribute metadata from MongoDB - mongoRepository := dbcommons.GetMongoRepository(ctx) + mongoRepository, err := g.requireMongoRepository() + if err != nil { + log.Printf("[GraphMetadataManager.GetAttribute] Error getting Mongo repository: %v", err) + return nil, err + } attributeMetadataEntity, err := mongoRepository.ReadEntity(ctx, targetAttributeID) if err != nil { log.Printf("[GraphMetadataManager.GetAttribute] Error getting attribute metadata from MongoDB for attribute %s (entity %s): %v", targetAttributeID, entityID, err) @@ -342,7 +368,7 @@ func (g *GraphMetadataManager) GetAttribute(ctx context.Context, entityID string func (g *GraphMetadataManager) ListAttributes(ctx context.Context, entityID string) ([]*AttributeMetadata, error) { fmt.Printf("Listing attributes for entity: %s\n", entityID) - neo4jRepository, err := dbcommons.GetNeo4jRepository(ctx) + neo4jRepository, err := g.requireNeo4jRepository() if err != nil { log.Printf("[GraphMetadataManager.ListAttributes] Error getting Neo4j repository: %v", err) return nil, err @@ -374,7 +400,11 @@ func (g *GraphMetadataManager) ListAttributes(ctx context.Context, entityID stri attributeNameStr := commons.ExtractStringFromAny(attributeName.Value) // Get the attribute metadata from the mongo database - mongoRepository := dbcommons.GetMongoRepository(ctx) + mongoRepository, err := g.requireMongoRepository() + if err != nil { + log.Printf("[GraphMetadataManager.ListAttributes] Error getting Mongo repository: %v", err) + return nil, err + } attributeMetadataEntity, err := mongoRepository.ReadEntity(ctx, attributeID) if err != nil { log.Printf("[GraphMetadataManager.ListAttributes] Error getting attribute metadata from MongoDB for attribute %s (entity %s): %v", attributeID, entityID, err) diff --git a/opengin/core-api/engine/graph_metadata_test.go b/opengin/core-api/engine/graph_metadata_test.go index 4fae4547..9fce4bb6 100644 --- a/opengin/core-api/engine/graph_metadata_test.go +++ b/opengin/core-api/engine/graph_metadata_test.go @@ -15,7 +15,10 @@ import ( // TestGraphMetadataManager tests the graph metadata manager functionality func TestGraphMetadataManager(t *testing.T) { - manager := NewGraphMetadataManager() + if testNeo4jRepo == nil || testMongoRepo == nil { + t.Fatal("test repositories are not initialized") + } + manager := NewGraphMetadataManager(testNeo4jRepo, testMongoRepo) assert.NotNil(t, manager) ctx := context.Background() @@ -134,7 +137,7 @@ func TestGraphMetadataIntegration(t *testing.T) { }) assert.NoError(t, err) - processor := NewEntityAttributeProcessor() + processor := testProcessor ctx := context.Background() // save the parent entity in the database