| package httpdriver |
|
|
| import ( |
| "context" |
| "fmt" |
| "net/http" |
|
|
| "github.com/samber/lo" |
|
|
| "github.com/openmeterio/openmeter/api" |
| "github.com/openmeterio/openmeter/openmeter/app" |
| appcustominvoicing "github.com/openmeterio/openmeter/openmeter/app/custominvoicing" |
| appsandbox "github.com/openmeterio/openmeter/openmeter/app/sandbox" |
| appstripe "github.com/openmeterio/openmeter/openmeter/app/stripe" |
| "github.com/openmeterio/openmeter/pkg/framework/commonhttp" |
| "github.com/openmeterio/openmeter/pkg/framework/transport/httptransport" |
| "github.com/openmeterio/openmeter/pkg/models" |
| "github.com/openmeterio/openmeter/pkg/pagination" |
| ) |
|
|
| |
| type ( |
| ListAppsRequest = app.ListAppInput |
| ListAppsResponse = api.AppPaginatedResponse |
| ListAppsParams = api.ListAppsParams |
| ListAppsHandler httptransport.HandlerWithArgs[ListAppsRequest, ListAppsResponse, ListAppsParams] |
| ) |
|
|
| |
| func (h *handler) ListApps() ListAppsHandler { |
| return httptransport.NewHandlerWithArgs( |
| func(ctx context.Context, r *http.Request, params ListAppsParams) (ListAppsRequest, error) { |
| |
| namespace, err := h.resolveNamespace(ctx) |
| if err != nil { |
| return ListAppsRequest{}, fmt.Errorf("failed to resolve namespace: %w", err) |
| } |
|
|
| return ListAppsRequest{ |
| Namespace: namespace, |
| Page: pagination.Page{ |
| PageSize: lo.FromPtrOr(params.PageSize, app.DefaultPageSize), |
| PageNumber: lo.FromPtrOr(params.Page, app.DefaultPageNumber), |
| }, |
| }, nil |
| }, |
| func(ctx context.Context, request ListAppsRequest) (ListAppsResponse, error) { |
| result, err := h.service.ListApps(ctx, request) |
| if err != nil { |
| return ListAppsResponse{}, fmt.Errorf("failed to list apps: %w", err) |
| } |
|
|
| items := make([]api.App, 0, len(result.Items)) |
| for _, item := range result.Items { |
| app, err := MapAppToAPI(item) |
| if err != nil { |
| return ListAppsResponse{}, fmt.Errorf("failed to map app to api: %w", err) |
| } |
|
|
| items = append(items, app) |
| } |
|
|
| return ListAppsResponse{ |
| Page: result.Page.PageNumber, |
| PageSize: result.Page.PageSize, |
| TotalCount: result.TotalCount, |
| Items: items, |
| }, nil |
| }, |
| commonhttp.JSONResponseEncoderWithStatus[ListAppsResponse](http.StatusOK), |
| httptransport.AppendOptions( |
| h.options, |
| httptransport.WithOperationName("listApps"), |
| )..., |
| ) |
| } |
|
|
| |
| type ( |
| GetAppRequest = app.GetAppInput |
| GetAppResponse = api.App |
| GetAppHandler httptransport.HandlerWithArgs[GetAppRequest, GetAppResponse, string] |
| ) |
|
|
| |
| func (h *handler) GetApp() GetAppHandler { |
| return httptransport.NewHandlerWithArgs( |
| func(ctx context.Context, r *http.Request, appId string) (GetAppRequest, error) { |
| |
| namespace, err := h.resolveNamespace(ctx) |
| if err != nil { |
| return GetAppRequest{}, fmt.Errorf("failed to resolve namespace: %w", err) |
| } |
|
|
| return GetAppRequest{ |
| Namespace: namespace, |
| ID: appId, |
| }, nil |
| }, |
| func(ctx context.Context, request GetAppRequest) (GetAppResponse, error) { |
| app, err := h.service.GetApp(ctx, request) |
| if err != nil { |
| return GetAppResponse{}, fmt.Errorf("failed to get app: %w", err) |
| } |
|
|
| return MapAppToAPI(app) |
| }, |
| commonhttp.JSONResponseEncoderWithStatus[GetAppResponse](http.StatusOK), |
| httptransport.AppendOptions( |
| h.options, |
| httptransport.WithOperationName("getApp"), |
| )..., |
| ) |
| } |
|
|
| |
| type ( |
| UpdateAppRequest = app.UpdateAppInput |
| UpdateAppResponse = api.App |
| UpdateAppHandler httptransport.HandlerWithArgs[UpdateAppRequest, UpdateAppResponse, string] |
| ) |
|
|
| |
| func (h *handler) UpdateApp() UpdateAppHandler { |
| return httptransport.NewHandlerWithArgs( |
| func(ctx context.Context, r *http.Request, appId string) (UpdateAppRequest, error) { |
| |
| namespace, err := h.resolveNamespace(ctx) |
| if err != nil { |
| return UpdateAppRequest{}, fmt.Errorf("failed to resolve namespace: %w", err) |
| } |
|
|
| var body api.UpdateAppJSONRequestBody |
| if err := commonhttp.JSONRequestBodyDecoder(r, &body); err != nil { |
| return UpdateAppRequest{}, fmt.Errorf("field to decode upsert customer data request: %w", err) |
| } |
|
|
| updateType, err := body.Discriminator() |
| if err != nil { |
| return UpdateAppRequest{}, models.NewGenericValidationError(fmt.Errorf("failed to get update type: %w", err)) |
| } |
|
|
| switch updateType { |
| case string(app.AppTypeStripe): |
| payload, err := body.AsStripeAppReplaceUpdate() |
| if err != nil { |
| return UpdateAppRequest{}, fmt.Errorf("failed to get stripe app replace update: %w", err) |
| } |
|
|
| return UpdateAppRequest{ |
| AppID: app.AppID{ |
| ID: appId, |
| Namespace: namespace, |
| }, |
| Name: payload.Name, |
| Description: payload.Description, |
| Metadata: payload.Metadata, |
| AppConfigUpdate: appstripe.Configuration{ |
| SecretAPIKey: payload.SecretAPIKey, |
| }, |
| }, nil |
|
|
| case string(app.AppTypeSandbox): |
| payload, err := body.AsSandboxAppReplaceUpdate() |
| if err != nil { |
| return UpdateAppRequest{}, fmt.Errorf("failed to get sandbox app replace update: %w", err) |
| } |
|
|
| return UpdateAppRequest{ |
| AppID: app.AppID{ |
| ID: appId, |
| Namespace: namespace, |
| }, |
| Name: payload.Name, |
| Description: payload.Description, |
| Metadata: payload.Metadata, |
| AppConfigUpdate: appsandbox.Configuration{}, |
| }, nil |
| case string(app.AppTypeCustomInvoicing): |
| payload, err := body.AsCustomInvoicingAppReplaceUpdate() |
| if err != nil { |
| return UpdateAppRequest{}, fmt.Errorf("failed to get custom invoicing app replace update: %w", err) |
| } |
|
|
| return UpdateAppRequest{ |
| AppID: app.AppID{ |
| ID: appId, |
| Namespace: namespace, |
| }, |
| Name: payload.Name, |
| Description: payload.Description, |
| Metadata: payload.Metadata, |
| AppConfigUpdate: appcustominvoicing.Configuration{ |
| EnableDraftSyncHook: payload.EnableDraftSyncHook, |
| EnableIssuingSyncHook: payload.EnableIssuingSyncHook, |
| }, |
| }, nil |
| default: |
| return UpdateAppRequest{}, models.NewGenericValidationError(fmt.Errorf("invalid app type: %s", updateType)) |
| } |
| }, |
| func(ctx context.Context, request UpdateAppRequest) (UpdateAppResponse, error) { |
| app, err := h.service.UpdateApp(ctx, request) |
| if err != nil { |
| return UpdateAppResponse{}, fmt.Errorf("failed to update app: %w", err) |
| } |
|
|
| return MapAppToAPI(app) |
| }, |
| commonhttp.JSONResponseEncoderWithStatus[UpdateAppResponse](http.StatusOK), |
| httptransport.AppendOptions( |
| h.options, |
| httptransport.WithOperationName("updateApp"), |
| )..., |
| ) |
| } |
|
|
| |
| type ( |
| UninstallAppRequest = app.UninstallAppInput |
| UninstallAppResponse = interface{} |
| UninstallAppHandler httptransport.HandlerWithArgs[UninstallAppRequest, UninstallAppResponse, string] |
| ) |
|
|
| |
| func (h *handler) UninstallApp() UninstallAppHandler { |
| return httptransport.NewHandlerWithArgs( |
| func(ctx context.Context, r *http.Request, appId string) (UninstallAppRequest, error) { |
| |
| namespace, err := h.resolveNamespace(ctx) |
| if err != nil { |
| return UninstallAppRequest{}, fmt.Errorf("failed to resolve namespace: %w", err) |
| } |
|
|
| return UninstallAppRequest{ |
| Namespace: namespace, |
| ID: appId, |
| }, nil |
| }, |
| func(ctx context.Context, request UninstallAppRequest) (UninstallAppResponse, error) { |
| |
|
|
| if err := h.billingService.IsAppUsed(ctx, request); err != nil { |
| return nil, err |
| } |
|
|
| |
| err := h.service.UninstallApp(ctx, request) |
| if err != nil { |
| return nil, fmt.Errorf("failed to uninstall app: %w", err) |
| } |
|
|
| return nil, nil |
| }, |
| commonhttp.EmptyResponseEncoder[UninstallAppResponse](http.StatusNoContent), |
| httptransport.AppendOptions( |
| h.options, |
| httptransport.WithOperationName("uninstallApp"), |
| )..., |
| ) |
| } |
|
|