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 <bin...@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 <bin...@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