13
13
"gopkg.in/juju/charmrepo.v2-unstable/csclient/params"
15
15
"gopkg.in/juju/charmstore.v5-unstable/internal/charmstore"
16
"gopkg.in/juju/charmstore.v5-unstable/internal/mongodoc"
16
17
"gopkg.in/juju/charmstore.v5-unstable/internal/router"
21
22
// GET search[?text=text][&autocomplete=1][&filter=value…][&limit=limit][&include=meta][&skip=count][&sort=field[+dir]]
22
23
// https://github.com/juju/charmstore/blob/v4/docs/API.md#get-search
23
24
func (h *ReqHandler) serveSearch(_ http.Header, req *http.Request) (interface{}, error) {
24
sp, err := parseSearchParams(req)
25
sp, err := ParseSearchParams(req)
28
auth, err := h.checkRequest(req, nil, opOther)
29
auth, err := h.CheckRequest(req, nil, OpOther)
30
31
logger.Infof("authorization failed on search request, granting no privileges: %v", err)
32
33
sp.Admin = auth.Admin
33
34
if auth.Username != "" {
34
35
sp.Groups = append(sp.Groups, auth.Username)
35
groups, err := h.groupsForUser(auth.Username)
36
groups, err := h.GroupsForUser(auth.Username)
37
38
logger.Infof("cannot get groups for user %q, assuming no groups: %v", auth.Username, err)
39
40
sp.Groups = append(sp.Groups, groups...)
41
return h.doSearch(sp, req)
42
return h.Search(sp, req)
44
// doSearch performs the search specified by SearchParams. If sp
45
// Search performs the search specified by SearchParams. If sp
45
46
// specifies that additional metadata needs to be added to the results,
46
47
// then it is added.
47
func (h *ReqHandler) doSearch(sp charmstore.SearchParams, req *http.Request) (interface{}, error) {
48
func (h *ReqHandler) Search(sp charmstore.SearchParams, req *http.Request) (interface{}, error) {
49
50
results, err := h.Store.Search(sp)
60
//addMetada adds the requested meta data with the include list.
61
func (h *ReqHandler) addMetaData(results []*router.ResolvedURL, include []string, req *http.Request) []params.EntityResult {
61
// addMetaData adds the requested meta data with the include list.
62
func (h *ReqHandler) addMetaData(results []*mongodoc.Entity, include []string, req *http.Request) []params.EntityResult {
62
63
entities := make([]params.EntityResult, len(results))
63
64
run := parallel.NewRun(maxConcurrency)
65
for i, ref := range results {
66
for i, ent := range results {
67
68
run.Do(func() error {
68
meta, err := h.Router.GetMetadata(ref, include, req)
69
meta, err := h.Router.GetMetadata(charmstore.EntityResolvedURL(ent), include, req)
70
71
// Unfortunately it is possible to get errors here due to
71
72
// internal inconsistency, so rather than throwing away
72
73
// all the search results, we just log the error and move on.
73
logger.Errorf("cannot retrieve metadata for %v: %v", ref, err)
74
logger.Errorf("cannot retrieve metadata for %v: %v", ent.PreferredURL(true), err)
74
75
atomic.AddInt32(&missing, 1)
77
78
entities[i] = params.EntityResult{
78
Id: ref.PreferredURL(),
79
Id: ent.PreferredURL(true),
106
107
router.WriteError(w, errNotImplemented)
109
// parseSearchParms extracts the search paramaters from the request
110
func parseSearchParams(req *http.Request) (charmstore.SearchParams, error) {
110
// ParseSearchParms extracts the search paramaters from the request
111
func ParseSearchParams(req *http.Request) (charmstore.SearchParams, error) {
111
112
sp := charmstore.SearchParams{}
113
114
for k, v := range req.Form {