in parsers/manifest_parser.go [1188:1322]
func (dm *YAMLParser) ComposeApiRecords(client *whisk.Config, packageName string, pkg Package, manifestPath string,
actionrecords []utils.ActionRecord, sequencerecords []utils.ActionRecord) ([]*whisk.ApiCreateRequest, map[string]*whisk.ApiCreateRequestOptions, error) {
var requests = make([]*whisk.ApiCreateRequest, 0)
// supply a dummy API GW token as it is optional
if pkg.Apis != nil && len(pkg.Apis) != 0 {
if len(client.ApigwAccessToken) == 0 {
warningString := wski18n.T(wski18n.ID_MSG_CONFIG_PROVIDE_DEFAULT_APIGW_ACCESS_TOKEN,
map[string]interface{}{wski18n.KEY_DUMMY_TOKEN: DUMMY_APIGW_ACCESS_TOKEN})
wskprint.PrintOpenWhiskWarning(warningString)
client.ApigwAccessToken = DUMMY_APIGW_ACCESS_TOKEN
}
}
requestOptions := make(map[string]*whisk.ApiCreateRequestOptions, 0)
for apiName, apiDoc := range pkg.Apis {
for gatewayBasePath, gatewayBasePathMap := range apiDoc {
// Base Path
// validate base path should not have any path parameters
if !isGatewayBasePathValid(gatewayBasePath) {
err := wskderrors.NewYAMLParserErr(manifestPath,
wski18n.T(wski18n.ID_ERR_API_GATEWAY_BASE_PATH_INVALID_X_api_X,
map[string]interface{}{wski18n.KEY_API_BASE_PATH: gatewayBasePath}))
return requests, requestOptions, err
}
// append "/" to the gateway base path if its missing
if !strings.HasPrefix(gatewayBasePath, PATH_SEPARATOR) {
gatewayBasePath = PATH_SEPARATOR + gatewayBasePath
}
for gatewayRelPath, gatewayRelPathMap := range gatewayBasePathMap {
// Relative Path
// append "/" to the gateway relative path if its missing
if !strings.HasPrefix(gatewayRelPath, PATH_SEPARATOR) {
gatewayRelPath = PATH_SEPARATOR + gatewayRelPath
}
for actionName, gatewayMethodResponse := range gatewayRelPathMap {
// verify that the action is defined under action records
if _, ok := pkg.Actions[actionName]; ok {
// verify that the action is defined as web action;
// web or web-export set to any of [true, yes, raw]; if not,
// we will try to add it (if no strict" flag) and warn user that we did so
if err := webaction.TryUpdateAPIsActionToWebAction(actionrecords, packageName,
apiName, actionName, false); err != nil {
return requests, requestOptions, err
}
// verify that the sequence action is defined under sequence records
} else if _, ok := pkg.Sequences[actionName]; ok {
// verify that the sequence action is defined as web sequence
// web or web-export set to any of [true, yes, raw]; if not,
// we will try to add it (if no strict" flag) and warn user that we did so
if err := webaction.TryUpdateAPIsActionToWebAction(sequencerecords, packageName,
apiName, actionName, true); err != nil {
return requests, requestOptions, err
}
} else {
return nil, nil, wskderrors.NewYAMLFileFormatError(manifestPath,
wski18n.T(wski18n.ID_ERR_API_MISSING_ACTION_OR_SEQUENCE_X_action_or_sequence_X_api_X,
map[string]interface{}{
wski18n.KEY_ACTION: actionName,
wski18n.KEY_API: apiName}))
}
// get the list of path parameters from relative path
pathParameters := generatePathParameters(gatewayRelPath)
// Check if response type is set to http for API using path parameters
if strings.ToLower(gatewayMethodResponse.Method) != utils.HTTP_FILE_EXTENSION &&
len(pathParameters) > 0 {
warningString := wski18n.T(wski18n.ID_WARN_API_INVALID_RESPONSE_TYPE,
map[string]interface{}{
wski18n.KEY_API: apiName,
wski18n.KEY_API_RELATIVE_PATH: gatewayRelPath,
wski18n.KEY_RESPONSE: gatewayMethodResponse.Response})
wskprint.PrintlnOpenWhiskWarning(warningString)
gatewayMethodResponse.Response = utils.HTTP_FILE_EXTENSION
}
// Check if API verb is valid, it must be one of (GET, PUT, POST, DELETE)
if _, ok := whisk.ApiVerbs[strings.ToUpper(gatewayMethodResponse.Method)]; !ok {
return nil, nil, wskderrors.NewInvalidAPIGatewayMethodError(manifestPath,
gatewayBasePath+gatewayRelPath,
gatewayMethodResponse.Method,
dm.getGatewayMethods())
}
apiDocActionName := actionName
if strings.ToLower(packageName) != DEFAULT_PACKAGE {
apiDocActionName = packageName + PATH_SEPARATOR + actionName
}
// set action of an API Doc
apiDocAction := whisk.ApiAction{
Name: apiDocActionName,
Namespace: client.Namespace,
BackendUrl: strings.Join([]string{HTTPS +
client.Host, strings.ToLower(API),
API_VERSION, WEB, client.Namespace, packageName,
actionName + "." + utils.HTTP_FILE_EXTENSION},
PATH_SEPARATOR),
BackendMethod: gatewayMethodResponse.Method,
Auth: client.AuthToken,
}
requestApiDoc := whisk.Api{
GatewayBasePath: gatewayBasePath,
PathParameters: pathParameters,
GatewayRelPath: gatewayRelPath,
GatewayMethod: strings.ToUpper(gatewayMethodResponse.Method),
Namespace: client.Namespace,
ApiName: apiName,
Id: strings.Join([]string{API, client.Namespace, gatewayRelPath}, ":"),
Action: &apiDocAction,
}
request := whisk.ApiCreateRequest{
ApiDoc: &requestApiDoc,
}
// add a newly created ApiCreateRequest object to a list of requests
requests = append(requests, &request)
// Create an instance of ApiCreateRequestOptions
options := whisk.ApiCreateRequestOptions{
ResponseType: gatewayMethodResponse.Response,
}
apiPath := request.ApiDoc.ApiName + " " + request.ApiDoc.GatewayBasePath +
request.ApiDoc.GatewayRelPath + " " + request.ApiDoc.GatewayMethod
requestOptions[apiPath] = &options
}
}
}
}
return requests, requestOptions, nil
}