Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1110)

Side by Side Diff: luci_config/server/cfgclient/config.go

Issue 2580713002: Implement a server-side config service interface. (Closed)
Patch Set: Renamed, moved to luci_config package, fixes, split out backends. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file.
4
5 package cfgclient
6
7 import (
8 "net/url"
9
10 "github.com/luci/luci-go/common/config"
11 "github.com/luci/luci-go/common/errors"
12 "github.com/luci/luci-go/luci_config/common/cfgtypes"
13 "github.com/luci/luci-go/luci_config/server/cfgclient/backend"
14
15 "golang.org/x/net/context"
16 )
17
18 // ErrNoConfig is a sentinel error returned by Get when the requested
19 // configuration is not found.
20 //
21 // This is an alias of github.com/luci/luci-go/common/config.ErrNoConfig for
22 // backward compatibility.
23 var ErrNoConfig = config.ErrNoConfig
24
25 // Meta is metadata about a single configuration file.
26 //
27 // This differs from backend.Meta in that it uses the ConfigSet type for the
28 // ConfigSet field.
29 type Meta struct {
30 // ConfigSet is the item's config set.
31 ConfigSet cfgtypes.ConfigSet
32 // Path is the item's path within its config set.
33 Path string
34
35 // ContentHash is the content hash.
36 ContentHash string
37 // Revision is the revision string.
38 Revision string
39 }
40
41 // Authority is the authority on whose behalf a request is operating.
42 type Authority backend.Authority
43
44 var (
45 // AsAnonymous requests config data as an anonymous user.
46 //
47 // Corresponds to auth.NoAuth.
48 AsAnonymous = Authority(backend.AsAnonymous)
49
50 // AsService requests config data as the currently-running service.
51 //
52 // Corresponds to auth.AsSelf.
53 AsService = Authority(backend.AsService)
54
55 // AsUser requests config data as the currently logged-in user.
56 //
57 // Corresponds to auth.AsUser.
58 AsUser = Authority(backend.AsUser)
59 )
60
61 // ServiceURL returns the URL of the config service.
62 func ServiceURL(c context.Context) url.URL { return backend.Get(c).ServiceURL(c) }
63
64 // Get retrieves a single configuration file.
65 //
66 // r, if supplied, is a MultiResolver that will load the configuration data.
67 // If nil, the configuration data will be discarded (useful if you only care
68 // about metas).
69 //
70 // meta, if not nil, will have the configuration's Meta loaded into it on
71 // success.
72 func Get(c context.Context, a Authority, cs cfgtypes.ConfigSet, path string, r R esolver, meta *Meta) error {
73 be := backend.Get(c)
74
75 params := backend.Params{
76 Authority: backend.Authority(a),
77 Content: true,
78 }
79
80 if fr, ok := r.(FormattingResolver); ok {
81 params.FormatSpec = fr.Format()
82 }
83
84 item, err := be.Get(c, string(cs), path, params)
85 if err != nil {
86 return err
87 }
88
89 if meta != nil {
90 *meta = *makeMeta(&item.Meta)
91 }
92 if r == nil {
93 return nil
94 }
95 return r.Resolve(item)
96 }
97
98 // Projects retrieves all named project configurations.
99 //
100 // r, if supplied, is a MultiResolver that will load the configuration data.
101 // If nil, the configuration data will be discarded (useful if you only care
102 // about metas). If the MultiResolver operates on a slice (which it probably
103 // will), each meta and/or error index will correspond to its slice index.
104 //
105 // If meta is not nil, it will be populated with a slice of *Meta entries
106 // for each loaded configuration, in the same order that r receives them. If
107 // r resolves to a slice, the indexes for each resolved slice entry and meta
108 // entry should align unless r is doing something funky.
109 //
110 // Two types of failure may happen here. A systemic failure fails to load the
111 // set of project configurations. This will be returned directly.
112 //
113 // A resolver failure happens when the configuratiokns load, but could not be
114 // resolved. In this case, any successful resolutions and "meta" will be
115 // populated and an errors.MultiError will be returned containing non-nil
116 // errors at indices whose configs failed to resolve.
117 func Projects(c context.Context, a Authority, path string, r MultiResolver, meta *[]*Meta) error {
118 return getAll(c, a, backend.GetAllProject, path, r, meta)
119 }
120
121 // Refs retrieves all named ref configurations.
122 //
123 // See Projects for individual argument descriptions.
124 func Refs(c context.Context, a Authority, path string, r MultiResolver, meta *[] *Meta) error {
125 return getAll(c, a, backend.GetAllRef, path, r, meta)
126 }
127
128 func getAll(c context.Context, a Authority, t backend.GetAllTarget, path string, r MultiResolver,
129 meta *[]*Meta) error {
130
131 be := backend.Get(c)
132
133 params := backend.Params{
134 Authority: backend.Authority(a),
135 Content: true,
136 }
137
138 if fr, ok := r.(FormattingResolver); ok {
139 params.FormatSpec = fr.Format()
140 }
141
142 items, err := be.GetAll(c, t, path, params)
143 if err != nil {
144 return err
145 }
146
147 // Load our metas.
148 if meta != nil {
149 metaSlice := *meta
150 if metaSlice == nil {
151 metaSlice = make([]*Meta, 0, len(items))
152 } else {
153 // Re-use the supplied slice.
154 metaSlice = metaSlice[:0]
155 }
156
157 for _, item := range items {
158 metaSlice = append(metaSlice, makeMeta(&item.Meta))
159 }
160
161 *meta = metaSlice
162 }
163
164 if r == nil {
165 return nil
166 }
167
168 // Resolve our items. If any individual resolution fails, return that fa ilure
169 // as a positional error in a MultiError.
170 lme := errors.NewLazyMultiError(len(items))
171 r.PrepareMulti(len(items))
172 for i, it := range items {
173 if err := r.ResolveItemAt(i, it); err != nil {
174 lme.Assign(i, err)
175 }
176 }
177 return lme.Get()
178 }
179
180 // GetConfigSetURL returns the URL where the specified ConfigSet is
181 // configured. If the config set doesn't exist, ErrNoConfig will be returned.
182 func GetConfigSetURL(c context.Context, a Authority, cs cfgtypes.ConfigSet) (url .URL, error) {
183 return backend.Get(c).ConfigSetURL(c, string(cs), backend.Params{
184 Authority: backend.Authority(a),
185 })
186 }
187
188 func makeMeta(b *backend.Meta) *Meta {
189 return &Meta{
190 ConfigSet: cfgtypes.ConfigSet(b.ConfigSet),
191 Path: b.Path,
192 ContentHash: b.ContentHash,
193 Revision: b.Revision,
194 }
195 }
OLDNEW
« no previous file with comments | « luci_config/server/cfgclient/backend/meta.go ('k') | luci_config/server/cfgclient/config_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698