You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ni...@apache.org on 2019/06/21 07:09:18 UTC
[servicecomb-toolkit] 02/49: initial version.Support for generating
ServiceComb code that used Springmvc model.
This is an automated email from the ASF dual-hosted git repository.
ningjiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-toolkit.git
commit bfa5bd740a5263bffef468eed493fb1a56f7aa87
Author: MabinGo <bi...@huawei.com>
AuthorDate: Thu May 16 21:31:32 2019 +0800
initial version.Support for generating ServiceComb code that used Springmvc model.
Signed-off-by: MabinGo <bi...@huawei.com>
---
.gitignore | 86 ++++++++++++
code-generator/pom.xml | 69 +++++++++
.../servicecomb/toolkit/codegen/CodeGenerator.java | 30 ++++
.../toolkit/codegen/DefaultCodeGenerator.java | 41 ++++++
.../codegen/ServiceCombProviderCodegen.java | 155 +++++++++++++++++++++
.../services/io.swagger.codegen.CodegenConfig | 18 +++
.../resources/ServiceCombProvider/README.mustache | 20 +++
.../ServiceCombProvider/enumClass.mustache | 43 ++++++
.../ServiceCombProvider/enumOuterClass.mustache | 37 +++++
.../generatedAnnotation.mustache | 1 +
.../libraries/SpringMvc/Application.mustache | 28 ++++
.../libraries/SpringMvc/api.mustache | 42 ++++++
.../libraries/SpringMvc/api_test.mustache | 102 ++++++++++++++
.../libraries/SpringMvc/bodyParams.mustache | 1 +
.../libraries/SpringMvc/formParams.mustache | 2 +
.../libraries/SpringMvc/headerParams.mustache | 1 +
.../libraries/SpringMvc/pathParams.mustache | 1 +
.../libraries/SpringMvc/pom.mustache | 104 ++++++++++++++
.../libraries/SpringMvc/queryParams.mustache | 1 +
.../resources/ServiceCombProvider/log4j2.mustache | 41 ++++++
.../ServiceCombProvider/microservice.mustache | 43 ++++++
.../resources/ServiceCombProvider/model.mustache | 27 ++++
.../resources/ServiceCombProvider/pojo.mustache | 134 ++++++++++++++++++
.../ServiceCombProvider/returnTypes.mustache | 1 +
.../typeInfoAnnotation.mustache | 7 +
.../ServiceCombProvider/xmlAnnotation.mustache | 6 +
pom.xml | 40 ++++++
toolkit-cli/dependency-reduced-pom.xml | 64 +++++++++
toolkit-cli/pom.xml | 102 ++++++++++++++
.../servicecomb/toolkit/cli/CodeGenerate.java | 114 +++++++++++++++
.../servicecomb/toolkit/cli/ToolkitMain.java | 58 ++++++++
.../src/main/resources/application.properties | 1 +
32 files changed, 1420 insertions(+)
diff --git a/.gitignore b/.gitignore
new file mode 100755
index 0000000..e396f22
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,86 @@
+# Output Directory
+target/
+
+# C pre-compile
+*.gch
+*.pch
+
+# C compile
+*.a
+*.o
+*.ko
+*.la
+*.lo
+*.obj
+*.elf
+*.so
+*.so.*
+*.dylib
+*.exe
+*.lib
+*.dll
+*.out
+*.app
+*.hex
+
+# Debug files
+*.dSYM/
+
+# Java
+*.class
+
+# Java Package Files
+*.jar
+*.war
+*.ear
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+# Zip Files
+*.rar
+*.zip
+*.7z
+*.tar
+*.gz
+
+# Ant
+build/
+
+# Compiled Python
+__pycache__/
+*.py[cod]
+*py.class
+
+# Eclipse
+.settings/
+.classpath
+.project
+
+# IntelliJ, based on http://devnet.jetbrains.net/docs/DOC-1186
+.idea/
+*.iml
+*.ipr
+*.iws
+
+# logs and trace
+*.log
+*.trace
+*.dat
+
+# vi swap
+*.swp
+
+# Backup Files
+*.bak
+*.old
+
+# SVN metadata
+.svn/
+
+# Mac
+.DS_Store
+
+# gradle
+.gradle
+
diff --git a/code-generator/pom.xml b/code-generator/pom.xml
new file mode 100755
index 0000000..9866719
--- /dev/null
+++ b/code-generator/pom.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You 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
+ ~
+ ~ http://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.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>toolkit</artifactId>
+ <groupId>org.apache.servicecomb</groupId>
+ <version>0.1.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>code-generator</artifactId>
+
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <swagger-codegen-version>2.4.3</swagger-codegen-version>
+ <maven-plugin-version>1.0.0</maven-plugin-version>
+ <junit-version>4.8.1</junit-version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>io.swagger</groupId>
+ <artifactId>swagger-codegen</artifactId>
+ <version>${swagger-codegen-version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.6.1</version>
+ <configuration>
+ <source>8</source>
+ <target>8</target>
+ </configuration>
+ </plugin>
+ </plugins>
+
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <includes>
+ <include>**/*.*</include>
+ </includes>
+ </resource>
+ </resources>
+ </build>
+</project>
diff --git a/code-generator/src/main/java/org/apache/servicecomb/toolkit/codegen/CodeGenerator.java b/code-generator/src/main/java/org/apache/servicecomb/toolkit/codegen/CodeGenerator.java
new file mode 100755
index 0000000..2ac18c5
--- /dev/null
+++ b/code-generator/src/main/java/org/apache/servicecomb/toolkit/codegen/CodeGenerator.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ * http://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.
+ */
+
+package org.apache.servicecomb.toolkit.codegen;
+
+import java.io.File;
+import java.util.List;
+
+import io.swagger.codegen.config.CodegenConfigurator;
+
+public interface CodeGenerator {
+
+ CodeGenerator opts(CodegenConfigurator opts);
+
+ List<File> generate();
+}
diff --git a/code-generator/src/main/java/org/apache/servicecomb/toolkit/codegen/DefaultCodeGenerator.java b/code-generator/src/main/java/org/apache/servicecomb/toolkit/codegen/DefaultCodeGenerator.java
new file mode 100755
index 0000000..459cf56
--- /dev/null
+++ b/code-generator/src/main/java/org/apache/servicecomb/toolkit/codegen/DefaultCodeGenerator.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ * http://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.
+ */
+
+package org.apache.servicecomb.toolkit.codegen;
+
+import java.io.File;
+import java.util.List;
+
+import io.swagger.codegen.DefaultGenerator;
+import io.swagger.codegen.config.CodegenConfigurator;
+
+public class DefaultCodeGenerator implements CodeGenerator {
+
+ private DefaultGenerator generator = new DefaultGenerator();
+
+ @Override
+ public CodeGenerator opts(CodegenConfigurator opts) {
+
+ generator.opts(opts.toClientOptInput());
+ return this;
+ }
+
+ @Override
+ public List<File> generate() {
+ return generator.generate();
+ }
+}
diff --git a/code-generator/src/main/java/org/apache/servicecomb/toolkit/codegen/ServiceCombProviderCodegen.java b/code-generator/src/main/java/org/apache/servicecomb/toolkit/codegen/ServiceCombProviderCodegen.java
new file mode 100755
index 0000000..25b345f
--- /dev/null
+++ b/code-generator/src/main/java/org/apache/servicecomb/toolkit/codegen/ServiceCombProviderCodegen.java
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ * http://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.
+ */
+
+package org.apache.servicecomb.toolkit.codegen;
+
+import java.io.File;
+import java.util.Map;
+
+import io.swagger.codegen.CliOption;
+import io.swagger.codegen.CodegenConfig;
+import io.swagger.codegen.CodegenConstants;
+import io.swagger.codegen.CodegenType;
+import io.swagger.codegen.SupportingFile;
+import io.swagger.codegen.languages.AbstractJavaCodegen;
+import io.swagger.codegen.languages.SpringCodegen;
+import io.swagger.codegen.mustache.CamelCaseLambda;
+
+public class ServiceCombProviderCodegen extends AbstractJavaCodegen implements CodegenConfig {
+
+ private static final String DEFAULT_LIBRARY = "SpringMvc";
+
+ private String resourcesFolder = projectFolder + File.separator + "resources";
+
+ private String apiVersion = "1.0.0";
+
+ private String mainClassPackage;
+
+
+ @Override
+ public CodegenType getTag() {
+ return CodegenType.SERVER;
+ }
+
+ @Override
+ public String getName() {
+ return "ServiceCombProvider";
+ }
+
+ @Override
+ public String getHelp() {
+ return "Generates a ServiceComb server library.";
+ }
+
+ public ServiceCombProviderCodegen() {
+ super();
+
+ outputFolder = "generated-code/ServiceCombProvider";
+
+ modelDocTemplateFiles.remove("model_doc.mustache");
+ apiDocTemplateFiles.remove("api_doc.mustache");
+ apiTestTemplateFiles.remove("api_test.mustache");
+
+ embeddedTemplateDir = templateDir = "ServiceCombProvider";
+
+ apiPackage = "servicecomb.example.controller";
+
+ modelPackage = "servicecomb.example.model";
+
+ mainClassPackage = "servicecomb.example";
+
+ groupId = "org.apache.servicecomb";
+ artifactId = "demo";
+
+ supportedLibraries.put(DEFAULT_LIBRARY, "ServiceComb Server application using the springboot programming model.");
+
+ setLibrary(DEFAULT_LIBRARY);
+
+ CliOption library = new CliOption(CodegenConstants.LIBRARY, "library template (sub-template) to use");
+ library.setDefault(DEFAULT_LIBRARY);
+ library.setEnum(supportedLibraries);
+ library.setDefault(DEFAULT_LIBRARY);
+ cliOptions.add(library);
+ }
+
+ @Override
+ public void processOpts() {
+
+ super.processOpts();
+
+ importMapping.put("OffsetDateTime", "java.time.OffsetDateTime");
+ additionalProperties.put("dateLibrary", "java8");
+ additionalProperties.put("jackson", "true");
+ additionalProperties.put("apiVersion", apiVersion);
+ additionalProperties.put("mainClassPackage", mainClassPackage);
+ additionalProperties.put("camelcase", new CamelCaseLambda());
+
+ supportingFiles.add(new SupportingFile("pom.mustache",
+ "",
+ "pom.xml")
+ );
+ supportingFiles.add(new SupportingFile("README.mustache",
+ "",
+ "README.md")
+ );
+
+ supportingFiles.add(new SupportingFile("Application.mustache",
+ mainClassFolder(),
+ "Application.java")
+ );
+
+ supportingFiles.add(new SupportingFile("log4j2.mustache",
+ resourcesFolder,
+ "log4j2.xml")
+ );
+ supportingFiles.add(new SupportingFile("microservice.mustache",
+ resourcesFolder,
+ "microservice.yaml")
+ );
+ }
+
+ @Override
+ public Map<String, Object> postProcessModelsEnum(Map<String, Object> objs) {
+ objs = super.postProcessModelsEnum(objs);
+ SpringCodegen springCodegen = new SpringCodegen();
+ return springCodegen.postProcessModelsEnum(objs);
+ }
+
+ @Override
+ public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
+ SpringCodegen springCodegen = new SpringCodegen();
+ return springCodegen.postProcessOperations(objs);
+ }
+
+ @Override
+ public String toApiName(String name) {
+ if (name.length() == 0) {
+ return "DefaultController";
+ }
+
+ String apiName = (String) additionalProperties.get("apiName");
+ if (apiName != null) {
+ return apiName;
+ }
+
+ return initialCaps(name) + "Controller";
+ }
+
+ private String mainClassFolder() {
+ return sourceFolder + File.separator + mainClassPackage.replace(".", File.separator);
+ }
+}
\ No newline at end of file
diff --git a/code-generator/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig b/code-generator/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig
new file mode 100755
index 0000000..9e194db
--- /dev/null
+++ b/code-generator/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig
@@ -0,0 +1,18 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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
+#
+# http://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.
+#
+
+org.apache.servicecomb.toolkit.codegen.ServiceCombProviderCodegen
diff --git a/code-generator/src/main/resources/ServiceCombProvider/README.mustache b/code-generator/src/main/resources/ServiceCombProvider/README.mustache
new file mode 100755
index 0000000..2258a49
--- /dev/null
+++ b/code-generator/src/main/resources/ServiceCombProvider/README.mustache
@@ -0,0 +1,20 @@
+## Welcome to use ServiceComb Java Chassis
+This project(module) is generate by *org.apache.servicecomb.archetypes:business-service-springmvc-archetype*, it use **springmvc provider** to develop service producer.
+
+### More works can be done further:
+1. Modify "HelloImpl", add your business service logic, or create some new producers to provide your services. More details can be found : http://servicecomb.apache.org/users/develop-with-springmvc/
+2. Modify "microservice.yaml", change APPLICATION_ID, service_description.name, version, and service center address, endpoints publish address etc. More details can be found : http://servicecomb.apache.org/users/service-definition/
+3. Modify setting value of "mainClass" in pom.xml for package.
+
+### Package your service
+Under project(module) root folder, run
+```bash
+mvn package
+```
+Then you can get outputs in target folder:
+- lib : contains all dependencies jars
+- xxxxxx-{version}.jar
+```bash
+java -jar xxxxxx-{version}.jar
+```
+*Notice: If you need to modify config setting in "microservice.yaml" like service center address but don't want repackage the executable jar, **you can direct place a new "microservice.yaml" file in same folder, then settings will be overridden.***
\ No newline at end of file
diff --git a/code-generator/src/main/resources/ServiceCombProvider/enumClass.mustache b/code-generator/src/main/resources/ServiceCombProvider/enumClass.mustache
new file mode 100755
index 0000000..dfdada5
--- /dev/null
+++ b/code-generator/src/main/resources/ServiceCombProvider/enumClass.mustache
@@ -0,0 +1,43 @@
+ /**
+ * {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{{description}}}{{/description}}
+ */
+ public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} {
+
+ {{#gson}}
+ {{#allowableValues}}
+ {{#enumVars}}
+ @SerializedName({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
+ {{{name}}}({{{value}}}){{^-last}},
+ {{/-last}}{{#-last}};{{/-last}}
+ {{/enumVars}}
+ {{/allowableValues}}
+ {{/gson}}
+ {{^gson}}
+ {{#allowableValues}}
+ {{#enumVars}}
+ {{{name}}}({{{value}}}){{^-last}},
+ {{/-last}}{{#-last}};{{/-last}}
+ {{/enumVars}}
+ {{/allowableValues}}
+ {{/gson}}
+
+ private {{{datatype}}} value;
+
+ {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}({{{datatype}}} value) {
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(value);
+ }
+
+ public static {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} fromValue(String text) {
+ for ({{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) {
+ if (String.valueOf(b.value).equals(text)) {
+ return b;
+ }
+ }
+ return null;
+ }
+ }
\ No newline at end of file
diff --git a/code-generator/src/main/resources/ServiceCombProvider/enumOuterClass.mustache b/code-generator/src/main/resources/ServiceCombProvider/enumOuterClass.mustache
new file mode 100755
index 0000000..a5f0034
--- /dev/null
+++ b/code-generator/src/main/resources/ServiceCombProvider/enumOuterClass.mustache
@@ -0,0 +1,37 @@
+
+/**
+ * {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{{description}}}{{/description}}
+ */
+public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} {
+ {{#gson}}
+ {{#allowableValues}}{{#enumVars}}
+ @SerializedName({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
+ {{{name}}}({{{value}}}){{^-last}},
+ {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}{{/allowableValues}}
+ {{/gson}}
+ {{^gson}}
+ {{#allowableValues}}{{#enumVars}}
+ {{{name}}}({{{value}}}){{^-last}},
+ {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}{{/allowableValues}}
+ {{/gson}}
+
+ private {{{dataType}}} value;
+
+ {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}({{{dataType}}} value) {
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(value);
+ }
+
+ public static {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} fromValue(String text) {
+ for ({{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} b : {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}.values()) {
+ if (String.valueOf(b.value).equals(text)) {
+ return b;
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/code-generator/src/main/resources/ServiceCombProvider/generatedAnnotation.mustache b/code-generator/src/main/resources/ServiceCombProvider/generatedAnnotation.mustache
new file mode 100755
index 0000000..49110fc
--- /dev/null
+++ b/code-generator/src/main/resources/ServiceCombProvider/generatedAnnotation.mustache
@@ -0,0 +1 @@
+@javax.annotation.Generated(value = "{{generatorClass}}", date = "{{generatedDate}}")
\ No newline at end of file
diff --git a/code-generator/src/main/resources/ServiceCombProvider/libraries/SpringMvc/Application.mustache b/code-generator/src/main/resources/ServiceCombProvider/libraries/SpringMvc/Application.mustache
new file mode 100755
index 0000000..aef3762
--- /dev/null
+++ b/code-generator/src/main/resources/ServiceCombProvider/libraries/SpringMvc/Application.mustache
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ * http://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.
+ */
+
+package {{mainClassPackage}};
+
+import org.apache.servicecomb.foundation.common.utils.BeanUtils;
+
+public class Application {
+
+ public static void main(String[] args) throws Exception {
+ System.setProperty("local.registry.file", "notExistJustForceLocal");
+ BeanUtils.init();
+ }
+}
\ No newline at end of file
diff --git a/code-generator/src/main/resources/ServiceCombProvider/libraries/SpringMvc/api.mustache b/code-generator/src/main/resources/ServiceCombProvider/libraries/SpringMvc/api.mustache
new file mode 100755
index 0000000..d303827
--- /dev/null
+++ b/code-generator/src/main/resources/ServiceCombProvider/libraries/SpringMvc/api.mustache
@@ -0,0 +1,42 @@
+package {{apiPackage}};
+
+import {{modelPackage}}.*;
+
+{{#imports}}import {{import}};
+{{/imports}}
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RequestPart;
+import org.springframework.web.multipart.MultipartFile;
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+import java.util.List;
+import java.util.Map;
+import static org.springframework.http.MediaType.*;
+
+@RestSchema(schemaId = "{{#camelcase}}{{classname}}{{/camelcase}}")
+@RequestMapping(value = "/", produces = {APPLICATION_JSON_VALUE})
+{{>generatedAnnotation}}
+{{#operations}}
+public class {{classname}} {
+ {{#operation}}
+
+ @RequestMapping(value = "{{path}}",
+ {{#hasProduces}}produces = { {{#produces}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }, {{/hasProduces}}
+ {{#hasConsumes}}consumes = { {{#consumes}}"{{mediaType}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} },{{/hasConsumes}}
+ method = RequestMethod.{{httpMethod}})
+ public ResponseEntity<{{>returnTypes}}> {{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},
+ {{/hasMore}}{{/allParams}}) {
+ // do some magic!
+ return new ResponseEntity<{{>returnTypes}}>(HttpStatus.OK);
+ }
+
+ {{/operation}}
+}
+{{/operations}}
\ No newline at end of file
diff --git a/code-generator/src/main/resources/ServiceCombProvider/libraries/SpringMvc/api_test.mustache b/code-generator/src/main/resources/ServiceCombProvider/libraries/SpringMvc/api_test.mustache
new file mode 100755
index 0000000..1633203
--- /dev/null
+++ b/code-generator/src/main/resources/ServiceCombProvider/libraries/SpringMvc/api_test.mustache
@@ -0,0 +1,102 @@
+package {{package}};
+{{#imports}}import {{import}};
+{{/imports}}
+import java.util.*;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+
+import static org.junit.Assert.assertEquals;
+
+public class {{classname}}ContractTest {
+ @Autowired
+ private {{classname}} api;
+
+ private static final String NAME_LARRY_JSON = "{\"name\": \"larry\"}";
+
+ @Rule
+ public TestFailureProviderRule mockTestProvider = new TestFailureProviderRule("{{#camelcase}}{{classname}}{{/camelcase}}Provider", this);
+
+ @Pact(provider="{{#camelcase}}{{classname}}{{/camelcase}}Provider", consumer="{{#camelcase}}{{classname}}{{/camelcase}}Consumer")
+ public RequestResponsePact createFragment(PactDslWithProvider builder) {
+
+{{#operations}}
+ {{#operation}}
+ {{#hasHeaderParams}}
+ Map<String, String> {{operationId}}RequestHeaders = new HashMap<String, String>();
+ {{/hasHeaderParams}}
+ {{/operation}}
+{{/operations}}
+{{#operations}}
+ {{#operation}}
+ {{#responseHeaders}}
+ Map<String, String> {{operationId}}ResponseHeaders = new HashMap<String, String>();
+ {{/responseHeaders}}
+ {{/operation}}
+{{/operations}}
+
+ return builder
+{{#operations}}
+ {{#operation}}
+ .uponReceiving("{{summary}}")
+ .path("{{path}}")
+ .method("{{httpMethod}}")
+ {{#hasHeaderParams}}
+ .headers({{operationId}}RequestHeaders)
+ {{/hasHeaderParams}}
+ .willRespondWith()
+ .status(200)
+ {{#responseHeaders}}
+ .headers({{operationId}}ResponseHeaders)
+ {{/responseHeaders}}
+ .body("{\"responsetest\": true, \"name\": \"harry\"}")
+ {{/operation}}
+{{/operations}}
+ .toPact();
+ }
+
+
+ @Test
+ @PactVerification({"{{#camelcase}}{{classname}}{{/camelcase}}Provider"})
+ public void allPass() throws IOException {
+ mockTestProvider.validateResultWith((result, t) -> {
+ assertThat(t, is(nullValue()));
+ assertThat(result, is(PactVerificationResult.Ok.INSTANCE));
+ });
+ doTest("/", NAME_LARRY_JSON);
+ }
+
+ private void doTest(String path, String json) throws IOException {
+ ConsumerClient consumerClient = new ConsumerClient(mockTestProvider.getUrl());
+ consumerClient.options("/second");
+ try {
+ consumerClient.getAsMap(path, "");
+ } catch (IOException e) {
+ }
+ try {
+ new ConsumerClient(mockTestProvider2.getUrl()).putAsMap("/", json);
+ } catch (IOException e) {
+ }
+ }
+
+/*
+ @Test
+ public void {{operationId}}Test() throws Exception {
+ {{#allParams}}
+ {{^isFile}}
+ {{{dataType}}} {{paramName}} = {{{example}}};
+ {{/isFile}}
+ {{#isFile}}
+ org.springframework.web.multipart.MultipartFile {{paramName}} = null;
+ {{/isFile}}
+ {{/allParams}}
+ ResponseEntity<{{>returnTypes}}> responseEntity = api.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
+ assertEquals(HttpStatus.NOT_IMPLEMENTED, responseEntity.getStatusCode());
+ }
+*/
+}
\ No newline at end of file
diff --git a/code-generator/src/main/resources/ServiceCombProvider/libraries/SpringMvc/bodyParams.mustache b/code-generator/src/main/resources/ServiceCombProvider/libraries/SpringMvc/bodyParams.mustache
new file mode 100755
index 0000000..5932bd1
--- /dev/null
+++ b/code-generator/src/main/resources/ServiceCombProvider/libraries/SpringMvc/bodyParams.mustache
@@ -0,0 +1 @@
+{{#isBodyParam}}@RequestBody {{{dataType}}} {{paramName}}{{/isBodyParam}}
\ No newline at end of file
diff --git a/code-generator/src/main/resources/ServiceCombProvider/libraries/SpringMvc/formParams.mustache b/code-generator/src/main/resources/ServiceCombProvider/libraries/SpringMvc/formParams.mustache
new file mode 100755
index 0000000..336c14d
--- /dev/null
+++ b/code-generator/src/main/resources/ServiceCombProvider/libraries/SpringMvc/formParams.mustache
@@ -0,0 +1,2 @@
+{{#isFormParam}}{{#notFile}}
+@RequestPart(value="{{paramName}}"{{#required}}, required=true{{/required}}{{^required}}, required=false{{/required}}) {{{dataType}}} {{paramName}}{{/notFile}}{{#isFile}}@RequestPart("file") MultipartFile {{baseName}}{{/isFile}}{{/isFormParam}}
\ No newline at end of file
diff --git a/code-generator/src/main/resources/ServiceCombProvider/libraries/SpringMvc/headerParams.mustache b/code-generator/src/main/resources/ServiceCombProvider/libraries/SpringMvc/headerParams.mustache
new file mode 100755
index 0000000..7c3018b
--- /dev/null
+++ b/code-generator/src/main/resources/ServiceCombProvider/libraries/SpringMvc/headerParams.mustache
@@ -0,0 +1 @@
+{{#isHeaderParam}}@RequestHeader(value="{{paramName}}", required={{#required}}true{{/required}}{{^required}}false{{/required}}) {{{dataType}}} {{paramName}}{{/isHeaderParam}}
\ No newline at end of file
diff --git a/code-generator/src/main/resources/ServiceCombProvider/libraries/SpringMvc/pathParams.mustache b/code-generator/src/main/resources/ServiceCombProvider/libraries/SpringMvc/pathParams.mustache
new file mode 100755
index 0000000..5152be0
--- /dev/null
+++ b/code-generator/src/main/resources/ServiceCombProvider/libraries/SpringMvc/pathParams.mustache
@@ -0,0 +1 @@
+{{#isPathParam}}@PathVariable("{{paramName}}") {{{dataType}}} {{paramName}}{{/isPathParam}}
\ No newline at end of file
diff --git a/code-generator/src/main/resources/ServiceCombProvider/libraries/SpringMvc/pom.mustache b/code-generator/src/main/resources/ServiceCombProvider/libraries/SpringMvc/pom.mustache
new file mode 100755
index 0000000..c119ee1
--- /dev/null
+++ b/code-generator/src/main/resources/ServiceCombProvider/libraries/SpringMvc/pom.mustache
@@ -0,0 +1,104 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>{{groupId}}</groupId>
+ <artifactId>{{artifactId}}</artifactId>
+ <packaging>jar</packaging>
+ <name>{{artifactId}}</name>
+ <version>{{artifactVersion}}</version>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <java-chassis.version>1.2.0</java-chassis.version>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>java-chassis-dependencies</artifactId>
+ <version>${java-chassis.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>transport-rest-vertx</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>transport-highway</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>provider-springmvc</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-slf4j-impl</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ </dependency>
+
+ </dependencies>
+
+ <!--for package and deploy-->
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.6</version>
+ <configuration>
+ <archive>
+ <manifest>
+ <addClasspath>true</addClasspath>
+ <classpathPrefix>lib/</classpathPrefix>
+ <!--change to your main class-->
+ <mainClass>${package}.Application</mainClass>
+ </manifest>
+ <manifestEntries>
+ <Class-Path>. </Class-Path>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy-dependencies</id>
+ <phase>package</phase>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>target/lib</outputDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.1</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+
+ </plugins>
+ </build>
+
+</project>
\ No newline at end of file
diff --git a/code-generator/src/main/resources/ServiceCombProvider/libraries/SpringMvc/queryParams.mustache b/code-generator/src/main/resources/ServiceCombProvider/libraries/SpringMvc/queryParams.mustache
new file mode 100755
index 0000000..6ce8e14
--- /dev/null
+++ b/code-generator/src/main/resources/ServiceCombProvider/libraries/SpringMvc/queryParams.mustache
@@ -0,0 +1 @@
+{{#isQueryParam}}@RequestParam(value = "{{paramName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}) {{{dataType}}} {{paramName}}{{/isQueryParam}}
\ No newline at end of file
diff --git a/code-generator/src/main/resources/ServiceCombProvider/log4j2.mustache b/code-generator/src/main/resources/ServiceCombProvider/log4j2.mustache
new file mode 100755
index 0000000..e43e15b
--- /dev/null
+++ b/code-generator/src/main/resources/ServiceCombProvider/log4j2.mustache
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You 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
+ ~
+ ~ http://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.
+ -->
+
+<!--this is sample configuration, please modify as your wish-->
+<configuration>
+ <Properties>
+ <Property name="log_path">./target/log</Property>
+ </Properties>
+
+ <Appenders>
+ <Console name="Console" target="SYSTEM_OUT">
+ <PatternLayout pattern="[%d][%t][%p][%c:%L] %m%n"/>
+ </Console>
+ <RollingFile name="DailyRollingFile" fileName="${log_path}/output.log"
+ filePattern="${log_path}/%d{yyyy-MM-dd}.log">
+ <PatternLayout pattern="[%d][%t][%p][%c:%L] %m%n"/>
+ <TimeBasedTriggeringPolicy interval="1"/>
+ </RollingFile>
+ </Appenders>
+ <Loggers>
+ <Root level="info">
+ <AppenderRef ref="Console"/>
+ <AppenderRef ref="DailyRollingFile"/>
+ </Root>
+ </Loggers>
+</configuration>
\ No newline at end of file
diff --git a/code-generator/src/main/resources/ServiceCombProvider/microservice.mustache b/code-generator/src/main/resources/ServiceCombProvider/microservice.mustache
new file mode 100755
index 0000000..67ad88a
--- /dev/null
+++ b/code-generator/src/main/resources/ServiceCombProvider/microservice.mustache
@@ -0,0 +1,43 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You 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
+##
+## http://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.
+## ---------------------------------------------------------------------------
+
+#More details can be found :
+# 1.http://servicecomb.apache.org/users/service-definition/
+# 2.http://servicecomb.apache.org/users/service-configurations/
+# 3.http://servicecomb.apache.org/users/communicate-protocol/
+
+#Indicates an application name
+APPLICATION_ID: business
+service_description:
+#Indicates a microservice name
+#The microservice name should be unique within an application.
+#The name can contain digits, uppercase and lowercase letters, hyphens(-), underscores(_), and periods(.); and can neither start nor end with punctuations.
+#The naming rule is as follows: ^[a-zA-Z0-9]+$|^[a-zA-Z0-9][a-zA-Z0-9_-.]*[a-zA-Z0-9]$.
+ name: business-service
+#Indicates a service version
+ version: 1.0.0
+servicecomb:
+ service:
+ #Specifies the service center IP address.
+ registry:
+ address: http://127.0.0.1:30100
+ #Specifies the rest transport listening IP address.
+ rest:
+ address: 0.0.0.0:8080
+ #Specifies the highway transport listening IP address.
+ highway:
+ address: 0.0.0.0:7070
\ No newline at end of file
diff --git a/code-generator/src/main/resources/ServiceCombProvider/model.mustache b/code-generator/src/main/resources/ServiceCombProvider/model.mustache
new file mode 100755
index 0000000..1923ac6
--- /dev/null
+++ b/code-generator/src/main/resources/ServiceCombProvider/model.mustache
@@ -0,0 +1,27 @@
+package {{package}};
+
+import java.util.Objects;
+{{#imports}}import {{import}};
+{{/imports}}
+{{#serializableModel}}
+import java.io.Serializable;
+{{/serializableModel}}
+{{#useBeanValidation}}
+import org.springframework.validation.annotation.Validated;
+import javax.validation.Valid;
+import javax.validation.constraints.*;
+{{/useBeanValidation}}
+{{#withXml}}
+import javax.xml.bind.annotation.*;
+{{/withXml}}
+
+{{#models}}
+{{#model}}
+{{#isEnum}}
+{{>enumOuterClass}}
+{{/isEnum}}
+{{^isEnum}}
+{{>pojo}}
+{{/isEnum}}
+{{/model}}
+{{/models}}
\ No newline at end of file
diff --git a/code-generator/src/main/resources/ServiceCombProvider/pojo.mustache b/code-generator/src/main/resources/ServiceCombProvider/pojo.mustache
new file mode 100755
index 0000000..5c3f7f3
--- /dev/null
+++ b/code-generator/src/main/resources/ServiceCombProvider/pojo.mustache
@@ -0,0 +1,134 @@
+/**
+ * {{#description}}{{.}}{{/description}}{{^description}}{{classname}}{{/description}}
+ */
+{{#useBeanValidation}}@Validated{{/useBeanValidation}}
+{{>generatedAnnotation}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{>xmlAnnotation}}
+public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} {{#serializableModel}}implements Serializable{{/serializableModel}} {
+{{#serializableModel}}
+ private static final long serialVersionUID = 1L;
+
+{{/serializableModel}}
+ {{#vars}}
+ {{#isEnum}}
+ {{^isContainer}}
+{{>enumClass}}
+ {{/isContainer}}
+ {{/isEnum}}
+ {{#items.isEnum}}
+ {{#items}}
+ {{^isContainer}}
+{{>enumClass}}
+ {{/isContainer}}
+ {{/items}}
+ {{/items.isEnum}}
+ {{#gson}}
+ @SerializedName("{{baseName}}")
+ {{/gson}}
+ {{#isContainer}}
+ {{#useBeanValidation}}@Valid{{/useBeanValidation}}
+ private {{{datatypeWithEnum}}} {{name}}{{#required}} = {{{defaultValue}}}{{/required}}{{^required}} = null{{/required}};
+ {{/isContainer}}
+ {{^isContainer}}
+ private {{{datatypeWithEnum}}} {{name}} = {{{defaultValue}}};
+ {{/isContainer}}
+
+ {{/vars}}
+ {{#vars}}
+ public {{classname}} {{name}}({{{datatypeWithEnum}}} {{name}}) {
+ this.{{name}} = {{name}};
+ return this;
+ }
+ {{#isListContainer}}
+
+ public {{classname}} add{{nameInCamelCase}}Item({{{items.datatypeWithEnum}}} {{name}}Item) {
+ {{^required}}
+ if (this.{{name}} == null) {
+ this.{{name}} = {{{defaultValue}}};
+ }
+ {{/required}}
+ this.{{name}}.add({{name}}Item);
+ return this;
+ }
+ {{/isListContainer}}
+ {{#isMapContainer}}
+
+ public {{classname}} put{{nameInCamelCase}}Item(String key, {{{items.datatypeWithEnum}}} {{name}}Item) {
+ {{^required}}
+ if (this.{{name}} == null) {
+ this.{{name}} = {{{defaultValue}}};
+ }
+ {{/required}}
+ this.{{name}}.put(key, {{name}}Item);
+ return this;
+ }
+ {{/isMapContainer}}
+
+ /**
+ {{#description}}
+ * {{{description}}}
+ {{/description}}
+ {{^description}}
+ * Get {{name}}
+ {{/description}}
+ {{#minimum}}
+ * minimum: {{minimum}}
+ {{/minimum}}
+ {{#maximum}}
+ * maximum: {{maximum}}
+ {{/maximum}}
+ * @return {{name}}
+ **/
+ {{#vendorExtensions.extraAnnotation}}
+ {{{vendorExtensions.extraAnnotation}}}
+ {{/vendorExtensions.extraAnnotation}}
+{{#useBeanValidation}}{{>beanValidation}}{{/useBeanValidation}} public {{{datatypeWithEnum}}} {{#isBoolean}}is{{/isBoolean}}{{getter}}() {
+ return {{name}};
+ }
+
+ public void {{setter}}({{{datatypeWithEnum}}} {{name}}) {
+ this.{{name}} = {{name}};
+ }
+
+ {{/vars}}
+
+ @Override
+ public boolean equals(java.lang.Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }{{#hasVars}}
+ {{classname}} {{classVarName}} = ({{classname}}) o;
+ return {{#vars}}Objects.equals(this.{{name}}, {{classVarName}}.{{name}}){{#hasMore}} &&
+ {{/hasMore}}{{/vars}}{{#parent}} &&
+ super.equals(o){{/parent}};{{/hasVars}}{{^hasVars}}
+ return true;{{/hasVars}}
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash({{#vars}}{{name}}{{#hasMore}}, {{/hasMore}}{{/vars}}{{#parent}}{{#hasVars}}, {{/hasVars}}super.hashCode(){{/parent}});
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("class {{classname}} {\n");
+ {{#parent}}sb.append(" ").append(toIndentedString(super.toString())).append("\n");{{/parent}}
+ {{#vars}}sb.append(" {{name}}: ").append(toIndentedString({{name}})).append("\n");
+ {{/vars}}sb.append("}");
+ return sb.toString();
+ }
+
+ /**
+ * Convert the given object to string with each line indented by 4 spaces
+ * (except the first line).
+ */
+ private String toIndentedString(java.lang.Object o) {
+ if (o == null) {
+ return "null";
+ }
+ return o.toString().replace("\n", "\n ");
+ }
+}
\ No newline at end of file
diff --git a/code-generator/src/main/resources/ServiceCombProvider/returnTypes.mustache b/code-generator/src/main/resources/ServiceCombProvider/returnTypes.mustache
new file mode 100755
index 0000000..63acd6f
--- /dev/null
+++ b/code-generator/src/main/resources/ServiceCombProvider/returnTypes.mustache
@@ -0,0 +1 @@
+{{#returnContainer}}{{#isMapContainer}}Map<String, {{{returnType}}}>{{/isMapContainer}}{{#isListContainer}}List<{{returnType}}>{{/isListContainer}}{{/returnContainer}}{{^returnContainer}}{{{returnType}}}{{/returnContainer}}
\ No newline at end of file
diff --git a/code-generator/src/main/resources/ServiceCombProvider/typeInfoAnnotation.mustache b/code-generator/src/main/resources/ServiceCombProvider/typeInfoAnnotation.mustache
new file mode 100755
index 0000000..09be1ca
--- /dev/null
+++ b/code-generator/src/main/resources/ServiceCombProvider/typeInfoAnnotation.mustache
@@ -0,0 +1,7 @@
+{{#jackson}}
+@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "{{discriminator}}", visible = true )
+@JsonSubTypes({
+ {{#children}}
+ @JsonSubTypes.Type(value = {{classname}}.class, name = "{{^vendorExtensions.x-discriminator-value}}{{name}}{{/vendorExtensions.x-discriminator-value}}{{#vendorExtensions.x-discriminator-value}}{{{vendorExtensions.x-discriminator-value}}}{{/vendorExtensions.x-discriminator-value}}"),
+ {{/children}}
+}){{/jackson}}
\ No newline at end of file
diff --git a/code-generator/src/main/resources/ServiceCombProvider/xmlAnnotation.mustache b/code-generator/src/main/resources/ServiceCombProvider/xmlAnnotation.mustache
new file mode 100755
index 0000000..03586da
--- /dev/null
+++ b/code-generator/src/main/resources/ServiceCombProvider/xmlAnnotation.mustache
@@ -0,0 +1,6 @@
+{{#withXml}}
+{{#jackson}}
+@JacksonXmlRootElement({{#xmlNamespace}}namespace="{{xmlNamespace}}", {{/xmlNamespace}}localName = "{{#xmlName}}{{xmlName}}{{/xmlName}}{{^xmlName}}{{classname}}{{/xmlName}}")
+{{/jackson}}
+@XmlRootElement({{#xmlNamespace}}namespace="{{xmlNamespace}}", {{/xmlNamespace}}name = "{{#xmlName}}{{xmlName}}{{/xmlName}}{{^xmlName}}{{classname}}{{/xmlName}}")
+@XmlAccessorType(XmlAccessType.FIELD){{/withXml}}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100755
index 0000000..ca48b94
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You 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
+ ~
+ ~ http://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.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>toolkit</artifactId>
+ <version>0.1.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <name>Microservice development toolkit</name>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <modules>
+ <module>code-generator</module>
+ <module>toolkit-cli</module>
+ </modules>
+
+</project>
diff --git a/toolkit-cli/dependency-reduced-pom.xml b/toolkit-cli/dependency-reduced-pom.xml
new file mode 100644
index 0000000..33bd7aa
--- /dev/null
+++ b/toolkit-cli/dependency-reduced-pom.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <artifactId>toolkit</artifactId>
+ <groupId>org.apache.servicecomb</groupId>
+ <version>0.1.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>toolkit-cli</artifactId>
+ <build>
+ <resources>
+ <resource>
+ <filtering>true</filtering>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.1</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-shade-plugin</artifactId>
+ <version>2.4.1</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <filters>
+ <filter>
+ <artifact>*:*</artifact>
+ <excludes>
+ <exclude>META-INF/*.SF</exclude>
+ <exclude>META-INF/*.DSA</exclude>
+ <exclude>META-INF/*.RSA</exclude>
+ </excludes>
+ </filter>
+ </filters>
+ <transformers>
+ <transformer>
+ <mainClass>org.apache.servicecomb.toolkit.cli.ToolkitMain</mainClass>
+ </transformer>
+ <transformer>
+ <resource>META-INF/spring.handlers</resource>
+ </transformer>
+ <transformer>
+ <resource>META-INF/spring.schemas</resource>
+ </transformer>
+ </transformers>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
+
diff --git a/toolkit-cli/pom.xml b/toolkit-cli/pom.xml
new file mode 100755
index 0000000..570dde4
--- /dev/null
+++ b/toolkit-cli/pom.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You 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
+ ~
+ ~ http://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.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>toolkit</artifactId>
+ <groupId>org.apache.servicecomb</groupId>
+ <version>0.1.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>toolkit-cli</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>io.airlift</groupId>
+ <artifactId>airline</artifactId>
+ <version>0.7</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>code-generator</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.1</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <version>2.4.1</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <filters>
+ <filter>
+ <artifact>*:*</artifact>
+ <excludes>
+ <exclude>META-INF/*.SF</exclude>
+ <exclude>META-INF/*.DSA</exclude>
+ <exclude>META-INF/*.RSA</exclude>
+ </excludes>
+ </filter>
+ </filters>
+ <transformers>
+ <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+ <mainClass>org.apache.servicecomb.toolkit.cli.ToolkitMain</mainClass>
+ </transformer>
+ <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+ <resource>META-INF/spring.handlers</resource>
+ </transformer>
+ <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+ <resource>META-INF/spring.schemas</resource>
+ </transformer>
+ </transformers>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </build>
+</project>
diff --git a/toolkit-cli/src/main/java/org/apache/servicecomb/toolkit/cli/CodeGenerate.java b/toolkit-cli/src/main/java/org/apache/servicecomb/toolkit/cli/CodeGenerate.java
new file mode 100755
index 0000000..c9506ce
--- /dev/null
+++ b/toolkit-cli/src/main/java/org/apache/servicecomb/toolkit/cli/CodeGenerate.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ * http://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.
+ */
+
+package org.apache.servicecomb.toolkit.cli;
+
+import static org.apache.commons.lang3.StringUtils.isNotEmpty;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+
+import org.apache.servicecomb.toolkit.codegen.DefaultCodeGenerator;
+
+import io.airlift.airline.Command;
+import io.airlift.airline.Option;
+import io.swagger.codegen.config.CodegenConfigurator;
+
+@Command(name = "generate", description = "CodeGenerate code with chosen lang")
+public class CodeGenerate implements Runnable {
+
+ @Option(name = {"--programming-model"}, title = "programming model", required = false,
+ description = "programming model, equals to --library")
+ private String programmingModel;
+
+ @Option(name = {"-i", "--input-spec"}, title = "spec file", required = true,
+ description = "location of the swagger spec, as URL or file (required)")
+ private String spec;
+
+ @Option(name = {"-o", "--output"}, title = "output directory",
+ description = "where to write the generated files (current dir by default)")
+ private String output = "";
+
+ @Option(name = {"--group-id"}, title = "group id", description = "groupId in generated pom.xml")
+ private String groupId;
+
+ @Option(name = {"--artifact-id"}, title = "artifact id",
+ description = "artifact version in generated pom.xml")
+ private String artifactId;
+
+ @Option(name = {"--artifact-version"}, title = "artifact version",
+ description = "artifact version in generated pom.xml")
+ private String artifactVersion;
+
+ @Option(name = {"--library"}, title = "library", description = "library template (sub-template)")
+ private String library;
+
+ @Option(name = {"-l", "--lang"}, title = "language",
+ description = "client language to generate (maybe class name in classpath, required)")
+ private String lang = "ServiceCombProvider";
+
+
+ @Override
+ public void run() {
+
+ CodegenConfigurator configurator = new CodegenConfigurator();
+
+ configurator.setOutputDir(output)
+ .setGroupId(groupId)
+ .setArtifactId(artifactId)
+ .setArtifactVersion(artifactVersion)
+ .setLibrary(library)
+ .setLibrary(programmingModel)
+ .setLang(lang);
+
+ if (isNotEmpty(spec)) {
+
+ File contractFile = new File(spec);
+
+ // has many contracts
+ if (contractFile.isDirectory()) {
+
+ try {
+ Files.walkFileTree(Paths.get(contractFile.toURI()), new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+
+ configurator.setInputSpec(file.toFile().getCanonicalPath())
+ .addAdditionalProperty("apiName", file.toFile().getName().split("\\.")[0]);
+
+ new DefaultCodeGenerator().opts(configurator).generate();
+
+ return super.visitFile(file, attrs);
+ }
+ });
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ } else {
+ // one contract
+ configurator.setInputSpec(spec);
+ new DefaultCodeGenerator().opts(configurator).generate();
+ }
+ }
+ }
+}
diff --git a/toolkit-cli/src/main/java/org/apache/servicecomb/toolkit/cli/ToolkitMain.java b/toolkit-cli/src/main/java/org/apache/servicecomb/toolkit/cli/ToolkitMain.java
new file mode 100755
index 0000000..32795ef
--- /dev/null
+++ b/toolkit-cli/src/main/java/org/apache/servicecomb/toolkit/cli/ToolkitMain.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ * http://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.
+ */
+
+package org.apache.servicecomb.toolkit.cli;
+
+import java.io.IOException;
+import java.util.Optional;
+import java.util.Properties;
+
+import io.airlift.airline.Cli;
+import io.airlift.airline.Help;
+
+public class ToolkitMain {
+
+ private static String projectVersion;
+
+ @SuppressWarnings("unchecked")
+ public static void main(String[] args) {
+
+ initialProjectVersion();
+
+ Cli.CliBuilder<Runnable> builder = Cli.<Runnable>builder("java -jar assistant-cli-" + projectVersion + ".jar");
+ builder.withDescription(
+ "ServiceComb code generator CLI (version " + projectVersion + "). More info on servicecomb.apache.org");
+ builder.withDefaultCommand(Help.class);
+ builder.withCommands(CodeGenerate.class, Help.class);
+ Runnable cmd = builder.build().parse(args);
+
+ cmd.run();
+ }
+
+ private static void initialProjectVersion() {
+
+ Properties properties = new Properties();
+ try {
+ properties.load(ToolkitMain.class.getClassLoader().getResourceAsStream("application.properties"));
+
+ projectVersion = Optional.ofNullable(properties.getProperty("version"))
+ .orElse("unknown");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/toolkit-cli/src/main/resources/application.properties b/toolkit-cli/src/main/resources/application.properties
new file mode 100755
index 0000000..e5683df
--- /dev/null
+++ b/toolkit-cli/src/main/resources/application.properties
@@ -0,0 +1 @@
+version=${project.version}
\ No newline at end of file