github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/pkg/whitesource/scanPolling.go (about)

     1  package whitesource
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/SAP/jenkins-library/pkg/log"
     6  	"time"
     7  )
     8  
     9  type whitesourcePoller interface {
    10  	GetProjectByToken(projectToken string) (Project, error)
    11  }
    12  
    13  // BlockUntilReportsAreReady polls the WhiteSource system for all projects known to the Scan and blocks
    14  // until their LastUpdateDate time stamp is from within the last 20 seconds.
    15  func (s *Scan) BlockUntilReportsAreReady(sys whitesourcePoller) error {
    16  	for _, project := range s.ScannedProjects() {
    17  		if err := pollProjectStatus(project.Token, s.ScanTime(project.Name), sys); err != nil {
    18  			return err
    19  		}
    20  	}
    21  	return nil
    22  }
    23  
    24  type pollOptions struct {
    25  	scanTime         time.Time
    26  	maxAge           time.Duration
    27  	timeBetweenPolls time.Duration
    28  	maxWaitTime      time.Duration
    29  }
    30  
    31  // pollProjectStatus polls project LastUpdateDate until it reflects the most recent scan
    32  func pollProjectStatus(projectToken string, scanTime time.Time, sys whitesourcePoller) error {
    33  	options := pollOptions{
    34  		scanTime:         scanTime,
    35  		maxAge:           20 * time.Second,
    36  		timeBetweenPolls: 20 * time.Second,
    37  		maxWaitTime:      30 * time.Minute,
    38  	}
    39  	return blockUntilProjectIsUpdated(projectToken, sys, options)
    40  }
    41  
    42  // blockUntilProjectIsUpdated polls the project LastUpdateDate until it is newer than the given time stamp
    43  // or no older than maxAge relative to the given time stamp.
    44  func blockUntilProjectIsUpdated(projectToken string, sys whitesourcePoller, options pollOptions) error {
    45  	startTime := time.Now()
    46  	for {
    47  		project, err := sys.GetProjectByToken(projectToken)
    48  		if err != nil {
    49  			return err
    50  		}
    51  
    52  		if project.LastUpdateDate == "" {
    53  			log.Entry().Infof("last updated time missing from project metadata, retrying")
    54  		} else {
    55  			lastUpdatedTime, err := time.Parse(DateTimeLayout, project.LastUpdateDate)
    56  			if err != nil {
    57  				return fmt.Errorf("failed to parse last updated time (%s) of Whitesource project: %w",
    58  					project.LastUpdateDate, err)
    59  			}
    60  			age := options.scanTime.Sub(lastUpdatedTime)
    61  			if age < options.maxAge {
    62  				//done polling
    63  				break
    64  			}
    65  			log.Entry().Infof("time since project was last updated %v > %v, polling status...", age, options.maxAge)
    66  		}
    67  
    68  		if time.Now().Sub(startTime) > options.maxWaitTime {
    69  			return fmt.Errorf("timeout while waiting for Whitesource scan results to be reflected in service")
    70  		}
    71  
    72  		time.Sleep(options.timeBetweenPolls)
    73  	}
    74  	return nil
    75  }