Introduce NodeJS codegen for Google Cloud Functions. (#4406)

* Another approach: extending NodeJS server to support GCF.

This does not add a new language, but adding some client options
to support Google Cloud Functions (GCF).

* Add URLs for how to deploy the generated code.

Adds the client options help message and the README.md file.
This commit is contained in:
Jun Mukai
2016-12-22 07:11:52 -08:00
committed by wing328
parent 41701a15b0
commit 27f1b6ee98
18 changed files with 1462 additions and 23 deletions

View File

@@ -24,10 +24,16 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
private static final Logger LOGGER = LoggerFactory.getLogger(NodeJSServerCodegen.class);
public static final String GOOGLE_CLOUD_FUNCTIONS = "googleCloudFunctions";
public static final String EXPORTED_NAME = "exportedName";
protected String apiVersion = "1.0.0";
protected int serverPort = 8080;
protected String projectName = "swagger-server";
protected boolean googleCloudFunctions;
protected String exportedName;
public NodeJSServerCodegen() {
super();
@@ -76,27 +82,15 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
additionalProperties.put("apiVersion", apiVersion);
additionalProperties.put("serverPort", serverPort);
/*
* Supporting Files. You can write single files for the generator with the
* entire object tree available. If the input file has a suffix of `.mustache
* it will be processed by the template engine. Otherwise, it will be copied
*/
// supportingFiles.add(new SupportingFile("controller.mustache",
// "controllers",
// "controller.js")
// );
supportingFiles.add(new SupportingFile("swagger.mustache",
"api",
"swagger.yaml")
);
writeOptional(outputFolder, new SupportingFile("index.mustache", "", "index.js"));
writeOptional(outputFolder, new SupportingFile("package.mustache", "", "package.json"));
writeOptional(outputFolder, new SupportingFile("README.mustache", "", "README.md"));
if (System.getProperty("noservice") == null) {
apiTemplateFiles.put(
"service.mustache", // the template to use
"Service.js"); // the extension for each file to write
}
cliOptions.add(CliOption.newBoolean(GOOGLE_CLOUD_FUNCTIONS,
"When specified, it will generate the code which runs within Google Cloud Functions "
+ "instead of standalone Node.JS server. See "
+ "https://cloud.google.com/functions/docs/quickstart for the details of how to "
+ "deploy the generated code."));
cliOptions.add(new CliOption(EXPORTED_NAME,
"When the generated code will be deployed to Google Cloud Functions, this option can be "
+ "used to update the name of the exported function. By default, it refers to the "
+ "basePath. This does not affect normal standalone nodejs server code."));
}
@Override
@@ -171,6 +165,22 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
return outputFolder + File.separator + apiPackage().replace('.', File.separatorChar);
}
public boolean getGoogleCloudFunctions() {
return googleCloudFunctions;
}
public void setGoogleCloudFunctions(boolean value) {
googleCloudFunctions = value;
}
public String getExportedName() {
return exportedName;
}
public void setExportedName(String name) {
exportedName = name;
}
@Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
@SuppressWarnings("unchecked")
@@ -240,6 +250,46 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
return opsByPathList;
}
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey(GOOGLE_CLOUD_FUNCTIONS)) {
setGoogleCloudFunctions(
Boolean.valueOf(additionalProperties.get(GOOGLE_CLOUD_FUNCTIONS).toString()));
}
if (additionalProperties.containsKey(EXPORTED_NAME)) {
setExportedName((String)additionalProperties.get(EXPORTED_NAME));
}
/*
* Supporting Files. You can write single files for the generator with the
* entire object tree available. If the input file has a suffix of `.mustache
* it will be processed by the template engine. Otherwise, it will be copied
*/
// supportingFiles.add(new SupportingFile("controller.mustache",
// "controllers",
// "controller.js")
// );
supportingFiles.add(new SupportingFile("swagger.mustache",
"api",
"swagger.yaml")
);
if (getGoogleCloudFunctions()) {
writeOptional(outputFolder, new SupportingFile("index-gcf.mustache", "", "index.js"));
} else {
writeOptional(outputFolder, new SupportingFile("index.mustache", "", "index.js"));
}
writeOptional(outputFolder, new SupportingFile("package.mustache", "", "package.json"));
writeOptional(outputFolder, new SupportingFile("README.mustache", "", "README.md"));
if (System.getProperty("noservice") == null) {
apiTemplateFiles.put(
"service.mustache", // the template to use
"Service.js"); // the extension for each file to write
}
}
@Override
public void preprocessSwagger(Swagger swagger) {
String host = swagger.getHost();
@@ -262,6 +312,22 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
}
}
if (getGoogleCloudFunctions()) {
// Note that Cloud Functions don't allow customizing port name, simply checking host
// is good enough.
if (!host.endsWith(".cloudfunctions.net")) {
LOGGER.warn("Host " + host + " seems not matching with cloudfunctions.net URL.");
}
if (!additionalProperties.containsKey(EXPORTED_NAME)) {
String basePath = swagger.getBasePath();
if (basePath == null || basePath.equals("/")) {
LOGGER.warn("Cannot find the exported name properly. Using 'openapi' as the exported name");
basePath = "/openapi";
}
additionalProperties.put(EXPORTED_NAME, basePath.substring(1));
}
}
// need vendor extensions for x-swagger-router-controller
Map<String, Path> paths = swagger.getPaths();
if(paths != null) {