diff --git a/Dockerfile b/Dockerfile index b67724e..a8544a3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,6 +6,7 @@ RUN go build -o /build/registry ./cmd/registry FROM alpine:latest WORKDIR /app COPY --from=builder /build/registry . +COPY --from=builder /app/data/seed.json /app/data/seed.json COPY --from=builder /app/internal/docs/swagger.yaml /app/internal/docs/swagger.yaml EXPOSE 8080 diff --git a/cmd/registry/main.go b/cmd/registry/main.go index c86a50b..9f5573c 100644 --- a/cmd/registry/main.go +++ b/cmd/registry/main.go @@ -39,36 +39,35 @@ func main() { // Initialize services based on environment var registryService service.RegistryService - if cfg.Environment == "test" { - // Use fake registry service in test environment - registryService = service.NewFakeRegistryService() - log.Println("Using fake registry service with dummy data (test environment)") - } else { - // Use MongoDB for real registry service in production/other environments - // Create a context with timeout for MongoDB connection - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() + // Use MongoDB for real registry service in production/other environments + // Create a context with timeout for MongoDB connection + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() - // Connect to MongoDB - mongoDB, err := database.NewMongoDB(ctx, cfg.DatabaseURL, cfg.DatabaseName, cfg.CollectionName) - if err != nil { - log.Fatalf("Failed to connect to MongoDB: %v", err) + // Connect to MongoDB + mongoDB, err := database.NewMongoDB(ctx, cfg.DatabaseURL, cfg.DatabaseName, cfg.CollectionName) + if err != nil { + log.Fatalf("Failed to connect to MongoDB: %v", err) + } + + // Create registry service with MongoDB + registryService = service.NewRegistryServiceWithDB(mongoDB) + log.Printf("MongoDB database name: %s", cfg.DatabaseName) + log.Printf("MongoDB collection name: %s", cfg.CollectionName) + + // Store the MongoDB instance for later cleanup + defer func() { + if err := mongoDB.Close(); err != nil { + log.Printf("Error closing MongoDB connection: %v", err) + } else { + log.Println("MongoDB connection closed successfully") } + }() - // Create registry service with MongoDB - registryService = service.NewRegistryServiceWithDB(mongoDB) - log.Printf("Using MongoDB-based registry service (%s environment)", cfg.Environment) - log.Printf("MongoDB database name: %s", cfg.DatabaseName) - log.Printf("MongoDB collection name: %s", cfg.CollectionName) - - // Store the MongoDB instance for later cleanup - defer func() { - if err := mongoDB.Close(); err != nil { - log.Printf("Error closing MongoDB connection: %v", err) - } else { - log.Println("MongoDB connection closed successfully") - } - }() + if cfg.Import { + log.Println("Importing data...") + database.ImportSeedFile(mongoDB, cfg.SeedFilePath) + log.Println("Data import completed successfully") } // Initialize authentication services @@ -92,11 +91,11 @@ func main() { log.Println("Shutting down server...") // Create context with timeout for shutdown - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() + sctx, scancel := context.WithTimeout(context.Background(), 10*time.Second) + defer scancel() // Gracefully shutdown the server - if err := server.Shutdown(ctx); err != nil { + if err := server.Shutdown(sctx); err != nil { log.Fatalf("Server forced to shutdown: %v", err) } diff --git a/internal/config/config.go b/internal/config/config.go index e4f559e..466e1b2 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -6,17 +6,16 @@ import ( // Config holds the application configuration type Config struct { - ServerAddress string `env:"SERVER_ADDRESS" envDefault:":8080"` - DatabaseURL string `env:"DATABASE_URL" envDefault:"mongodb://localhost:27017"` - DatabaseName string `env:"DATABASE_NAME" envDefault:"mcp-registry"` - CollectionName string `env:"COLLECTION_NAME" envDefault:"servers_v2"` - LogLevel string `env:"LOG_LEVEL" envDefault:"info"` - Environment string `env:"ENVIRONMENT" envDefault:"production"` - Version string `env:"VERSION" envDefault:"dev"` - - // GitHub OAuth settings + ServerAddress string `env:"SERVER_ADDRESS" envDefault:":8080"` + DatabaseURL string `env:"DATABASE_URL" envDefault:"mongodb://localhost:27017"` + DatabaseName string `env:"DATABASE_NAME" envDefault:"mcp-registry"` + CollectionName string `env:"COLLECTION_NAME" envDefault:"servers_v2"` + LogLevel string `env:"LOG_LEVEL" envDefault:"info"` + SeedFilePath string `env:"SEED_FILE_PATH" envDefault:"data/seed.json"` + Version string `env:"VERSION" envDefault:"dev"` GithubClientID string `env:"GITHUB_CLIENT_ID" envDefault:""` GithubClientSecret string `env:"GITHUB_CLIENT_SECRET" envDefault:""` + Import bool `env:"IMPORT" envDefault:"true"` } // NewConfig creates a new configuration with default values diff --git a/tools/importer/main.go b/internal/database/import.go similarity index 82% rename from tools/importer/main.go rename to internal/database/import.go index 9f7ab41..6a3fa8c 100644 --- a/tools/importer/main.go +++ b/internal/database/import.go @@ -1,15 +1,12 @@ -package main +package database import ( "context" "encoding/json" - "flag" "fmt" "log" "os" - "os/signal" "path/filepath" - "syscall" "time" "github.com/modelcontextprotocol/registry/internal/model" @@ -18,87 +15,30 @@ import ( "go.mongodb.org/mongo-driver/mongo/options" ) -var ( - mongoURI string - databaseName string - collectionName string - seedFilePath string - dropCollection bool -) - -func init() { - flag.StringVar(&mongoURI, "uri", "mongodb://localhost:27017", "MongoDB connection URI") - flag.StringVar(&databaseName, "db", "mcp_registry", "MongoDB database name") - flag.StringVar(&collectionName, "collection", "servers", "MongoDB collection name") - flag.StringVar(&seedFilePath, "seed", "", "Path to seed.json file (default: data/seed.json)") - flag.BoolVar(&dropCollection, "drop", false, "Drop collection before importing") - flag.Parse() - +// ImportSeedFile populates the MongoDB database with initial data from a seed file. +func ImportSeedFile(mongo *MongoDB, seedFilePath string) error { // Set default seed file path if not provided if seedFilePath == "" { // Try to find the seed.json in the data directory seedFilePath = filepath.Join("data", "seed.json") if _, err := os.Stat(seedFilePath); os.IsNotExist(err) { - // Try from the repository root - repoRoot := filepath.Join("..", "..") - seedFilePath = filepath.Join(repoRoot, "data", "seed.json") + return fmt.Errorf("seed file not found at %s", seedFilePath) } } -} -func main() { // Create a context with timeout for the database operations ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() - // Handle graceful shutdown - sigChan := make(chan os.Signal, 1) - signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) - go func() { - <-sigChan - log.Println("Received termination signal. Cleaning up...") - cancel() - os.Exit(0) - }() - // Read the seed file seedData, err := readSeedFile(seedFilePath) if err != nil { log.Fatalf("Failed to read seed file: %v", err) } - // Connect to MongoDB - log.Printf("Connecting to MongoDB at %s", mongoURI) - client, err := mongo.Connect(ctx, options.Client().ApplyURI(mongoURI)) - if err != nil { - log.Fatalf("Failed to connect to MongoDB: %v", err) - } - defer func() { - if err = client.Disconnect(ctx); err != nil { - log.Fatalf("Failed to disconnect from MongoDB: %v", err) - } - }() - - // Ping MongoDB to verify the connection - if err = client.Ping(ctx, nil); err != nil { - log.Fatalf("Failed to ping MongoDB: %v", err) - } - log.Println("Successfully connected to MongoDB") - - // Get collection - db := client.Database(databaseName) - collection := db.Collection(collectionName) - - // Drop collection if requested - if dropCollection { - log.Printf("Dropping collection %s", collectionName) - if err := collection.Drop(ctx); err != nil { - log.Fatalf("Failed to drop collection: %v", err) - } - } - - // Import data + collection := mongo.collection importData(ctx, collection, seedData) + return nil } // readSeedFile reads and parses the seed.json file diff --git a/tools/importer/README.md b/tools/importer/README.md deleted file mode 100644 index dcf7b4f..0000000 --- a/tools/importer/README.md +++ /dev/null @@ -1,48 +0,0 @@ -# MCP Registry Importer Tool - -This command-line tool imports server data from a JSON file into a MongoDB database for the Model Context Protocol Registry. - -## Usage - -```bash -go run main.go [options] -``` - -### Options - -- `-uri string`: MongoDB connection URI (default "mongodb://localhost:27017") -- `-db string`: MongoDB database name (default "mcp_registry") -- `-collection string`: MongoDB collection name (default "servers") -- `-seed string`: Path to seed.json file (default: looks for data/seed.json relative to current directory) -- `-drop`: Drop collection before importing (default false) - -### Examples - -Import data using default settings: -```bash -go run main.go -``` - -Import data into a specific MongoDB instance: -```bash -go run main.go -uri mongodb://username:password@example.com:27017 -db registry -``` - -Import data from a specific seed file and replace all existing data: -```bash -go run main.go -seed /path/to/custom-seed.json -drop -``` - -## Building - -To build the tool as an executable: - -```bash -go build -o registry-importer -``` - -Then you can run it directly: - -```bash -./registry-importer [options] -```