// Parse command and flags and infer resource, action, href and params func (a *Api) ParseCommandAndFlags(cmd, hrefPrefix string, values ActionCommands) (*CommandTarget, []string, error) { resource, vars, err := a.parseResource(cmd, hrefPrefix, values) if err != nil { return nil, nil, err } var action *metadata.Action elems := strings.Split(cmd, " ") actionName := elems[len(elems)-1] for _, a := range resource.Actions { if a.Name == actionName { action = a break } } if action == nil { supported := make([]string, len(resource.Actions)) for i, a := range resource.Actions { supported[i] = a.Name } return nil, nil, fmt.Errorf("Unknown %s action '%s'. Supported actions are: %s", resource.Name, actionName, strings.Join(supported, ", ")) } path, err := action.Url(vars) if err != nil { return nil, nil, err } flags := values[cmd] return &CommandTarget{resource, action, path, flags.Href}, flags.Params, nil }
// IdentifyParams organizes the given params in two groups: the payload params and the query params. func IdentifyParams(a *metadata.Action, params APIParams) (payloadParams APIParams, queryParams APIParams) { payloadParamNames := a.PayloadParamNames() payloadParams = make(APIParams) for _, n := range payloadParamNames { if p, ok := params[n]; ok { payloadParams[n] = p } } queryParamNames := a.QueryParamNames() queryParams = make(APIParams) for _, n := range queryParamNames { if p, ok := params[n]; ok { queryParams[n] = p } } return payloadParams, queryParams }
// ActionPath computes the path to the given resource action. For example given the href // "/api/servers/123" calling ActionPath with resource "servers" and action "clone" returns the path // "/api/servers/123/clone" and verb POST. // The algorithm consists of extracting the variables from the href by looking up a matching // pattern from the resource metadata. The variables are then substituted in the action path. // If there are more than one pattern that match the href then the algorithm picks the one that can // substitute the most variables. func (r *Href) ActionPath(rName, aName string) (*metadata.ActionPath, error) { res, ok := GenMetadata[rName] if !ok { return nil, fmt.Errorf("No resource with name '%s'", rName) } var action *metadata.Action for _, a := range res.Actions { if a.Name == aName { action = a break } } if action == nil { return nil, fmt.Errorf("No action with name '%s' on %s", aName, rName) } vars, err := res.ExtractVariables(string(*r)) if err != nil { return nil, err } return action.Url(vars) }
It("returns an empty string and the unmatched variables", func() { Ω(path).Should(BeEmpty()) Ω(names).Should(Equal([]string{"d"})) }) }) }) Context("Action Url", func() { var ( // In action *metadata.Action variables []*metadata.PathVariable // Out url string err error // Test data prefix = "/a/path/pattern/with/one/" p1 = &metadata.PathPattern{"GET", prefix + "%s", []string{"a"}, nil} p2 = &metadata.PathPattern{"GET", "%s%s", []string{"a", "b"}, nil} a = metadata.PathVariable{"a", "1"} b = metadata.PathVariable{"b", "2"} ) JustBeforeEach(func() { var p *metadata.ActionPath p, err = action.Url(variables) if err == nil { url = p.Path } })
It("returns an empty string and the unmatched variables", func() { Ω(path).Should(BeEmpty()) Ω(names).Should(Equal([]string{"d"})) }) }) }) Context("Action Url", func() { var ( // In action *metadata.Action variables []*metadata.PathVariable // Out url string err error // Test data prefix = "/a/path/pattern/with/one/" p1 = &metadata.PathPattern{"GET", prefix + "%s", []string{"a"}, nil} p2 = &metadata.PathPattern{"GET", "%s%s", []string{"a", "b"}, nil} a = metadata.PathVariable{"a", "1"} b = metadata.PathVariable{"b", "2"} ) JustBeforeEach(func() { var p *metadata.ActionPath p, err = action.URL(variables) if err == nil { url = p.Path } })