Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ai-services/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
REGISTRY?=icr.io/ai-services-private
IMAGE=ai-services
TAG?=v0.0.262
TAG?=v0.0.263
CONTAINER_BUILDER?=podman
CREDS_ARG := $(if $(and $(REGISTRY_USER),$(REGISTRY_PASSWORD)),--creds="$(REGISTRY_USER):$(REGISTRY_PASSWORD)")

Expand Down
2 changes: 1 addition & 1 deletion ai-services/assets/catalog/openshift/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ ui:
cpu: "500m"

backend:
image: icr.io/ai-services-cicd/ai-services:v0.0.262
image: icr.io/ai-services-cicd/ai-services:v0.0.263
runtime: "openshift"
adminPasswordHash: ""
# @generate:password length=32, special=false
Expand Down
2 changes: 1 addition & 1 deletion ai-services/assets/catalog/podman/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ ui:

backend:
port: ""
image: icr.io/ai-services-cicd/ai-services:v0.0.262
image: icr.io/ai-services-cicd/ai-services:v0.0.263
runtime: ""
adminPasswordHash: ""
# @generate:password length=32, special=false
Expand Down
4 changes: 2 additions & 2 deletions ai-services/cmd/ai-services/cmd/application/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ func checkApplicationExists(appClient *catalogClient.ApplicationClient, appName
// buildCatalogPayload builds the catalog API payload for the given template.
func buildCatalogPayload(appName string) (*apiModels.CreateApplicationRequest, error) {
// Initialize catalog provider
provider, err := catalog.NewCatalogProvider()
provider, err := catalog.NewCatalogProvider(nil)
if err != nil {
return nil, fmt.Errorf("failed to create catalog provider: %w", err)
}
Expand Down Expand Up @@ -539,7 +539,7 @@ func printNextSteps(app *catalogTypes.Application) error {
return fmt.Errorf("failed to get application: %w", err)
}

catalogProvider, err := catalog.NewCatalogProvider()
catalogProvider, err := catalog.NewCatalogProvider(nil)
if err != nil {
return fmt.Errorf("failed to create catalog provider: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion ai-services/cmd/ai-services/cmd/application/image/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ var ImageCmd = &cobra.Command{

// getCatalogImages is a helper that creates a catalog provider and collects images.
func getCatalogImages(templateID string) ([]string, error) {
provider, err := catalog.NewCatalogProvider()
provider, err := catalog.NewCatalogProvider(nil)
if err != nil {
return nil, fmt.Errorf("failed to create catalog provider: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion ai-services/cmd/ai-services/cmd/application/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ func renderApplicationInfo(appName string) error {
}

func printServicesInfo(services []catalogTypes.ApplicationService, appPS *catalogTypes.ApplicationPSResponse) error {
catalogProvider, err := catalog.NewCatalogProvider()
catalogProvider, err := catalog.NewCatalogProvider(nil)
if err != nil {
return fmt.Errorf("failed to create catalog provider: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion ai-services/cmd/ai-services/cmd/application/model/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func models(template string) ([]string, error) {
// getCatalogModels is a helper that creates a catalog provider and collects models.
// excludeComponentProviders is a variadic parameter that allows excluding specific component provider by ID.
func getCatalogModels(templateID string, excludeComponentProviders ...string) ([]string, error) {
provider, err := catalog.NewCatalogProvider()
provider, err := catalog.NewCatalogProvider(nil)
if err != nil {
return nil, fmt.Errorf("failed to create catalog provider: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion ai-services/cmd/ai-services/cmd/application/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func init() {
// listCatalogTemplates lists architectures, services, and components from the catalog.
func listCatalogTemplates(cmd *cobra.Command) error {
// Create catalog provider
provider, err := catalog.NewCatalogProvider()
provider, err := catalog.NewCatalogProvider(nil)
if err != nil {
return fmt.Errorf("failed to create catalog provider: %w", err)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func NewParametersCmd() *cobra.Command {
}

// Create catalog provider
provider, err := catalog.NewCatalogProvider()
provider, err := catalog.NewCatalogProvider(nil)
if err != nil {
return fmt.Errorf("failed to create catalog provider: %w", err)
}
Expand Down
17 changes: 8 additions & 9 deletions ai-services/cmd/ai-services/cmd/catalog/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,21 +84,19 @@ func buildAPIServerOptions(ctx context.Context, pool *pgxpool.Pool, secretKey, a
compRepo := repository.NewComponentRepository(pool)
svcDepRepo := repository.NewServiceDependencyRepository(pool)

catalogProvider, err := catalog.NewCatalogProvider(bundleRepo)
if err != nil {
return apiserver.APIServerOptions{}, nil, fmt.Errorf("failed to initialize catalog provider: %w", err)
}

// Initialize sync service for background DB-Pod synchronization
// TODO: implement sync service on remote machines
syncService, err := sync.NewSyncService(appRepo, svcRepo, compRepo, svcDepRepo, sync.DefaultSyncInterval)
syncService, err := sync.NewSyncService(appRepo, svcRepo, compRepo, svcDepRepo, sync.DefaultSyncInterval, catalogProvider)
if err != nil {
return apiserver.APIServerOptions{}, nil, fmt.Errorf("failed to initialize sync service: %w", err)
}
syncService.Start(ctx)

catalogProvider, err := catalog.NewCatalogProvider()
if err != nil {
syncService.Stop(ctx)

return apiserver.APIServerOptions{}, nil, fmt.Errorf("failed to initialize catalog provider: %w", err)
}

tokenMgr := auth.NewTokenManager(secretKey, accessTTL, refreshTTL)
workerRepo := repository.NewWorkerRepository(pool)
workerReg := workerregistry.New(workerRepo)
Expand All @@ -119,7 +117,8 @@ func buildAPIServerOptions(ctx context.Context, pool *pgxpool.Pool, secretKey, a
TokenManager: tokenMgr,
Blacklist: blacklist,
ApplicationService: apirepository.NewApplicationService(appRepo, svcRepo, compRepo, svcDepRepo, catalogProvider, vars.RuntimeFactory.GetRuntimeType()),
BundleService: bundlesvc.NewBundleService(bundleRepo, svcRepo, compRepo),
BundleService: bundlesvc.NewBundleService(bundleRepo, svcRepo, compRepo, catalogProvider),
CatalogProvider: catalogProvider,
WorkerGatewayPort: workerGatewayPort,
WorkerRegistry: workerReg,
}
Expand Down
6 changes: 5 additions & 1 deletion ai-services/internal/pkg/catalog/apiserver/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
"context"
"fmt"

"github.com/project-ai-services/ai-services/internal/pkg/catalog"
"github.com/project-ai-services/ai-services/internal/pkg/catalog/apiserver/repository"
"github.com/project-ai-services/ai-services/internal/pkg/catalog/apiserver/services/auth"
bundlesvc "github.com/project-ai-services/ai-services/internal/pkg/catalog/apiserver/services/bundle"
Expand All @@ -52,6 +53,7 @@ type APIServerOptions struct {
Blacklist repository.TokenBlacklist
ApplicationService repository.ApplicationServiceInterface
BundleService bundlesvc.BundleServiceInterface
CatalogProvider *catalog.CatalogProvider

// WorkerGatewayPort is the port the gRPC worker gateway listens on.
// Defaults to 9090 when zero.
Expand All @@ -69,6 +71,7 @@ type APIserver struct {
blacklist repository.TokenBlacklist
applicationService repository.ApplicationServiceInterface
bundleService bundlesvc.BundleServiceInterface
catalogProvider *catalog.CatalogProvider

workerGatewayPort int
workerRegistry *registry.Registry
Expand All @@ -91,6 +94,7 @@ func NewAPIserver(options APIServerOptions) *APIserver {
blacklist: options.Blacklist,
applicationService: options.ApplicationService,
bundleService: options.BundleService,
catalogProvider: options.CatalogProvider,
workerGatewayPort: options.WorkerGatewayPort,
workerRegistry: options.WorkerRegistry,
}
Expand All @@ -113,7 +117,7 @@ func (a *APIserver) Start(ctx context.Context) error {
}
logger.InfofCtx(ctx, "Worker gateway started on %s", gatewayAddr)

r := CreateRouter(a.authService, a.tokenManager, a.blacklist, a.applicationService, a.workerRegistry, a.bundleService)
r := CreateRouter(a.authService, a.tokenManager, a.blacklist, a.applicationService, a.workerRegistry, a.bundleService, a.catalogProvider)

if err := r.Run(fmt.Sprintf(":%d", a.port)); err != nil {
return err
Expand Down
14 changes: 3 additions & 11 deletions ai-services/internal/pkg/catalog/apiserver/handlers/catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,9 @@ type CatalogHandler struct {
provider *catalog.CatalogProvider
}

// NewCatalogHandler creates a new catalog handler.
func NewCatalogHandler() *CatalogHandler {
provider, err := catalog.NewCatalogProvider()
if err != nil {
// Log error but don't fail - let individual requests handle it
panic(fmt.Sprintf("Failed to initialize catalog provider: %v", err))
}

return &CatalogHandler{
provider: provider,
}
// NewCatalogHandler creates a new catalog handler backed by the given provider.
func NewCatalogHandler(provider *catalog.CatalogProvider) *CatalogHandler {
return &CatalogHandler{provider: provider}
}

// ListArchitectures godoc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"testing"

"github.com/gin-gonic/gin"
"github.com/project-ai-services/ai-services/internal/pkg/catalog"
"github.com/project-ai-services/ai-services/internal/pkg/catalog/types"
"github.com/project-ai-services/ai-services/internal/pkg/runtime"
runtimeTypes "github.com/project-ai-services/ai-services/internal/pkg/runtime/types"
Expand All @@ -27,9 +28,18 @@ func setupTestRouter() *gin.Engine {
return router
}

// newTestCatalogHandler creates a CatalogHandler backed by embedded-only catalog items
// (no bundle DB) — sufficient for unit tests that exercise built-in catalog entries.
func newTestCatalogHandler(t *testing.T) *CatalogHandler {
t.Helper()
provider, err := catalog.NewCatalogProvider(nil)
require.NoError(t, err)
return NewCatalogHandler(provider)
}

func TestListArchitectures(t *testing.T) {
router := setupTestRouter()
handler := NewCatalogHandler()
handler := newTestCatalogHandler(t)
router.GET("/api/v1/architectures", handler.ListArchitectures)

tests := []struct {
Expand Down Expand Up @@ -77,7 +87,7 @@ func TestListArchitectures(t *testing.T) {

func TestGetArchitecture(t *testing.T) {
router := setupTestRouter()
handler := NewCatalogHandler()
handler := newTestCatalogHandler(t)
router.GET("/api/v1/architectures/:id", handler.GetArchitectureDetails)

tests := []struct {
Expand Down Expand Up @@ -146,7 +156,7 @@ func validateArchitectureNotFound(t *testing.T, body []byte) {

func TestListServices(t *testing.T) {
router := setupTestRouter()
handler := NewCatalogHandler()
handler := newTestCatalogHandler(t)
router.GET("/api/v1/services", handler.ListServices)

tests := []struct {
Expand Down Expand Up @@ -206,7 +216,7 @@ func TestListServices(t *testing.T) {

func TestGetService(t *testing.T) {
router := setupTestRouter()
handler := NewCatalogHandler()
handler := newTestCatalogHandler(t)
router.GET("/api/v1/services/:id", handler.GetServiceDetails)

tests := []struct {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -729,12 +729,7 @@ func (s *ApplicationServiceBase) GetApplicationResources(ctx context.Context, id
return nil, fmt.Errorf("failed to create runtime client: %w", err)
}

catalogProvider, err := catalog.NewCatalogProvider()
if err != nil {
return nil, fmt.Errorf("failed to create catalog provider: %w", err)
}

resourceTotals, err := s.collectResources(ctx, app, runtimeClient, catalogProvider)
resourceTotals, err := s.collectResources(ctx, app, runtimeClient, s.Provider)
if err != nil {
return nil, fmt.Errorf("failed to collect application resources: %w", err)
}
Expand Down
5 changes: 3 additions & 2 deletions ai-services/internal/pkg/catalog/apiserver/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/gin-gonic/gin"
_ "github.com/project-ai-services/ai-services/docs" // Import generated docs
"github.com/project-ai-services/ai-services/internal/pkg/catalog"
"github.com/project-ai-services/ai-services/internal/pkg/catalog/apiserver/handlers"
"github.com/project-ai-services/ai-services/internal/pkg/catalog/apiserver/middleware"
"github.com/project-ai-services/ai-services/internal/pkg/catalog/apiserver/repository"
Expand All @@ -17,7 +18,7 @@ import (
)

// CreateRouter sets up the Gin router with the necessary routes and authentication middleware for the API server.
func CreateRouter(authSvc auth.Service, tokenMgr *auth.TokenManager, blacklist repository.TokenBlacklist, appService repository.ApplicationServiceInterface, workerReg *registry.Registry, bundleService bundlesvc.BundleServiceInterface) *gin.Engine {
func CreateRouter(authSvc auth.Service, tokenMgr *auth.TokenManager, blacklist repository.TokenBlacklist, appService repository.ApplicationServiceInterface, workerReg *registry.Registry, bundleService bundlesvc.BundleServiceInterface, catalogProvider *catalog.CatalogProvider) *gin.Engine {
if mode := os.Getenv("GIN_MODE"); mode != "" {
gin.SetMode(mode)
}
Expand All @@ -35,7 +36,7 @@ func CreateRouter(authSvc auth.Service, tokenMgr *auth.TokenManager, blacklist r
registerAuthRoutes(v1, handlers.NewAuthHandler(authSvc), tokenMgr, blacklist)

auth := middleware.AuthMiddleware(tokenMgr, blacklist)
registerCatalogRoutes(v1, handlers.NewCatalogHandler(), handlers.NewResourcesHandler(), auth)
registerCatalogRoutes(v1, handlers.NewCatalogHandler(catalogProvider), handlers.NewResourcesHandler(), auth)
registerApplicationRoutes(v1, handlers.NewApplicationHandler(appService), auth)
registerWorkerRoutes(v1, handlers.NewWorkerHandler(workerReg), auth)
registerBundleRoutes(v1, handlers.NewBundleHandler(bundleService), auth)
Expand Down
Loading
Loading