github.com/web-platform-tests/wpt.fyi@v0.0.0-20240530210107-70cf978996f1/api/labels.go (about)

     1  // Copyright 2019 The WPT Dashboard Project. All rights reserved.
     2  // Use of this source code is governed by a BSD-style license that can be
     3  // found in the LICENSE file.
     4  
     5  package api
     6  
     7  import (
     8  	"context"
     9  	"encoding/json"
    10  	"net/http"
    11  	"sort"
    12  	"time"
    13  
    14  	mapset "github.com/deckarep/golang-set"
    15  	"github.com/web-platform-tests/wpt.fyi/shared"
    16  )
    17  
    18  // LabelsHandler is an http.Handler for the /api/labels endpoint.
    19  type LabelsHandler struct {
    20  	ctx context.Context // nolint:containedctx // TODO: Fix containedctx lint error
    21  }
    22  
    23  // apiLabelsHandler is responsible for emitting just all labels used for test runs.
    24  func apiLabelsHandler(w http.ResponseWriter, r *http.Request) {
    25  	// Serve cached with 5 minute expiry. Delegate to LabelsHandler on cache miss.
    26  	ctx := r.Context()
    27  	shared.NewCachingHandler(
    28  		ctx,
    29  		LabelsHandler{ctx},
    30  		shared.NewGZReadWritable(shared.NewRedisReadWritable(ctx, 5*time.Minute)),
    31  		shared.AlwaysCachable,
    32  		shared.URLAsCacheKey,
    33  		shared.CacheStatusOK,
    34  	).ServeHTTP(w, r)
    35  }
    36  
    37  func (h LabelsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    38  	store := shared.NewAppEngineDatastore(h.ctx, false)
    39  	var runs shared.TestRuns
    40  	_, err := store.GetAll(store.NewQuery("TestRun").Project("Labels").Distinct(), &runs)
    41  	if err != nil {
    42  		http.Error(w, err.Error(), http.StatusInternalServerError)
    43  
    44  		return
    45  	}
    46  
    47  	all := mapset.NewSet()
    48  	for _, run := range runs {
    49  		for _, label := range run.Labels {
    50  			all.Add(label)
    51  		}
    52  	}
    53  	labels := shared.ToStringSlice(all)
    54  	sort.Strings(labels)
    55  	data, err := json.Marshal(labels)
    56  	if err != nil {
    57  		http.Error(w, err.Error(), http.StatusInternalServerError)
    58  
    59  		return
    60  	}
    61  	_, err = w.Write(data)
    62  	if err != nil {
    63  		logger := shared.GetLogger(r.Context())
    64  		logger.Warningf("Failed to write data in api/labels handler: %s", err.Error())
    65  	}
    66  }