func()

in openapi/commando.go [287:404]


func (c *Commando) createInvoker(ctx *cli.Context, productCode string, apiOrMethod string, path string) (Invoker, error) {
	force := ForceFlag(ctx.Flags()).IsAssigned()
	basicInvoker := NewBasicInvoker(&c.profile)

	//
	// get product info
	if product, ok := c.library.GetProduct(productCode); ok {
		err := basicInvoker.Init(ctx, &product)
		if err != nil {
			return nil, err
		}
		if force {
			if version, _ := ctx.Flags().Get("version").GetValue(); version != "" {
				if style, ok := c.library.GetStyle(productCode, version); ok {
					product.ApiStyle = style
				} else {
					// 没有在 versions.json 中配置的版本可以通过 --style 自行指定
					style, _ := ctx.Flags().Get("style").GetValue()
					if style == "" {
						return nil, cli.NewErrorWithTip(fmt.Errorf("uncheked version %s", version),
							"Please use --style to specify API style, rpc or restful.")
					}
					product.ApiStyle = style
				}
			}
		}

		if strings.ToLower(product.ApiStyle) == "rpc" {
			//
			// Rpc call
			if path != "" {
				return nil, cli.NewErrorWithTip(fmt.Errorf("invalid argument %s", path),
					"Use `aliyun help %s` see more information.", product.GetLowerCode())
			}
			if force {
				return &ForceRpcInvoker{
					basicInvoker,
					apiOrMethod,
				}, nil
			}
			if api, ok := c.library.GetApi(product.Code, product.Version, apiOrMethod); ok {
				return &RpcInvoker{
					basicInvoker,
					&api,
				}, nil
			}
			return nil, &InvalidApiError{apiOrMethod, &product}
		}

		//
		// Restful Call
		// aliyun cs GET /clusters
		// aliyun cs /clusters --roa GET
		ok, method, path, err := checkRestfulMethod(ctx, apiOrMethod, path)
		if err != nil {
			return nil, err
		}

		if !ok {
			return nil, cli.NewErrorWithTip(fmt.Errorf("product '%s' need restful call", product.GetLowerCode()),
				"Use `aliyun %s {GET|PUT|POST|DELETE} <path> ...`", product.GetLowerCode())
		}

		if api, ok := c.library.GetApi(product.Code, product.Version, ctx.Command().Name); ok {
			return &RestfulInvoker{
				basicInvoker,
				method,
				path,
				force,
				&api,
			}, nil
		}

		return &RestfulInvoker{
			basicInvoker,
			method,
			path,
			force,
			nil,
		}, nil
	} else {
		if !force {
			return nil, &InvalidProductError{Code: productCode, library: c.library}
		}

		//
		// force call on unknown product, use temporary product info
		product = meta.Product{
			Code: productCode,
		}
		err := basicInvoker.Init(ctx, &product)
		if err != nil {
			return nil, err
		}

		//
		// Restful Call
		// aliyun cs GET /clusters
		// aliyun cs /clusters --roa GET
		ok, method, path, err := checkRestfulMethod(ctx, apiOrMethod, path)
		if err != nil {
			return nil, err
		}
		if ok {
			return &RestfulInvoker{
				basicInvoker,
				method,
				path,
				force,
				nil,
			}, nil
		}
		return &ForceRpcInvoker{
			basicInvoker,
			apiOrMethod,
		}, nil
	}
}