github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/api/jobserver/list_builds.go (about)

     1  package jobserver
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"net/http"
     7  	"strconv"
     8  
     9  	"github.com/pf-qiu/concourse/v6/atc"
    10  	"github.com/pf-qiu/concourse/v6/atc/api/present"
    11  	"github.com/pf-qiu/concourse/v6/atc/db"
    12  )
    13  
    14  func (s *Server) ListJobBuilds(pipeline db.Pipeline) http.Handler {
    15  	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    16  		var (
    17  			builds     []db.Build
    18  			pagination db.Pagination
    19  			err        error
    20  			from       int
    21  			to         int
    22  			limit      int
    23  		)
    24  
    25  		logger := s.logger.Session("list-job-builds")
    26  
    27  		jobName := r.FormValue(":job_name")
    28  		teamName := r.FormValue(":team_name")
    29  
    30  		timestamps := r.FormValue(atc.PaginationQueryTimestamps)
    31  
    32  		urlFrom := r.FormValue(atc.PaginationQueryFrom)
    33  		urlTo := r.FormValue(atc.PaginationQueryTo)
    34  
    35  		urlLimit := r.FormValue(atc.PaginationQueryLimit)
    36  		limit, _ = strconv.Atoi(urlLimit)
    37  		if limit == 0 {
    38  			limit = atc.PaginationAPIDefaultLimit
    39  		}
    40  
    41  		page := db.Page{Limit: limit}
    42  		if urlFrom != "" {
    43  			from, _ = strconv.Atoi(urlFrom)
    44  			page.From = db.NewIntPtr(from)
    45  		}
    46  		if urlTo != "" {
    47  			to, _ = strconv.Atoi(urlTo)
    48  			page.To = db.NewIntPtr(to)
    49  		}
    50  
    51  		job, found, err := pipeline.Job(jobName)
    52  		if err != nil {
    53  			logger.Error("failed-to-get-job", err)
    54  			w.WriteHeader(http.StatusInternalServerError)
    55  			return
    56  		}
    57  
    58  		if !found {
    59  			w.WriteHeader(http.StatusNotFound)
    60  			return
    61  		}
    62  
    63  		if timestamps == "" {
    64  			builds, pagination, err = job.Builds(page)
    65  		} else {
    66  			page.UseDate = true
    67  			builds, pagination, err = job.BuildsWithTime(page)
    68  		}
    69  		if err != nil {
    70  			w.WriteHeader(http.StatusNotFound)
    71  			return
    72  		}
    73  
    74  		pipelineRef := atc.PipelineRef{
    75  			Name:         pipeline.Name(),
    76  			InstanceVars: pipeline.InstanceVars(),
    77  		}
    78  		if pagination.Older != nil {
    79  			s.addNextLink(w, teamName, pipelineRef, jobName, *pagination.Older)
    80  		}
    81  
    82  		if pagination.Newer != nil {
    83  			s.addPreviousLink(w, teamName, pipelineRef, jobName, *pagination.Newer)
    84  		}
    85  
    86  		w.Header().Set("Content-Type", "application/json")
    87  		w.WriteHeader(http.StatusOK)
    88  
    89  		jobBuilds := make([]atc.Build, len(builds))
    90  		for i := 0; i < len(builds); i++ {
    91  			jobBuilds[i] = present.Build(builds[i])
    92  		}
    93  
    94  		err = json.NewEncoder(w).Encode(jobBuilds)
    95  		if err != nil {
    96  			logger.Error("failed-to-encode-job-builds", err)
    97  			w.WriteHeader(http.StatusInternalServerError)
    98  		}
    99  	})
   100  }
   101  
   102  func (s *Server) addNextLink(w http.ResponseWriter, teamName string, pipelineRef atc.PipelineRef, jobName string, page db.Page) {
   103  	if pipelineRef.InstanceVars != nil {
   104  		w.Header().Add("Link", fmt.Sprintf(
   105  			`<%s/api/v1/teams/%s/pipelines/%s/jobs/%s/builds?%s=%d&%s=%d&%s>; rel="%s"`,
   106  			s.externalURL,
   107  			teamName,
   108  			pipelineRef.Name,
   109  			jobName,
   110  			atc.PaginationQueryTo,
   111  			*page.To,
   112  			atc.PaginationQueryLimit,
   113  			page.Limit,
   114  			pipelineRef.QueryParams().Encode(),
   115  			atc.LinkRelNext,
   116  		))
   117  	} else {
   118  		w.Header().Add("Link", fmt.Sprintf(
   119  			`<%s/api/v1/teams/%s/pipelines/%s/jobs/%s/builds?%s=%d&%s=%d>; rel="%s"`,
   120  			s.externalURL,
   121  			teamName,
   122  			pipelineRef.Name,
   123  			jobName,
   124  			atc.PaginationQueryTo,
   125  			*page.To,
   126  			atc.PaginationQueryLimit,
   127  			page.Limit,
   128  			atc.LinkRelNext,
   129  		))
   130  	}
   131  }
   132  
   133  func (s *Server) addPreviousLink(w http.ResponseWriter, teamName string, pipelineRef atc.PipelineRef, jobName string, page db.Page) {
   134  	if pipelineRef.InstanceVars != nil {
   135  		w.Header().Add("Link", fmt.Sprintf(
   136  			`<%s/api/v1/teams/%s/pipelines/%s/jobs/%s/builds?%s=%d&%s=%d&%s>; rel="%s"`,
   137  			s.externalURL,
   138  			teamName,
   139  			pipelineRef.Name,
   140  			jobName,
   141  			atc.PaginationQueryFrom,
   142  			*page.From,
   143  			atc.PaginationQueryLimit,
   144  			page.Limit,
   145  			pipelineRef.QueryParams().Encode(),
   146  			atc.LinkRelPrevious,
   147  		))
   148  	} else {
   149  		w.Header().Add("Link", fmt.Sprintf(
   150  			`<%s/api/v1/teams/%s/pipelines/%s/jobs/%s/builds?%s=%d&%s=%d>; rel="%s"`,
   151  			s.externalURL,
   152  			teamName,
   153  			pipelineRef.Name,
   154  			jobName,
   155  			atc.PaginationQueryFrom,
   156  			*page.From,
   157  			atc.PaginationQueryLimit,
   158  			page.Limit,
   159  			atc.LinkRelPrevious,
   160  		))
   161  	}
   162  }