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 }