func()

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
}