func (s *Server) Roles() []ttnpb.ClusterRole {
	return []ttnpb.ClusterRole{ttnpb.ClusterRole_GATEWAY_CONFIGURATION_SERVER}
}
Roles returns the roles that the Gateway Configuration Server fulfills.
package gatewayconfigurationserver
import (
	"context"
	"encoding"
	"encoding/json"
	"net/http"
	"github.com/gogo/protobuf/types"
	"github.com/gorilla/mux"
	"github.com/grpc-ecosystem/grpc-gateway/runtime"
	"go.thethings.network/lorawan-stack/v3/pkg/component"
	gcsv2 "go.thethings.network/lorawan-stack/v3/pkg/gatewayconfigurationserver/v2"
	"go.thethings.network/lorawan-stack/v3/pkg/pfconfig/cpf"
	"go.thethings.network/lorawan-stack/v3/pkg/pfconfig/semtechudp"
	"go.thethings.network/lorawan-stack/v3/pkg/ratelimit"
	"go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
	"go.thethings.network/lorawan-stack/v3/pkg/web"
	"go.thethings.network/lorawan-stack/v3/pkg/webhandlers"
	"go.thethings.network/lorawan-stack/v3/pkg/webmiddleware"
	"google.golang.org/grpc"
)
type Server struct {
	*component.Component
	config *Config
}
func (s *Server) withGateway(next func(http.ResponseWriter, *http.Request, *ttnpb.Gateway)) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		ctx := r.Context()
		gtwID := gatewayIDFromContext(ctx)
		cc, err := s.GetPeerConn(ctx, ttnpb.ClusterRole_ENTITY_REGISTRY, &gtwID)
		if err != nil {
			webhandlers.Error(w, r, err)
			return
		}
		client := ttnpb.NewGatewayRegistryClient(cc)
		gtw, err := client.Get(ctx, &ttnpb.GetGatewayRequest{
			GatewayIds: &gtwID,
			FieldMask: &types.FieldMask{
				Paths: []string{
					"antennas",
					"frequency_plan_id",
					"gateway_server_address",
				},
			},
		}, s.WithClusterAuth())
		if err != nil {
			webhandlers.Error(w, r, err)
			return
		}
		next(w, r, gtw)
	}
}
func (s *Server) makeJSONHandler(f func(context.Context, *ttnpb.Gateway) (interface{}, error)) http.HandlerFunc {
	return s.withGateway(func(w http.ResponseWriter, r *http.Request, gtw *ttnpb.Gateway) {
		msg, err := f(r.Context(), gtw)
		if err != nil {
			webhandlers.Error(w, r, err)
			return
		}
		w.Header().Set("Content-Type", "application/json")
		w.WriteHeader(http.StatusOK)
		enc := json.NewEncoder(w)
		enc.SetIndent("", "\t")
		enc.Encode(msg)
	})
}
func (s *Server) makeTextMarshalerHandler(contentType string, f func(context.Context, *ttnpb.Gateway) (encoding.TextMarshaler, error)) http.HandlerFunc {
	return s.withGateway(func(w http.ResponseWriter, r *http.Request, gtw *ttnpb.Gateway) {
		msg, err := f(r.Context(), gtw)
		if err != nil {
			webhandlers.Error(w, r, err)
			return
		}
		b, err := msg.MarshalText()
		if err != nil {
			webhandlers.Error(w, r, err)
			return
		}
		w.Header().Set("Content-Type", contentType)
		w.WriteHeader(http.StatusOK)
		w.Write(b)
	})
}