github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/statusupdate/handler.go (about)

     1  package statusupdate
     2  
     3  import (
     4  	"context"
     5  	"net/http"
     6  
     7  	"github.com/kyma-incubator/compass/components/hydrator/pkg/oathkeeper"
     8  
     9  	"github.com/kyma-incubator/compass/components/director/pkg/persistence"
    10  
    11  	"github.com/kyma-incubator/compass/components/director/pkg/log"
    12  
    13  	"github.com/kyma-incubator/compass/components/director/pkg/consumer"
    14  )
    15  
    16  type update struct {
    17  	transact persistence.Transactioner
    18  	repo     StatusUpdateRepository
    19  }
    20  
    21  // StatusUpdateRepository missing godoc
    22  //
    23  //go:generate mockery --name=StatusUpdateRepository --output=automock --outpkg=automock --case=underscore --disable-version-string
    24  type StatusUpdateRepository interface {
    25  	UpdateStatus(ctx context.Context, id string, object WithStatusObject) error
    26  	IsConnected(ctx context.Context, id string, object WithStatusObject) (bool, error)
    27  }
    28  
    29  // WithStatusObject missing godoc
    30  type WithStatusObject string
    31  
    32  const (
    33  	// Applications missing godoc
    34  	Applications WithStatusObject = "applications"
    35  	// Runtimes missing godoc
    36  	Runtimes WithStatusObject = "runtimes"
    37  )
    38  
    39  // New missing godoc
    40  func New(transact persistence.Transactioner, repo StatusUpdateRepository) *update {
    41  	return &update{
    42  		transact: transact,
    43  		repo:     repo,
    44  	}
    45  }
    46  
    47  // Handler missing godoc
    48  func (u *update) Handler() func(next http.Handler) http.Handler {
    49  	return func(next http.Handler) http.Handler {
    50  		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    51  			ctx := r.Context()
    52  			logger := log.C(ctx)
    53  
    54  			consumerInfo, err := consumer.LoadFromContext(ctx)
    55  			if err != nil {
    56  				logger.WithError(err).Errorf("An error has occurred while fetching consumer info from context: %v", err)
    57  				next.ServeHTTP(w, r)
    58  				return
    59  			}
    60  
    61  			consumerID := consumerInfo.ConsumerID
    62  
    63  			if consumerInfo.Flow == oathkeeper.OneTimeTokenFlow {
    64  				logger.Infof("AuthFlow is %s. Will not update status of %s with ID: %s", consumerInfo.Flow, consumerInfo.ConsumerType, consumerID)
    65  				next.ServeHTTP(w, r)
    66  				return
    67  			}
    68  
    69  			var object WithStatusObject
    70  			switch consumerInfo.ConsumerType {
    71  			case consumer.Application:
    72  				object = Applications
    73  			case consumer.Runtime:
    74  				object = Runtimes
    75  			default:
    76  				next.ServeHTTP(w, r)
    77  				return
    78  			}
    79  
    80  			logger.Infof("Consumer type is: %s. Will check if %s with ID %s is connected.", object, object, consumerID)
    81  
    82  			tx, err := u.transact.Begin()
    83  			if err != nil {
    84  				logger.WithError(err).Errorf("An error has occurred while opening transaction: %v", err)
    85  				next.ServeHTTP(w, r)
    86  				return
    87  			}
    88  			defer u.transact.RollbackUnlessCommitted(ctx, tx)
    89  
    90  			ctxWithDB := persistence.SaveToContext(ctx, tx)
    91  
    92  			isConnected, err := u.repo.IsConnected(ctxWithDB, consumerID, object)
    93  			if err != nil {
    94  				logger.WithError(err).Errorf("An error has occurred while checking repository status for %s with ID %s: %v", object, consumerID, err)
    95  				next.ServeHTTP(w, r)
    96  				return
    97  			}
    98  
    99  			if !isConnected {
   100  				logger.Infof("Consumer %s with ID %s is not connected. Will atempt the update it.", object, consumerID)
   101  
   102  				if err = u.repo.UpdateStatus(ctxWithDB, consumerID, object); err != nil {
   103  					logger.WithError(err).Errorf("An error has occurred while updating repository status for %s with ID %s: %v", object, consumerID, err)
   104  					next.ServeHTTP(w, r)
   105  					return
   106  				}
   107  			}
   108  
   109  			if err := tx.Commit(); err != nil {
   110  				logger.WithError(err).Errorf("An error has occurred while committing transaction: %v", err)
   111  				next.ServeHTTP(w, r)
   112  				return
   113  			}
   114  			next.ServeHTTP(w, r)
   115  		})
   116  	}
   117  }