UNPKG

openapi2apigee

Version:

A tool that converts openapi yaml file to Apigee API Proxy Bundle

235 lines (217 loc) 9.95 kB
/** Copyright 2022 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ var builder = require('xmlbuilder') var fs = require('fs') var path = require('path') var serviceUtils = require('../../util/service.js') module.exports = function generateProxyEndPoint (apiProxy, options, api, cb) { var useCors var destination = options.destination || path.join(__dirname, '../../../api_bundles') if (destination.substr(-1) === '/') { destination = destination.substr(0, destination.length - 1) } var rootDirectory = destination + '/' + apiProxy + '/apiproxy' var root = builder.create('ProxyEndpoint') root.att('name', 'default') root.ele('Description', {}, api.info.title) var preFlow = root.ele('PreFlow', { name: 'PreFlow' }) // Add steps to preflow. var raiseFaultName var requestPipe = preFlow.ele('Request') var responsePipe = preFlow.ele('Response') var services = serviceUtils.servicesToArray(api) if (options.oauth === 'true') { step = requestPipe.ele('Step', {}) step.ele('Name', {}, 'verifyAccessToken') var step2 = requestPipe.ele('Step', {}) step2.ele('Name', {}, 'removeHeaderAuthorization') } services.forEach(function (serviceItem) { if (serviceItem.provider === 'x-cors') { useCors = serviceItem.name var step = responsePipe.ele('Step', {}) step.ele('Name', {}, serviceItem.name) step.ele('Condition', {}, 'request.verb != "OPTIONS"') } if (serviceItem.provider === 'x-input-validation' && serviceItem['apply'].endPoint.indexOf('proxy') > -1) { if (serviceItem['apply'].pipe.indexOf('request') > -1 && serviceItem['options'].displayName) { step = requestPipe.ele('Step', {}) step.ele('Name', {}, 'Extract Path Parameters') step = requestPipe.ele('Step', {}) step.ele('Name', {}, serviceItem['options'].displayName) } } if (serviceItem.provider === 'x-raiseInputValidationFault' && serviceItem['apply'].endPoint.indexOf('proxy') > -1) { if (serviceItem['apply'].pipe.indexOf('request') > -1 && serviceItem['options'].displayName) { raiseFaultName = serviceItem['options'].displayName step = requestPipe.ele('Step', {}) step.ele('Condition', {}, '(INPUT.error equals true)') step.ele('Name', {}, raiseFaultName) } } if (serviceItem.provider === 'x-regex-protection' && serviceItem['apply'].endPoint.indexOf('proxy') > -1) { if (serviceItem['apply'].pipe.indexOf('request') > -1 && serviceItem['options'].displayName) { step = requestPipe.ele('Step', {}) step.ele('Name', {}, serviceItem['options'].displayName) } } if (serviceItem.provider === 'x-raiseFault' && serviceItem['apply'].endPoint.indexOf('proxy') > -1) { if (serviceItem['apply'].pipe.indexOf('request') > -1 && serviceItem['options'].displayName) { raiseFaultName = serviceItem['options'].displayName step = requestPipe.ele('Step', {}) step.ele('Condition', {}, '(FILTER.block equals true)') step.ele('Name', {}, raiseFaultName) } } }) var flows = root.ele('Flows', {}) if (useCors) { preFlow = flows.ele('Flow', { name: 'OptionsPreFlight' }) preFlow.ele('Condition', {}, 'request.verb == "OPTIONS"') preFlow.ele('Request') var preFlowResponse = preFlow.ele('Response') var requestStep = preFlowResponse.ele('Step') requestStep.ele('Name', {}, useCors) } var allowedVerbs = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'HEAD', 'TRACE', 'CONNECT', 'PATCH'] for (var apiPath in api.paths) { for (var resource in api.paths[apiPath]) { if (allowedVerbs.indexOf(resource.toUpperCase()) >= 0) { var resourceItem = api.paths[apiPath][resource] resourceItem.operationId = resourceItem.operationId || resource.toUpperCase() + ' ' + apiPath var flow = flows.ele('Flow', { name: resourceItem.operationId }) var flowCondition = '(proxy.pathsuffix MatchesPath "' + apiPath + '") and (request.verb = "' + resource.toUpperCase() + '")' flow.ele('Condition').raw(flowCondition) flow.ele('Description', {}, resourceItem.summary) requestPipe = flow.ele('Request') // Add conditions for parameters. if (raiseFaultName && resource.toUpperCase() === 'GET' && resourceItem.parameters) { var parameters = resourceItem.parameters var paramCondition = '' var cnt = 0 parameters.forEach(function (param) { if (param.required && param.in === 'query') { var op = (cnt > 0) ? ' or ' : '' paramCondition += op + '(request.queryparam.' + param.name + ' Equals null)' cnt++ } // if (param.required && param.in === 'path') { // var op = (cnt > 0) ? ' or ' : ''; // paramCondition += op + '(request.queryparam.' + param.name + ' Equals null)'; // cnt++; // } }) if (paramCondition.length > 0) { requestStep = requestPipe.ele('Step') requestStep.ele('Condition').raw(paramCondition) requestStep.ele('Name', {}, raiseFaultName) } } responsePipe = flow.ele('Response') if (resourceItem['x-a127-apply']) { for (var service in resourceItem['x-a127-apply']) { if (resourceItem['x-a127-apply'][service].endPoint.indexOf('proxy') > -1) { if (resourceItem['x-a127-apply'][service].pipe.indexOf('request') > -1) { var step = requestPipe.ele('Step', {}) step.ele('Name', {}, service) } if (resourceItem['x-a127-apply'][service].pipe.indexOf('response') > -1) { step = responsePipe.ele('Step', {}) step.ele('Name', {}, service) } // pipe request / response if ends here } // proxy check ends here } // for loop ends here } // check for normal policies ends here // Check for Security Policies in a-127 if (resourceItem['security']) { for (var security in resourceItem['security']) { for (var stepName in resourceItem['security'][security]) { if (stepName === 'oauth2' || stepName === 'apiKeyHeader' || stepName === 'apiKeyQuery') { // Attach verify access token policy.. step = requestPipe.ele('Step', {}) step.ele('Name', {}, 'verifyAccessToken') } } } } } // methods check ends here } // for loop for resources ends here } // for loop for paths ends here var postFlow = root.ele('PostFlow', { name: 'PostFlow' }) postFlow.ele('Request') var postFlowPipe = postFlow.ele('Response') for (var srv in api['x-a127-services']) { var serviceItem = api['x-a127-services'][srv] if (serviceItem.provider === 'x-output-validation' && serviceItem['apply'].endPoint.indexOf('proxy') > -1) { if (serviceItem['apply'].pipe.indexOf('response') > -1 && serviceItem['options'].displayName) { step = postFlowPipe.ele('Step', {}) step.ele('Name', {}, serviceItem['options'].displayName) } } if (serviceItem.provider === 'x-raiseOutputValidationFault' && serviceItem['apply'].endPoint.indexOf('proxy') > -1) { if (serviceItem['apply'].pipe.indexOf('response') > -1 && serviceItem['options'].displayName) { raiseFaultName = serviceItem['options'].displayName step = postFlowPipe.ele('Step', {}) step.ele('Condition', {}, '(SCHEMA.error equals true)') step.ele('Name', {}, raiseFaultName) } } if (serviceItem.provider === 'x-headers' && serviceItem['apply'].endPoint.indexOf('proxy') > -1) { if (serviceItem['apply'].pipe.indexOf('response') > -1 && serviceItem['options'].displayName) { raiseFaultName = serviceItem['options'].displayName step = postFlowPipe.ele('Step', {}) // step.ele('Condition', {}, '(SCHEMA.error equals true)'); step.ele('Name', {}, raiseFaultName) } } } var httpProxyConn = root.ele('HTTPProxyConnection') if (options.basepath) { httpProxyConn.ele('BasePath', {}, options.basepath) } else if (api.basePath !== undefined) { httpProxyConn.ele('BasePath', {}, api.basePath) } else { httpProxyConn.ele('BasePath', {}, '/' + apiProxy) } var virtualhosts = (options.virtualhosts) ? options.virtualhosts.split(',') : ['default', 'secure'] virtualhosts.forEach(function (virtualhost) { httpProxyConn.ele('VirtualHost', {}, virtualhost) }) if (useCors) { var routeRule1 = root.ele('RouteRule', { name: 'noRoute' }) routeRule1.ele('Condition', {}, 'request.verb == "OPTIONS"') } var routeRule2 = root.ele('RouteRule', { name: 'default' }) routeRule2.ele('TargetEndpoint', {}, 'default') var xmlString = root.end({ pretty: true, indent: ' ', newline: '\n' }) fs.writeFile(rootDirectory + '/proxies/default.xml', xmlString, function (err) { if (err) { return cb(err, {}) } cb(null, {}) }) }