github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/destinationfetchersvc/handler.go (about) 1 package destinationfetchersvc 2 3 import ( 4 "context" 5 "fmt" 6 "net/http" 7 8 "github.com/kyma-incubator/compass/components/director/internal/domain/tenant" 9 "github.com/kyma-incubator/compass/components/director/pkg/apperrors" 10 "github.com/kyma-incubator/compass/components/director/pkg/log" 11 ) 12 13 // HandlerConfig destination handler configuration 14 type HandlerConfig struct { 15 SyncDestinationsEndpoint string `envconfig:"APP_DESTINATIONS_SYNC_ENDPOINT,default=/v1/syncDestinations"` 16 DestinationsSensitiveEndpoint string `envconfig:"APP_DESTINATIONS_SENSITIVE_DATA_ENDPOINT,default=/v1/destinations"` 17 DestinationsQueryParameter string `envconfig:"APP_DESTINATIONS_SENSITIVE_DATA_QUERY_PARAM,default=name"` 18 } 19 20 type handler struct { 21 destinationManager DestinationManager 22 config HandlerConfig 23 } 24 25 //go:generate mockery --name=DestinationManager --output=automock --outpkg=automock --case=underscore --disable-version-string 26 // DestinationManager missing godoc 27 type DestinationManager interface { 28 SyncTenantDestinations(ctx context.Context, tenantID string) error 29 FetchDestinationsSensitiveData(ctx context.Context, tenantID string, destinationNames []string) ([]byte, error) 30 } 31 32 // NewDestinationsHTTPHandler returns a new HTTP handler, responsible for handling HTTP requests 33 func NewDestinationsHTTPHandler(destinationManager DestinationManager, config HandlerConfig) *handler { 34 return &handler{ 35 destinationManager: destinationManager, 36 config: config, 37 } 38 } 39 40 func (h *handler) SyncTenantDestinations(writer http.ResponseWriter, request *http.Request) { 41 ctx := request.Context() 42 43 tenantID, err := tenant.LoadFromContext(request.Context()) 44 if err != nil { 45 log.C(ctx).WithError(err).Error("Failed to load tenant ID from request") 46 http.Error(writer, err.Error(), http.StatusBadRequest) 47 return 48 } 49 50 if err := h.destinationManager.SyncTenantDestinations(ctx, tenantID); err != nil { 51 if apperrors.IsNotFoundError(err) { 52 http.Error(writer, err.Error(), http.StatusBadRequest) 53 return 54 } 55 56 log.C(ctx).WithError(err).Errorf("Failed to sync destinations for tenant '%s'", tenantID) 57 58 http.Error(writer, fmt.Sprintf("Failed to sync destinations for tenant %s", 59 tenantID), http.StatusInternalServerError) 60 return 61 } 62 writer.WriteHeader(http.StatusOK) 63 } 64 65 func (h *handler) FetchDestinationsSensitiveData(writer http.ResponseWriter, request *http.Request) { 66 ctx := request.Context() 67 68 tenantID, err := tenant.LoadFromContext(request.Context()) 69 if err != nil { 70 log.C(ctx).WithError(err).Error("Failed to fetch sensitive data for destinations") 71 http.Error(writer, err.Error(), http.StatusBadRequest) 72 return 73 } 74 75 names, ok := request.URL.Query()[h.config.DestinationsQueryParameter] 76 if !ok { 77 err := fmt.Errorf("missing query parameter '%s'", h.config.DestinationsQueryParameter) 78 log.C(ctx).WithError(err).Error("While fetching destinations sensitive data") 79 http.Error(writer, err.Error(), http.StatusBadRequest) 80 return 81 } 82 83 json, err := h.destinationManager.FetchDestinationsSensitiveData(ctx, tenantID, names) 84 85 if err != nil { 86 log.C(ctx).WithError(err).Errorf("Failed to fetch sensitive data for destinations %+v and tenant %s", 87 names, tenantID) 88 if apperrors.IsNotFoundError(err) { 89 http.Error(writer, err.Error(), http.StatusNotFound) 90 return 91 } 92 93 http.Error(writer, fmt.Sprintf("Failed to fetch sensitive data for destinations %+v", names), http.StatusInternalServerError) 94 return 95 } 96 97 if _, err = writer.Write(json); err != nil { 98 log.C(ctx).WithError(err).Error("Could not write response") 99 } 100 }