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  }