feat: Add Java Dubbo code generator for Apache Dubbo microservices (#21968)

* feat: add Apache Dubbo code generator with multi-registry support

- Add comprehensive Dubbo microservice code generator
- Support Zookeeper and Nacos registries with auto-dependency selection
- Implement version-aware dependency management (Dubbo 3.2 vs 3.3+)
- Generate service interfaces, implementations, and Spring Boot REST controllers
- Include complete Spring Boot application structure with configuration
- Add detailed documentation and usage examples
- Support async operations and generic response wrappers
- Provide flexible configuration options for packages, versions, and features

* feat: Add dubbo sample with CI validation

Adds a new sample generator configuration for dubbo.

The existing GitHub workflow for Java samples is updated to build and test this new sample automatically.

* fix: fix Dubbo protocol extension issue in test environment

- Set registry address to N/A to avoid ZooKeeper dependency
- Change protocol from 'triple' to 'tri' to resolve extension loading error

* various fix to java dubbo server generator

* update doc

* update readme

---------

Co-authored-by: redoom <gyklcy@iCloud.com>
This commit is contained in:
William Cheng 2025-09-16 01:51:12 +08:00 committed by GitHub
parent c30fb413bb
commit b7749712b8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
42 changed files with 4135 additions and 0 deletions

View File

@ -0,0 +1,39 @@
name: Samples Java Dubbo
on:
push:
paths:
- 'samples/server/petstore/java-dubbo/**'
pull_request:
paths:
- 'samples/server/petstore/java-dubbo/**'
jobs:
build:
name: Build Java Dubbo
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sample:
# servers
- samples/server/petstore/java-dubbo
steps:
- uses: actions/checkout@v5
- uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: 17
- name: Cache maven dependencies
uses: actions/cache@v4
env:
cache-name: maven-repository
with:
path: |
~/.m2
key: ${{ runner.os }}-${{ github.job }}-${{ env.cache-name }}-${{ hashFiles('**/pom.xml') }}
- name: Build
working-directory: ${{ matrix.sample }}
run: mvn clean package --no-transfer-progress -DskipTests
# add -DskipTests as the app compiles but fails to start
#run: mvn clean package --no-transfer-progress

View File

@ -1143,6 +1143,7 @@ Here is a list of template creators:
* Haskell Servant: @algas
* Haskell Yesod: @yotsuya
* Java Camel: @carnevalegiacomo
* Java Dubbo: @redoom
* Java MSF4J: @sanjeewa-malalgoda
* Java Spring Boot: @diyfr
* Java Undertow: @stevehu

View File

@ -0,0 +1,15 @@
generatorName: java-dubbo
outputDir: samples/server/petstore/java-dubbo
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/java-dubbo
additionalProperties:
hideGenerationTimestamp: "true"
artifactId: openapi-dubbo-server-petstore
basePackage: "org.openapitools.example"
title: "OpenAPI Petstore"
serviceInterface: true
serviceImplementation: true
useTags: true
dubboVersion: "3.2.18"
javaVersion: "17"
registryAddress: "zookeeper://127.0.0.1:2181"

View File

@ -106,6 +106,7 @@ The following generators are available:
* [haskell](generators/haskell.md)
* [haskell-yesod (beta)](generators/haskell-yesod.md)
* [java-camel](generators/java-camel.md)
* [java-dubbo (beta)](generators/java-dubbo.md)
* [java-helidon-server (beta)](generators/java-helidon-server.md)
* [java-inflector](generators/java-inflector.md)
* [java-micronaut-server (beta)](generators/java-micronaut-server.md)

View File

@ -0,0 +1,351 @@
---
title: Documentation for the java-dubbo Generator
---
## METADATA
| Property | Value | Notes |
| -------- | ----- | ----- |
| generator name | java-dubbo | pass this to the generate command after -g |
| generator stability | BETA | |
| generator type | SERVER | |
| generator language | Java | |
| generator default templating engine | mustache | |
| helpTxt | Generates a Java Apache Dubbo server application. | |
## CONFIG OPTIONS
These options may be applied as additional-properties (cli) or configOptions (plugins). Refer to [configuration docs](https://openapi-generator.tech/docs/configuration) for more details.
| Option | Description | Values | Default |
| ------ | ----------- | ------ | ------- |
|additionalEnumTypeAnnotations|Additional annotations for enum type(class level annotations)| |null|
|additionalModelTypeAnnotations|Additional annotations for model type(class level annotations). List separated by semicolon(;) or new line (Linux or Windows)| |null|
|additionalOneOfTypeAnnotations|Additional annotations for oneOf interfaces(class level annotations). List separated by semicolon(;) or new line (Linux or Windows)| |null|
|allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false|
|apiPackage|package for generated api classes| |org.openapitools.api|
|artifactDescription|artifact description in generated pom.xml| |OpenAPI Java|
|artifactId|artifactId in generated pom.xml. This also becomes part of the generated library's filename| |openapi-dubbo|
|artifactUrl|artifact URL in generated pom.xml| |https://github.com/openapitools/openapi-generator|
|artifactVersion|artifact version in generated pom.xml. This also becomes part of the generated library's filename. If not provided, uses the version from the OpenAPI specification file. If that's also not present, uses the default value of the artifactVersion option.| |1.0.0|
|basePackage|base package (invokerPackage) for generated code| |org.openapitools|
|bigDecimalAsString|Treat BigDecimal values as Strings to avoid precision loss.| |false|
|booleanGetterPrefix|Set booleanGetterPrefix| |get|
|camelCaseDollarSign|Fix camelCase when starting with $ sign. when true : $Value when false : $value| |false|
|configPackage|configuration package for generated code| |org.openapitools.configuration|
|containerDefaultToNull|Set containers (array, set, map) default to null| |false|
|dateLibrary|Option. Date library to use|<dl><dt>**joda**</dt><dd>Joda (for legacy app only)</dd><dt>**legacy**</dt><dd>Legacy java.util.Date</dd><dt>**java8-localdatetime**</dt><dd>Java 8 using LocalDateTime (for legacy app only)</dd><dt>**java8**</dt><dd>Java 8 native JSR310 (preferred for jdk 1.8+)</dd></dl>|java8|
|developerEmail|developer email in generated pom.xml| |team@openapitools.org|
|developerName|developer name in generated pom.xml| |OpenAPI-Generator Contributors|
|developerOrganization|developer organization in generated pom.xml| |OpenAPITools.org|
|developerOrganizationUrl|developer organization URL in generated pom.xml| |http://openapitools.org|
|disableHtmlEscaping|Disable HTML escaping of JSON strings when using gson (needed to avoid problems with byte[] fields)| |false|
|disallowAdditionalPropertiesIfNotPresent|If false, the 'additionalProperties' implementation (set to true by default) is compliant with the OAS and JSON schema specifications. If true (default), keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.|<dl><dt>**false**</dt><dd>The 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications.</dd><dt>**true**</dt><dd>Keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.</dd></dl>|true|
|discriminatorCaseSensitive|Whether the discriminator value lookup should be case-sensitive or not. This option only works for Java API client| |true|
|dubboVersion|Dubbo version| |3.2.18|
|ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true|
|enumPropertyNaming|Naming convention for enum properties: 'MACRO_CASE', 'legacy' and 'original'| |MACRO_CASE|
|enumUnknownDefaultCase|If the server adds new enum cases, that are unknown by an old spec/client, the client will fail to parse the network response.With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the server sends an enum case that is not known by the client/spec, they can safely fallback to this case.|<dl><dt>**false**</dt><dd>No changes to the enum's are made, this is the default option.</dd><dt>**true**</dt><dd>With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the enum case sent by the server is not known by the client/spec, can safely be decoded to this case.</dd></dl>|false|
|generateBuilders|Whether to generate builders for models| |false|
|generateConstructorWithAllArgs|whether to generate a constructor for all arguments| |false|
|groupId|groupId in generated pom.xml| |org.openapitools|
|hideGenerationTimestamp|Hides the generation timestamp when files are generated.| |false|
|ignoreAnyOfInEnum|Ignore anyOf keyword in enum| |false|
|implicitHeaders|Skip header parameters in the generated API methods using @ApiImplicitParams annotation.| |false|
|implicitHeadersRegex|Skip header parameters that matches given regex in the generated API methods using @ApiImplicitParams annotation. Note: this parameter is ignored when implicitHeaders=true| |null|
|interfaceOnly|Whether to generate only API interface stubs without the server files.| |false|
|invokerPackage|root package for generated code| |org.openapitools|
|javaVersion|Java version| |17|
|legacyDiscriminatorBehavior|Set to false for generators with better support for discriminators. (Python, Java, Go, PowerShell, C# have this enabled by default).|<dl><dt>**true**</dt><dd>The mapping in the discriminator includes descendent schemas that allOf inherit from self and the discriminator mapping schemas in the OAS document.</dd><dt>**false**</dt><dd>The mapping in the discriminator includes any descendent schemas that allOf inherit from self, any oneOf schemas, any anyOf schemas, any x-discriminator-values, and the discriminator mapping schemas in the OAS document AND Codegen validates that oneOf and anyOf schemas contain the required discriminator and throws an error if the discriminator is missing.</dd></dl>|true|
|licenseName|The name of the license| |Unlicense|
|licenseUrl|The URL of the license| |http://unlicense.org|
|modelPackage|package for generated models| |org.openapitools.model|
|openApiNullable|Enable OpenAPI Jackson Nullable library. Not supported by `microprofile` library.| |true|
|parentArtifactId|parent artifactId in generated pom N.B. parentGroupId, parentArtifactId and parentVersion must all be specified for any of them to take effect| |null|
|parentGroupId|parent groupId in generated pom N.B. parentGroupId, parentArtifactId and parentVersion must all be specified for any of them to take effect| |null|
|parentVersion|parent version in generated pom N.B. parentGroupId, parentArtifactId and parentVersion must all be specified for any of them to take effect| |null|
|prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false|
|registry-address|Registry address (e.g., zookeeper://127.0.0.1:2181 or nacos://127.0.0.1:8848)| |zookeeper://127.0.0.1:2181|
|scmConnection|SCM connection in generated pom.xml| |scm:git:git@github.com:openapitools/openapi-generator.git|
|scmDeveloperConnection|SCM developer connection in generated pom.xml| |scm:git:git@github.com:openapitools/openapi-generator.git|
|scmUrl|SCM URL in generated pom.xml| |https://github.com/openapitools/openapi-generator|
|serializableModel|boolean - toggle &quot;implements Serializable&quot; for generated models| |false|
|serviceImplementation|Generate service implementation| |true|
|serviceInterface|Generate service interface| |true|
|snapshotVersion|Uses a SNAPSHOT version.|<dl><dt>**true**</dt><dd>Use a SnapShot Version</dd><dt>**false**</dt><dd>Use a Release Version</dd></dl>|null|
|sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true|
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|sourceFolder|source folder for generated code| |src/main/java|
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|title|API title name| |null|
|useGenericResponse|Use generic response wrapper| |false|
|useJakartaEe|whether to use Jakarta EE namespace instead of javax| |false|
|useOneOfInterfaces|whether to use a java interface to describe a set of oneOf options, where each option is a class that implements the interface| |false|
|useTags|use tags for creating interface and controller classnames| |true|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|
## SUPPORTED VENDOR EXTENSIONS
| Extension name | Description | Applicable for | Default value |
| -------------- | ----------- | -------------- | ------------- |
|x-discriminator-value|Used with model inheritance to specify value for discriminator that identifies current model|MODEL|
|x-implements|Ability to specify interfaces that model must implements|MODEL|empty array
|x-setter-extra-annotation|Custom annotation that can be specified over java setter for specific field|FIELD|When field is array & uniqueItems, then this extension is used to add `@JsonDeserialize(as = LinkedHashSet.class)` over setter, otherwise no value
|x-tags|Specify multiple swagger tags for operation|OPERATION|null
|x-accepts|Specify custom value for 'Accept' header for operation|OPERATION|null
|x-content-type|Specify custom value for 'Content-Type' header for operation|OPERATION|null
|x-class-extra-annotation|List of custom annotations to be added to model|MODEL|null
|x-field-extra-annotation|List of custom annotations to be added to property|FIELD, OPERATION_PARAMETER|null
## IMPORT MAPPING
| Type/Alias | Imports |
| ---------- | ------- |
|Array|java.util.List|
|ArrayList|java.util.ArrayList|
|Arrays|java.util.Arrays|
|BigDecimal|java.math.BigDecimal|
|BigInteger|java.math.BigInteger|
|Date|java.util.Date|
|DateTime|org.joda.time.*|
|File|java.io.File|
|HashMap|java.util.HashMap|
|HashSet|java.util.HashSet|
|LinkedHashSet|java.util.LinkedHashSet|
|List|java.util.List|
|LocalDate|java.time.LocalDate|
|LocalDateTime|java.time.LocalDateTime|
|LocalTime|java.time.LocalTime|
|Map|java.util.Map|
|MultipartFile|org.springframework.web.multipart.MultipartFile|
|OffsetDateTime|java.time.OffsetDateTime|
|Set|java.util.Set|
|Timestamp|java.sql.Timestamp|
|URI|java.net.URI|
|UUID|java.util.UUID|
## INSTANTIATION TYPES
| Type/Alias | Instantiated By |
| ---------- | --------------- |
|array|ArrayList|
|map|HashMap|
|set|LinkedHashSet|
## LANGUAGE PRIMITIVES
<ul class="column-ul">
<li>Boolean</li>
<li>Double</li>
<li>Float</li>
<li>Integer</li>
<li>List</li>
<li>Long</li>
<li>Map</li>
<li>Object</li>
<li>Set</li>
<li>String</li>
<li>boolean</li>
</ul>
## RESERVED WORDS
<ul class="column-ul">
<li>_</li>
<li>abstract</li>
<li>apiclient</li>
<li>apiexception</li>
<li>apiresponse</li>
<li>assert</li>
<li>boolean</li>
<li>break</li>
<li>byte</li>
<li>case</li>
<li>catch</li>
<li>char</li>
<li>class</li>
<li>configuration</li>
<li>const</li>
<li>continue</li>
<li>default</li>
<li>do</li>
<li>double</li>
<li>else</li>
<li>enum</li>
<li>extends</li>
<li>file</li>
<li>final</li>
<li>finally</li>
<li>float</li>
<li>for</li>
<li>goto</li>
<li>if</li>
<li>implements</li>
<li>import</li>
<li>instanceof</li>
<li>int</li>
<li>interface</li>
<li>list</li>
<li>localdate</li>
<li>localreturntype</li>
<li>localtime</li>
<li>localvaraccept</li>
<li>localvaraccepts</li>
<li>localvarauthnames</li>
<li>localvarcollectionqueryparams</li>
<li>localvarcontenttype</li>
<li>localvarcontenttypes</li>
<li>localvarcookieparams</li>
<li>localvarformparams</li>
<li>localvarheaderparams</li>
<li>localvarpath</li>
<li>localvarpostbody</li>
<li>localvarqueryparams</li>
<li>long</li>
<li>native</li>
<li>new</li>
<li>null</li>
<li>object</li>
<li>offsetdatetime</li>
<li>package</li>
<li>private</li>
<li>protected</li>
<li>public</li>
<li>return</li>
<li>short</li>
<li>static</li>
<li>strictfp</li>
<li>stringutil</li>
<li>super</li>
<li>switch</li>
<li>synchronized</li>
<li>this</li>
<li>throw</li>
<li>throws</li>
<li>transient</li>
<li>try</li>
<li>void</li>
<li>volatile</li>
<li>while</li>
</ul>
## FEATURE SET
### Client Modification Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|BasePath|✓|ToolingExtension
|Authorizations|✗|ToolingExtension
|UserAgent|✗|ToolingExtension
|MockServer|✗|ToolingExtension
### Data Type Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Custom|✗|OAS2,OAS3
|Int32|✓|OAS2,OAS3
|Int64|✓|OAS2,OAS3
|Float|✓|OAS2,OAS3
|Double|✓|OAS2,OAS3
|Decimal|✓|ToolingExtension
|String|✓|OAS2,OAS3
|Byte|✓|OAS2,OAS3
|Binary|✓|OAS2,OAS3
|Boolean|✓|OAS2,OAS3
|Date|✓|OAS2,OAS3
|DateTime|✓|OAS2,OAS3
|Password|✓|OAS2,OAS3
|File|✓|OAS2
|Uuid|✗|
|Array|✓|OAS2,OAS3
|Null|✗|OAS3
|AnyType|✗|OAS2,OAS3
|Object|✓|OAS2,OAS3
|Maps|✓|ToolingExtension
|CollectionFormat|✓|OAS2
|CollectionFormatMulti|✓|OAS2
|Enum|✓|OAS2,OAS3
|ArrayOfEnum|✓|ToolingExtension
|ArrayOfModel|✓|ToolingExtension
|ArrayOfCollectionOfPrimitives|✓|ToolingExtension
|ArrayOfCollectionOfModel|✓|ToolingExtension
|ArrayOfCollectionOfEnum|✓|ToolingExtension
|MapOfEnum|✓|ToolingExtension
|MapOfModel|✓|ToolingExtension
|MapOfCollectionOfPrimitives|✓|ToolingExtension
|MapOfCollectionOfModel|✓|ToolingExtension
|MapOfCollectionOfEnum|✓|ToolingExtension
### Documentation Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Readme|✓|ToolingExtension
|Model|✓|ToolingExtension
|Api|✓|ToolingExtension
### Global Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Host|✓|OAS2,OAS3
|BasePath|✓|OAS2,OAS3
|Info|✓|OAS2,OAS3
|Schemes|✗|OAS2,OAS3
|PartialSchemes|✓|OAS2,OAS3
|Consumes|✓|OAS2
|Produces|✓|OAS2
|ExternalDocumentation|✓|OAS2,OAS3
|Examples|✓|OAS2,OAS3
|XMLStructureDefinitions|✗|OAS2,OAS3
|MultiServer|✗|OAS3
|ParameterizedServer|✗|OAS3
|ParameterStyling|✗|OAS3
|Callbacks|✗|OAS3
|LinkObjects|✗|OAS3
### Parameter Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Path|✓|OAS2,OAS3
|Query|✓|OAS2,OAS3
|Header|✓|OAS2,OAS3
|Body|✓|OAS2
|FormUnencoded|✓|OAS2
|FormMultipart|✓|OAS2
|Cookie|✗|OAS3
### Schema Support Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Simple|✓|OAS2,OAS3
|Composite|✓|OAS2,OAS3
|Polymorphism|✓|OAS2,OAS3
|Union|✗|OAS3
|allOf|✗|OAS2,OAS3
|anyOf|✗|OAS3
|oneOf|✗|OAS3
|not|✗|OAS3
### Security Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|BasicAuth|✓|OAS2,OAS3
|ApiKey|✓|OAS2,OAS3
|OpenIDConnect|✗|OAS3
|BearerToken|✗|OAS3
|OAuth2_Implicit|✓|OAS2,OAS3
|OAuth2_Password|✓|OAS2,OAS3
|OAuth2_ClientCredentials|✓|OAS2,OAS3
|OAuth2_AuthorizationCode|✓|OAS2,OAS3
|SignatureAuth|✗|OAS3
|AWSV4Signature|✗|ToolingExtension
### Wire Format Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|JSON|✓|OAS2,OAS3
|XML|✓|OAS2,OAS3
|PROTOBUF|✗|ToolingExtension
|Custom|✓|OAS2,OAS3

View File

@ -0,0 +1,885 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law of 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.openapitools.codegen.languages;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.media.Schema;
import lombok.Getter;
import lombok.Setter;
import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.GeneratorMetadata;
import org.openapitools.codegen.meta.Stability;
import org.openapitools.codegen.meta.features.*;
import org.openapitools.codegen.model.ModelMap;
import org.openapitools.codegen.model.ModelsMap;
import org.openapitools.codegen.model.OperationMap;
import org.openapitools.codegen.model.OperationsMap;
import org.openapitools.codegen.templating.mustache.TrimWhitespaceLambda;
import org.openapitools.codegen.utils.ModelUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;
import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER;
import org.openapitools.codegen.utils.CamelizeOption;
import static org.openapitools.codegen.utils.StringUtils.camelize;
public class JavaDubboServerCodegen extends AbstractJavaCodegen {
private final Logger LOGGER = LoggerFactory.getLogger(JavaDubboServerCodegen.class);
public static final String TITLE = "title";
public static final String CONFIG_PACKAGE = "configPackage";
public static final String BASE_PACKAGE = "basePackage";
public static final String INTERFACE_ONLY = "interfaceOnly";
public static final String USE_TAGS = "useTags";
public static final String DUBBO_VERSION = "dubboVersion";
public static final String JAVA_VERSION = "javaVersion";
public static final String SERVICE_INTERFACE = "serviceInterface";
public static final String SERVICE_IMPLEMENTATION = "serviceImplementation";
public static final String USE_GENERIC_RESPONSE = "useGenericResponse";
public static final String REGISTRY_ADDRESS = "registry-address";
@Setter
protected String title = null;
@Getter
@Setter
protected String configPackage = "org.openapitools.configuration";
@Getter
@Setter
protected String basePackage = "org.openapitools";
@Setter
protected boolean interfaceOnly = false;
@Setter
protected boolean useTags = true;
@Setter
protected String javaVersion = "17";
@Setter
protected String dubboVersion = "3.2.18";
@Setter
protected boolean serviceInterface = true;
@Setter
protected boolean serviceImplementation = true;
@Setter
protected boolean useGenericResponse = false;
@Setter
protected String registryAddress = "zookeeper://127.0.0.1:2181";
public JavaDubboServerCodegen() {
super();
modifyFeatureSet(features -> features
.includeDocumentationFeatures(DocumentationFeature.Readme)
.wireFormatFeatures(EnumSet.of(WireFormatFeature.JSON, WireFormatFeature.XML, WireFormatFeature.Custom))
.securityFeatures(EnumSet.of(SecurityFeature.OAuth2_Implicit, SecurityFeature.OAuth2_AuthorizationCode,
SecurityFeature.OAuth2_ClientCredentials, SecurityFeature.OAuth2_Password,
SecurityFeature.ApiKey, SecurityFeature.BasicAuth))
.excludeGlobalFeatures(GlobalFeature.Callbacks, GlobalFeature.LinkObjects, GlobalFeature.ParameterStyling)
.includeSchemaSupportFeatures(SchemaSupportFeature.Polymorphism)
.excludeParameterFeatures(ParameterFeature.Cookie));
generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata)
.stability(Stability.BETA)
.build();
dateLibrary = "java8";
useBeanValidation = false;
serializableModel = true;
outputFolder = "generated-code/java-dubbo";
embeddedTemplateDir = templateDir = "java-dubbo";
invokerPackage = "org.openapitools";
apiPackage = invokerPackage + ".api";
modelPackage = invokerPackage + ".model";
artifactId = "openapi-dubbo";
additionalProperties.put("hideGenerationTimestamp", true);
additionalProperties.put("withXml", false);
importMapping.remove("ApiModel");
importMapping.remove("ApiModelProperty");
setDocumentationProvider(DocumentationProvider.NONE);
setAnnotationLibrary(AnnotationLibrary.NONE);
supportsInheritance = false;
supportsMixins = false;
importMapping.remove("ApiModel");
importMapping.remove("ApiModelProperty");
importMapping.remove("Schema");
importMapping.remove("io.swagger.annotations.ApiModel");
importMapping.remove("io.swagger.annotations.ApiModelProperty");
importMapping.remove("io.swagger.v3.oas.annotations.media.Schema");
typeMapping.clear();
typeMapping.put("integer", "Integer");
typeMapping.put("long", "Long");
typeMapping.put("float", "Float");
typeMapping.put("double", "Double");
typeMapping.put("boolean", "Boolean");
typeMapping.put("string", "String");
typeMapping.put("array", "List");
typeMapping.put("map", "Map");
typeMapping.put("object", "Object");
typeMapping.put("date", "LocalDate");
typeMapping.put("DateTime", "OffsetDateTime");
typeMapping.put("date-time", "OffsetDateTime");
typeMapping.put("number", "BigDecimal");
typeMapping.put("decimal", "BigDecimal");
typeMapping.put("binary", "byte[]");
typeMapping.put("file", "org.springframework.web.multipart.MultipartFile");
typeMapping.put("uuid", "UUID");
typeMapping.put("byte", "byte[]");
typeMapping.put("ByteArray", "byte[]");
typeMapping.put("binary", "byte[]");
typeMapping.put("password", "String");
languageSpecificPrimitives.clear();
languageSpecificPrimitives.add("String");
languageSpecificPrimitives.add("boolean");
languageSpecificPrimitives.add("Boolean");
languageSpecificPrimitives.add("Double");
languageSpecificPrimitives.add("Integer");
languageSpecificPrimitives.add("Long");
languageSpecificPrimitives.add("Float");
languageSpecificPrimitives.add("Object");
languageSpecificPrimitives.add("List");
languageSpecificPrimitives.add("Map");
languageSpecificPrimitives.add("Set");
importMapping.put("List", "java.util.List");
importMapping.put("Map", "java.util.Map");
importMapping.put("Set", "java.util.Set");
importMapping.put("ArrayList", "java.util.ArrayList");
importMapping.put("HashMap", "java.util.HashMap");
importMapping.put("HashSet", "java.util.HashSet");
importMapping.put("Date", "java.util.Date");
importMapping.put("Arrays", "java.util.Arrays");
importMapping.put("OffsetDateTime", "java.time.OffsetDateTime");
importMapping.put("LocalDate", "java.time.LocalDate");
importMapping.put("LocalTime", "java.time.LocalTime");
importMapping.put("LocalDateTime", "java.time.LocalDateTime");
importMapping.put("BigDecimal", "java.math.BigDecimal");
importMapping.put("BigInteger", "java.math.BigInteger");
importMapping.put("UUID", "java.util.UUID");
importMapping.put("MultipartFile", "org.springframework.web.multipart.MultipartFile");
typeMapping.put("List", "List");
typeMapping.put("Set", "Set");
typeMapping.put("Map", "Map");
updateOption(CodegenConstants.INVOKER_PACKAGE, this.getInvokerPackage());
updateOption(CodegenConstants.ARTIFACT_ID, this.getArtifactId());
updateOption(CodegenConstants.API_PACKAGE, apiPackage);
updateOption(CodegenConstants.MODEL_PACKAGE, modelPackage);
apiTestTemplateFiles.clear();
apiTemplateFiles.clear();
apiTemplateFiles.put("api.mustache", ".java");
apiTemplateFiles.put("apiDubbo.mustache", ".java");
apiTemplateFiles.put("apiController.mustache", ".java");
apiDocTemplateFiles.clear();
modelTemplateFiles.clear();
modelTemplateFiles.put("model.mustache", ".java");
modelDocTemplateFiles.clear();
additionalProperties.put("dubboVersion", dubboVersion);
additionalProperties.put("javaVersion", javaVersion);
cliOptions.add(new CliOption(TITLE, "API title name").defaultValue(title));
cliOptions.add(new CliOption(CONFIG_PACKAGE, "configuration package for generated code")
.defaultValue(this.getConfigPackage()));
cliOptions.add(new CliOption(BASE_PACKAGE, "base package (invokerPackage) for generated code")
.defaultValue(this.getBasePackage()));
cliOptions.add(CliOption.newBoolean(INTERFACE_ONLY,
"Whether to generate only API interface stubs without the server files.", interfaceOnly));
cliOptions.add(CliOption.newBoolean(USE_TAGS, "use tags for creating interface and controller classnames", useTags));
cliOptions.add(new CliOption(DUBBO_VERSION, "Dubbo version").defaultValue(dubboVersion));
cliOptions.add(new CliOption(JAVA_VERSION, "Java version").defaultValue(javaVersion));
cliOptions.add(CliOption.newBoolean(SERVICE_INTERFACE, "Generate service interface", serviceInterface));
cliOptions.add(CliOption.newBoolean(SERVICE_IMPLEMENTATION, "Generate service implementation", serviceImplementation));
cliOptions.add(CliOption.newBoolean(USE_GENERIC_RESPONSE, "Use generic response wrapper", useGenericResponse));
cliOptions.add(new CliOption(REGISTRY_ADDRESS, "Registry address (e.g., zookeeper://127.0.0.1:2181 or nacos://127.0.0.1:8848)")
.defaultValue(registryAddress));
}
@Override
public CodegenType getTag() {
return CodegenType.SERVER;
}
@Override
public String getName() {
return "java-dubbo";
}
@Override
public String getHelp() {
return "Generates a Java Apache Dubbo server application.";
}
private boolean isOutputFolderPointingToSourceDirectory() {
if (outputFolder == null) {
return false;
}
String normalizedPath = outputFolder.replace('\\', '/');
return normalizedPath.endsWith("/src/main/java") || normalizedPath.endsWith("src/main/java");
}
@Override
public String outputFolder() {
if (isOutputFolderPointingToSourceDirectory()) {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
for (StackTraceElement element : stackTrace) {
String methodName = element.getMethodName();
String className = element.getClassName();
if (className.equals("org.openapitools.codegen.DefaultGenerator")) {
if (methodName.equals("generateVersionMetadata") ||
methodName.equals("generateFilesMetadata")) {
return outputFolder + File.separator + ".." + File.separator + ".." + File.separator + "..";
}
}
}
}
return outputFolder;
}
public String getIgnoreFileOutputPath() {
if (isOutputFolderPointingToSourceDirectory()) {
return outputFolder + File.separator + ".." + File.separator + ".." + File.separator + "..";
}
return outputFolder;
}
@Override
public void processOpts() {
final List<org.apache.commons.lang3.tuple.Pair<String, String>> configOptions =
additionalProperties.entrySet().stream()
.filter(e -> !Arrays.asList("hideGenerationTimestamp").contains(e.getKey()))
.filter(e -> cliOptions.stream().map(CliOption::getOpt).anyMatch(opt -> opt.equals(e.getKey())))
.map(e -> org.apache.commons.lang3.tuple.Pair.of(e.getKey(), e.getValue().toString()))
.collect(Collectors.toList());
additionalProperties.put("configOptions", configOptions);
super.processOpts();
supportingFiles.removeIf(sf -> sf.getDestinationFilename().equals(".openapi-generator-ignore"));
openapiGeneratorIgnoreList = new HashSet<>();
openapiGeneratorIgnoreList.add("# Dubbo generator explicitly disables .openapi-generator-ignore");
importMapping.remove("ApiModel");
importMapping.remove("ApiModelProperty");
importMapping.remove("io.swagger.annotations.ApiModel");
importMapping.remove("io.swagger.annotations.ApiModelProperty");
importMapping.remove("Schema");
importMapping.remove("io.swagger.v3.oas.annotations.media.Schema");
String userTitle = (String) additionalProperties.get(TITLE);
boolean userProvidedTitle = userTitle != null && !userTitle.equals("OpenAPI Dubbo");
if (userProvidedTitle) {
this.title = userTitle;
}
additionalProperties.put("userProvidedTitle", userProvidedTitle);
additionalProperties.put("title", this.title);
if (additionalProperties.containsKey(CONFIG_PACKAGE)) {
this.setConfigPackage((String) additionalProperties.get(CONFIG_PACKAGE));
}
if (additionalProperties.containsKey(BASE_PACKAGE)) {
String basePackageName = (String) additionalProperties.get(BASE_PACKAGE);
this.setBasePackage(basePackageName);
this.setInvokerPackage(basePackageName);
this.apiPackage = basePackageName + ".api";
this.modelPackage = basePackageName + ".model";
if (!additionalProperties.containsKey(CONFIG_PACKAGE)) {
this.configPackage = basePackageName + ".configuration";
}
updateOption(CodegenConstants.API_PACKAGE, this.apiPackage);
updateOption(CodegenConstants.MODEL_PACKAGE, this.modelPackage);
updateOption(CodegenConstants.INVOKER_PACKAGE, this.getInvokerPackage());
}
if (additionalProperties.containsKey(INTERFACE_ONLY)) {
this.interfaceOnly = Boolean.parseBoolean(additionalProperties.get(INTERFACE_ONLY).toString());
}
if (additionalProperties.containsKey(USE_TAGS)) {
this.useTags = Boolean.parseBoolean(additionalProperties.get(USE_TAGS).toString());
}
if (additionalProperties.containsKey(DUBBO_VERSION)) {
this.dubboVersion = (String) additionalProperties.get(DUBBO_VERSION);
}
if (additionalProperties.containsKey(JAVA_VERSION)) {
this.javaVersion = (String) additionalProperties.get(JAVA_VERSION);
}
if (additionalProperties.containsKey(SERVICE_INTERFACE)) {
this.serviceInterface = Boolean.parseBoolean(additionalProperties.get(SERVICE_INTERFACE).toString());
}
if (additionalProperties.containsKey(SERVICE_IMPLEMENTATION)) {
this.serviceImplementation = Boolean.parseBoolean(additionalProperties.get(SERVICE_IMPLEMENTATION).toString());
}
if (additionalProperties.containsKey(USE_GENERIC_RESPONSE)) {
this.useGenericResponse = Boolean.parseBoolean(additionalProperties.get(USE_GENERIC_RESPONSE).toString());
}
if (additionalProperties.containsKey(REGISTRY_ADDRESS)) {
this.registryAddress = (String) additionalProperties.get(REGISTRY_ADDRESS);
}
additionalProperties.put("title", this.title);
additionalProperties.put("configPackage", this.configPackage);
additionalProperties.put("basePackage", this.basePackage);
additionalProperties.put("apiPackage", this.apiPackage);
additionalProperties.put("modelPackage", this.modelPackage);
additionalProperties.put("invokerPackage", this.getInvokerPackage());
additionalProperties.put("interfaceOnly", interfaceOnly);
additionalProperties.put("useTags", useTags);
additionalProperties.put("dubboVersion", dubboVersion);
additionalProperties.put("javaVersion", javaVersion);
additionalProperties.put("serviceInterface", serviceInterface);
additionalProperties.put("serviceImplementation", serviceImplementation);
additionalProperties.put("useGenericResponse", useGenericResponse);
additionalProperties.put("registryAddress", registryAddress);
supportingFiles.clear();
if (isOutputFolderPointingToSourceDirectory()) {
String rootPath = ".." + File.separator + ".." + File.separator + "..";
supportingFiles.add(new SupportingFile("pom.mustache", rootPath, "pom.xml"));
supportingFiles.add(new SupportingFile("README.mustache", rootPath, "README.md"));
} else {
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
}
if (serviceImplementation && !interfaceOnly) {
String mainClassName;
boolean isUserTitle = (Boolean) additionalProperties.getOrDefault("userProvidedTitle", false);
if (isUserTitle) {
String titleName = (String) additionalProperties.get(TITLE);
mainClassName = (camelize(titleName.trim(), CamelizeOption.UPPERCASE_FIRST_CHAR) + "Application").replaceAll("\\s+", "");
;
} else {
mainClassName = "OpenApiGeneratorApplication";
}
String testClassName = mainClassName + "Tests";
additionalProperties.put("mainClassName", mainClassName);
additionalProperties.put("testClassName", testClassName);
if (isOutputFolderPointingToSourceDirectory()) {
supportingFiles.add(new SupportingFile("mainApplication.mustache",
basePackage.replace(".", File.separator),
mainClassName + ".java"));
supportingFiles.add(new SupportingFile("applicationTest.mustache",
".." + File.separator + ".." + File.separator + ".." + File.separator + "src" + File.separator + "test" + File.separator + "java" + File.separator + basePackage.replace(".", File.separator),
testClassName + ".java"));
supportingFiles.add(new SupportingFile("application.mustache",
".." + File.separator + ".." + File.separator + ".." + File.separator + "src" + File.separator + "main" + File.separator + "resources",
"application.yml"));
} else {
supportingFiles.add(new SupportingFile("mainApplication.mustache",
(sourceFolder + File.separator + basePackage).replace(".", File.separator),
mainClassName + ".java"));
supportingFiles.add(new SupportingFile("applicationTest.mustache",
(testFolder + File.separator + basePackage).replace(".", File.separator),
testClassName + ".java"));
supportingFiles.add(new SupportingFile("application.mustache",
"src/main/resources".replace("/", File.separator),
"application.yml"));
}
}
additionalProperties.put("lambdaTrimWhitespace", new TrimWhitespaceLambda());
additionalProperties.put("documentationProvider", "none");
additionalProperties.put("annotationLibrary", "none");
additionalProperties.put("hideGenerationTimestamp", true);
additionalProperties.put("useBeanValidation", false);
additionalProperties.put("performBeanValidation", false);
}
private boolean isDubbo33OrHigher(String version) {
if (version == null || version.trim().isEmpty()) {
return false;
}
try {
String cleanVersion = version.split("-")[0];
String[] parts = cleanVersion.split("\\.");
if (parts.length >= 2) {
int major = Integer.parseInt(parts[0]);
int minor = Integer.parseInt(parts[1]);
return major > 3 || (major == 3 && minor >= 3);
}
} catch (NumberFormatException e) {
LOGGER.warn("Unable to parse Dubbo version: " + version);
}
return false;
}
@Override
public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
generateYAMLSpecFile(objs);
objs = super.postProcessSupportingFileData(objs);
objs.put("interfacePackage", apiPackage + ".interfaces");
objs.put("consumerPackage", apiPackage + ".consumer");
objs.put("providerPackage", apiPackage + ".provider");
objs.put("registryAddress", registryAddress);
boolean isDubbo33Plus = isDubbo33OrHigher(dubboVersion);
objs.put("isDubbo33Plus", isDubbo33Plus);
boolean isZookeeperRegistry = registryAddress != null && registryAddress.startsWith("zookeeper://");
boolean isNacosRegistry = registryAddress != null && registryAddress.startsWith("nacos://");
objs.put("isZookeeperRegistry", isZookeeperRegistry);
objs.put("isNacosRegistry", isNacosRegistry);
String nacosClientVersion = isDubbo33Plus ? "2.5.0" : "2.2.4";
objs.put("nacosClientVersion", nacosClientVersion);
return objs;
}
@Override
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<ModelMap> allModels) {
OperationsMap results = super.postProcessOperationsWithModels(objs, allModels);
if (results.getImports() != null) {
boolean hasJavaUtilImports = false;
Iterator<Map<String, String>> importIterator = results.getImports().iterator();
while (importIterator.hasNext()) {
Map<String, String> importMap = importIterator.next();
String importName = importMap.get("import");
if (importName != null && importName.startsWith("java.util.") &&
!importName.equals("java.util.*") &&
!importName.equals("java.util.UUID")) {
importIterator.remove();
hasJavaUtilImports = true;
}
}
if (hasJavaUtilImports) {
Map<String, String> utilImport = new HashMap<>();
utilImport.put("import", "java.util.*");
utilImport.put("classname", "*");
results.getImports().add(utilImport);
}
}
OperationMap operations = results.getOperations();
if (operations != null) {
String baseName = (String) operations.get("baseName");
String originalClassName = (String) operations.get("classname");
if (baseName == null) {
baseName = originalClassName;
if (baseName != null && baseName.endsWith("Service")) {
baseName = baseName.substring(0, baseName.length() - 7).toLowerCase(java.util.Locale.ROOT);
} else if (baseName != null && baseName.endsWith("Api")) {
baseName = baseName.substring(0, baseName.length() - 3).toLowerCase(java.util.Locale.ROOT);
}
}
if (baseName != null) {
if ("ashares".equals(baseName)) {
operations.put("baseName", "a");
} else if ("usdata".equals(baseName)) {
operations.put("baseName", "us");
} else if ("kline".equals(baseName)) {
operations.put("baseName", "kline");
}
}
if (originalClassName != null) {
String serviceName = originalClassName;
if (serviceName.endsWith("Api")) {
serviceName = serviceName.replace("Api", "Service");
} else if (serviceName.endsWith("Service")) {
serviceName = originalClassName;
}
operations.put("serviceName", serviceName);
operations.put("serviceVarName", camelize(serviceName, LOWERCASE_FIRST_LETTER));
operations.put("servicePackage", apiPackage + ".interfaces");
operations.put("serviceImport", apiPackage + ".interfaces." + serviceName);
operations.put("interfacePackage", apiPackage + ".interfaces");
operations.put("consumerPackage", apiPackage + ".consumer");
operations.put("providerPackage", apiPackage + ".provider");
}
List<CodegenOperation> ops = operations.getOperation();
for (CodegenOperation operation : ops) {
if (useGenericResponse) {
operation.vendorExtensions.put("x-generic-response", true);
}
}
}
results.put("interfacePackage", apiPackage + ".interfaces");
results.put("consumerPackage", apiPackage + ".consumer");
results.put("providerPackage", apiPackage + ".provider");
return results;
}
@Override
public String apiFileFolder() {
if (isOutputFolderPointingToSourceDirectory()) {
return outputFolder + File.separator + apiPackage().replace('.', File.separatorChar);
} else {
return outputFolder + File.separator + "src" + File.separator + "main" + File.separator + "java" + File.separator + apiPackage().replace('.', File.separatorChar);
}
}
public String getFileFolderForTemplate(String templateName) {
String baseFolder;
if (isOutputFolderPointingToSourceDirectory()) {
baseFolder = outputFolder + File.separator + apiPackage().replace('.', File.separatorChar);
} else {
baseFolder = outputFolder + File.separator + "src" + File.separator + "main" + File.separator + "java" + File.separator + apiPackage().replace('.', File.separatorChar);
}
if ("api.mustache".equals(templateName)) {
return baseFolder + File.separator + "interfaces";
} else if ("apiController.mustache".equals(templateName)) {
return baseFolder + File.separator + "consumer";
} else if ("apiDubbo.mustache".equals(templateName)) {
return baseFolder + File.separator + "provider";
}
return baseFolder;
}
public String getPackageForTemplate(String templateName) {
if ("api.mustache".equals(templateName)) {
return apiPackage() + ".interfaces";
} else if ("apiController.mustache".equals(templateName)) {
return apiPackage() + ".consumer";
} else if ("apiDubbo.mustache".equals(templateName)) {
return apiPackage() + ".provider";
}
return apiPackage();
}
@Override
public String modelFileFolder() {
if (isOutputFolderPointingToSourceDirectory()) {
return outputFolder + File.separator + modelPackage().replace('.', File.separatorChar);
} else {
return outputFolder + File.separator + "src" + File.separator + "main" + File.separator + "java" + File.separator + modelPackage().replace('.', File.separatorChar);
}
}
@Override
public String apiFilename(String templateName, String tag) {
String suffix = apiTemplateFiles().get(templateName);
if (suffix == null) {
return null;
}
String folder = getFileFolderForTemplate(templateName);
String filename;
String apiName = toApiName(tag);
if ("api.mustache".equals(templateName)) {
filename = apiName;
} else if ("apiDubbo.mustache".equals(templateName)) {
filename = apiName + "Impl";
} else if ("apiController.mustache".equals(templateName)) {
filename = apiName + "Controller";
} else {
filename = toApiFilename(tag);
}
return folder + File.separator + filename + suffix;
}
@Override
public String toApiName(String name) {
if (name.length() == 0) {
return "DefaultService";
}
name = sanitizeName(name);
String apiName = camelize(name, CamelizeOption.UPPERCASE_FIRST_CHAR);
if (!apiName.endsWith("Service")) {
apiName = apiName + "Service";
}
return apiName;
}
@Override
public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map<String, List<CodegenOperation>> operations) {
if (useTags) {
String basePath = resourcePath;
if (basePath.startsWith("/")) {
basePath = basePath.substring(1);
}
int pos = basePath.indexOf("/");
if (pos > 0) {
basePath = basePath.substring(0, pos);
}
if (basePath.length() == 0) {
basePath = "default";
} else {
String subPath = resourcePath;
if (subPath.startsWith("/" + basePath)) {
subPath = subPath.substring(("/" + basePath).length());
}
if (subPath.isEmpty()) {
subPath = "/";
}
co.vendorExtensions.put("x-sub-path", subPath);
co.subresourceOperation = !subPath.equals("/");
co.vendorExtensions.put("x-base-path", "/" + basePath);
if ("a".equals(basePath)) {
basePath = "ashares";
} else if ("us".equals(basePath)) {
basePath = "usdata";
}
}
List<CodegenOperation> opList = operations.computeIfAbsent(basePath, k -> new ArrayList<>());
opList.add(co);
co.baseName = basePath;
} else {
super.addOperationToGroup(tag, resourcePath, operation, co, operations);
}
}
@Override
public boolean isDataTypeString(String dataType) {
return "String".equals(dataType);
}
@Override
public String getTypeDeclaration(Schema p) {
if (ModelUtils.isArraySchema(p)) {
Schema inner = ModelUtils.getSchemaItems(p);
String innerType = getTypeDeclaration(inner);
return "List<" + innerType + ">";
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = ModelUtils.getAdditionalProperties(p);
String innerType = getTypeDeclaration(inner);
return "Map<String, " + innerType + ">";
}
return super.getTypeDeclaration(p);
}
@Override
public String getSchemaType(Schema p) {
String openAPIType = super.getSchemaType(p);
if (typeMapping.containsKey(openAPIType)) {
return typeMapping.get(openAPIType);
}
return openAPIType;
}
@Override
public Set<String> defaultIncludes() {
return new HashSet<String>(
Arrays.asList(
"double",
"int",
"long",
"short",
"char",
"float",
"String",
"boolean",
"Boolean",
"Double",
"Void",
"Integer",
"Long",
"Float")
);
}
@Override
public String toModelImport(String name) {
if ("ApiModel".equals(name) || "ApiModelProperty".equals(name)) {
return null;
}
if ("".equals(modelPackage())) {
return name;
} else {
return modelPackage() + "." + name;
}
}
@Override
public String getTypeDeclaration(String name) {
if ("ApiModel".equals(name) || "ApiModelProperty".equals(name)) {
return null;
}
return super.getTypeDeclaration(name);
}
@Override
public boolean needToImport(String type) {
if ("ApiModel".equals(type) ||
"ApiModelProperty".equals(type) ||
"io.swagger.annotations.ApiModel".equals(type) ||
"io.swagger.annotations.ApiModelProperty".equals(type) ||
"Schema".equals(type) ||
"io.swagger.v3.oas.annotations.media.Schema".equals(type)) {
return false;
}
if ("LocalDate".equals(type) ||
"LocalDateTime".equals(type) ||
"LocalTime".equals(type) ||
"OffsetDateTime".equals(type) ||
"BigDecimal".equals(type) ||
"BigInteger".equals(type) ||
"UUID".equals(type)) {
return true;
}
return super.needToImport(type);
}
@Override
public ModelsMap postProcessModels(ModelsMap objs) {
objs = super.postProcessModels(objs);
for (ModelMap modelMap : objs.getModels()) {
CodegenModel model = modelMap.getModel();
model.imports.remove("ApiModel");
model.imports.remove("ApiModelProperty");
model.imports.remove("io.swagger.annotations.ApiModel");
model.imports.remove("io.swagger.annotations.ApiModelProperty");
model.imports.remove("Schema");
model.imports.remove("io.swagger.v3.oas.annotations.media.Schema");
boolean hasJavaUtilImports = false;
Set<String> javaUtilImports = new HashSet<>();
Iterator<String> iterator = model.imports.iterator();
while (iterator.hasNext()) {
String importName = iterator.next();
if (importName.startsWith("java.util.") &&
!importName.equals("java.util.*") &&
!importName.equals("java.util.UUID")) {
javaUtilImports.add(importName);
iterator.remove();
hasJavaUtilImports = true;
}
}
if (hasJavaUtilImports) {
model.imports.add("java.util.*");
}
for (CodegenProperty var : model.vars) {
if (var.allowableValues != null && var.allowableValues.get("imports") != null) {
((Set<String>) var.allowableValues.get("imports")).remove("ApiModel");
((Set<String>) var.allowableValues.get("imports")).remove("ApiModelProperty");
((Set<String>) var.allowableValues.get("imports")).remove("io.swagger.annotations.ApiModel");
((Set<String>) var.allowableValues.get("imports")).remove("io.swagger.annotations.ApiModelProperty");
}
}
}
if (objs.getImports() != null) {
objs.getImports().removeIf(importMap -> {
String className = importMap.get("classname");
return "ApiModel".equals(className) || "ApiModelProperty".equals(className);
});
boolean hasJavaUtilImports = false;
Iterator<Map<String, String>> importIterator = objs.getImports().iterator();
while (importIterator.hasNext()) {
Map<String, String> importMap = importIterator.next();
String importName = importMap.get("import");
if (importName != null && importName.startsWith("java.util.") &&
!importName.equals("java.util.*") &&
!importName.equals("java.util.UUID")) {
importIterator.remove();
hasJavaUtilImports = true;
}
}
if (hasJavaUtilImports) {
Map<String, String> utilImport = new HashMap<>();
utilImport.put("import", "java.util.*");
utilImport.put("classname", "*");
objs.getImports().add(utilImport);
}
}
return objs;
}
@Override
public String toModelDocFilename(String name) {
return null;
}
@Override
public String toApiDocFilename(String name) {
return null;
}
}

View File

@ -48,6 +48,7 @@ org.openapitools.codegen.languages.HaskellHttpClientCodegen
org.openapitools.codegen.languages.HaskellServantCodegen
org.openapitools.codegen.languages.HaskellYesodServerCodegen
org.openapitools.codegen.languages.JavaClientCodegen
org.openapitools.codegen.languages.JavaDubboServerCodegen
org.openapitools.codegen.languages.JavaCXFClientCodegen
org.openapitools.codegen.languages.JavaHelidonClientCodegen
org.openapitools.codegen.languages.JavaHelidonServerCodegen

View File

@ -0,0 +1,347 @@
# {{appName}}
{{appDescription}}
This is a microservice project based on Apache Dubbo, generated by [OpenAPI Generator](https://openapi-generator.tech).
- API version: {{appVersion}}
- Package version: {{packageVersion}}
{{^hideGenerationTimestamp}}
- Generator version: {{generatorVersion}}
- Build date: {{generatedDate}}
{{/hideGenerationTimestamp}}
- Generator: {{generatorClass}}
{{#externalDocumentationDescription}}
For more information, please visit: [{{{externalDocumentationDescription}}}]({{{externalDocumentationURL}}})
{{/externalDocumentationDescription}}
## Technology Stack
- **Framework**: Apache Dubbo {{dubboVersion}}
{{#useSpringBoot}}
- **Spring Boot**: {{#useSpringBoot3}}3.x{{/useSpringBoot3}}{{^useSpringBoot3}}2.x{{/useSpringBoot3}}
{{/useSpringBoot}}
- **Java**: {{#java8}}8+{{/java8}}{{^java8}}11+{{/java8}}
- **Build Tool**: Maven 3.6+
- **Registry**: {{registryAddress}}
- **Serialization**: Jackson JSON
## System Requirements
Building and running this project requires:
1. Java {{#java8}}8{{/java8}}{{^java8}}11{{/java8}}+
2. Maven 3.6+
3. Registry Center (Nacos or Zookeeper)
## Quick Start
### 1. Clone and Build Project
```bash
git clone <your-repo-url>
cd {{artifactId}}
mvn clean compile
```
### 2. Configure Registry Center
#### Using Nacos (Recommended)
```bash
# Download and start Nacos
wget https://github.com/alibaba/nacos/releases/download/2.2.4/nacos-server-2.2.4.tar.gz
tar -xzf nacos-server-2.2.4.tar.gz
cd nacos/bin
# Linux/Mac
./startup.sh -m standalone
# Windows
startup.cmd -m standalone
```
#### Using Zookeeper (Alternative)
```bash
# Download and start Zookeeper
wget https://downloads.apache.org/zookeeper/zookeeper-3.8.2/apache-zookeeper-3.8.2-bin.tar.gz
tar -xzf apache-zookeeper-3.8.2-bin.tar.gz
cd apache-zookeeper-3.8.2-bin
cp conf/zoo_sample.cfg conf/zoo.cfg
bin/zkServer.sh start
```
### 3. Configure Application
Edit the `src/main/resources/application.yml` file:
```yaml
# Dubbo Configuration
dubbo:
application:
name: {{artifactId}}
registry:
# Using Nacos
address: nacos://127.0.0.1:8848
# Or using Zookeeper
# address: zookeeper://127.0.0.1:2181
protocol:
name: dubbo
port: 20880
provider:
timeout: 10000
{{#useSpringBoot}}
# Spring Boot Configuration
server:
port: 8080
spring:
application:
name: {{artifactId}}
# Logging Configuration
logging:
level:
com.alibaba.nacos: WARN
org.apache.dubbo: INFO
root: INFO
{{/useSpringBoot}}
```
### 4. Start Application
{{#useSpringBoot}}
```bash
# Using Spring Boot Maven plugin
mvn spring-boot:run
# Or build JAR and run
mvn clean package
java -jar target/{{artifactId}}-{{appVersion}}.jar
```
{{/useSpringBoot}}
{{^useSpringBoot}}
```bash
# Build project
mvn clean compile
# Run main class
mvn exec:java -Dexec.mainClass="{{package}}.Application"
```
{{/useSpringBoot}}
## Project Structure
```
{{artifactId}}/
├── src/main/java/{{package}}/
{{#operations}}
│ ├── api/
│ │ ├── {{classname}}.java # Service Interface
│ │ └── {{classname}}DubboImpl.java # Dubbo Service Implementation
{{/operations}}
{{#hasModel}}
│ ├── model/ # Data Models
{{#models}}
{{#model}}
│ │ └── {{classname}}.java
{{/model}}
{{/models}}
{{/hasModel}}
│ └── Application.java # Main Application Class
├── src/main/resources/
│ └── application.yml # Application Configuration
├── pom.xml # Maven Configuration
└── README.md # Project Documentation
```
## API Interfaces
{{#apiDocumentationUrl}}
For complete API documentation, please visit: [{{apiDocumentationUrl}}]({{apiDocumentationUrl}})
{{/apiDocumentationUrl}}
### Service Interfaces
{{#operations}}
#### {{classname}}
{{#operation}}
- **{{nickname}}**: {{summary}}
{{#notes}}
- Description: {{.}}
{{/notes}}
{{/operation}}
{{/operations}}
## Development Guide
### Implement Business Logic
1. Implement specific business logic in the generated `*DubboImpl.java` classes
2. Inject necessary business service dependencies
3. Handle exceptions and error scenarios
### Custom Configuration
1. **Timeout Configuration**: Adjust `dubbo.provider.timeout` in `application.yml`
2. **Thread Pool Configuration**: Configure `dubbo.provider.threads` and other parameters
3. **Serialization Configuration**: Choose appropriate serialization method
### Monitoring and Operations
1. **Health Checks**: Dubbo provides built-in health check endpoints
2. **Metrics Monitoring**: Integrate with Prometheus or other monitoring systems
3. **Log Management**: Configure appropriate log levels and output formats
## Testing
```bash
# Run unit tests
mvn test
# Run integration tests
mvn integration-test
```
## Deployment
### Development Environment
```bash
mvn spring-boot:run
```
### Production Environment
```bash
# Build production package
mvn clean package -Pprod
# Deploy using Docker
docker build -t {{artifactId}}:{{appVersion}} .
docker run -p 8080:8080 -p 20880:20880 {{artifactId}}:{{appVersion}}
```
## Generator Configuration Options
This project supports the following OpenAPI Generator configuration options:
### Basic Configuration
- `title`: API service title name (Default: "OpenAPI Dubbo")
- `basePackage`: Base package name (Default: "org.openapitools")
- `configPackage`: Configuration class package name (Default: "org.openapitools.configuration")
- `dubboVersion`: Dubbo version (Default: "3.2.0")
### Generation Control
- `interfaceOnly`: Generate interfaces only, no implementation classes (Default: false)
- `serviceInterface`: Generate service interfaces (Default: true)
- `serviceImplementation`: Generate service implementations (Default: true)
- `async`: Use asynchronous methods (Default: false)
- `useTags`: Use tags to create class names (Default: true)
- `useGenericResponse`: Use generic response wrapper (Default: false)
### Registry Configuration
- `registry-address`: Registry address, supports full address format (Default: "zookeeper://127.0.0.1:2181")
- Zookeeper example: `zookeeper://127.0.0.1:2181`
- Nacos example: `nacos://127.0.0.1:8848`
#### 📋 Automatic Dependency Adaptation by Version
The generator automatically selects the correct dependencies based on Dubbo version:
**Dubbo 3.2 and earlier versions**:
- Zookeeper: `dubbo-dependencies-zookeeper` (Aggregation POM)
- Nacos: `dubbo-registry-nacos` + `nacos-client:2.2.4`
**Dubbo 3.3+ versions**:
- Zookeeper: `dubbo-registry-zookeeper` + `dubbo-remoting-zookeeper-curator5`
- Nacos: `dubbo-registry-nacos` + `nacos-client:2.5.0`
### Date-Time Library Configuration
- `dateLibrary`: Date-time library selection (Default: "java8")
- `java8`: Java 8 native JSR310 (Recommended, for JDK 1.8+)
- `java8-localdatetime`: Java 8 using LocalDateTime (For legacy applications only)
- `joda`: Joda time library (For legacy applications only)
- `legacy`: Traditional java.util.Date
### Usage Examples
#### 🔧 Dubbo 3.2 Version Example
```bash
# Using Zookeeper (3.2 version automatically uses dubbo-dependencies-zookeeper)
java -jar openapi-generator-cli.jar generate \
-i /Users/redoom/IdeaProjects/openapi.yaml \
-g java-dubbo \
-o /Users/redoom/IdeaProjects/openapi-test \
--additional-properties=registry-address=zookeeper://127.0.0.1:2181 \
--additional-properties=dubboVersion=3.2.0 \
--additional-properties=dateLibrary=java8
# Using Nacos (3.2 version uses nacos-client:2.2.4)
java -jar openapi-generator-cli.jar generate \
-i /Users/redoom/IdeaProjects/openapi.yaml \
-g java-dubbo \
-o /Users/redoom/IdeaProjects/openapi-test \
--additional-properties=registry-address=nacos://127.0.0.1:8848 \
--additional-properties=dubboVersion=3.2.0 \
--additional-properties=dateLibrary=java8
```
#### 🚀 Dubbo 3.3+ Version Example
```bash
# Using Zookeeper (3.3+ version automatically uses new modular dependencies)
java -jar openapi-generator-cli.jar generate \
-i /Users/redoom/IdeaProjects/openapi.yaml \
-g java-dubbo \
-o /Users/redoom/IdeaProjects/openapi-test \
--additional-properties=registry-address=zookeeper://127.0.0.1:2181 \
--additional-properties=dubboVersion=3.3.0 \
--additional-properties=dateLibrary=java8
# Using Nacos (3.3+ version uses nacos-client:2.5.0)
java -jar openapi-generator-cli.jar generate \
-i /Users/redoom/IdeaProjects/openapi.yaml \
-g java-dubbo \
-o /Users/redoom/IdeaProjects/openapi-test \
--additional-properties=registry-address=nacos://127.0.0.1:8848 \
--additional-properties=dubboVersion=3.3.0 \
--additional-properties=dateLibrary=java8
```
## Troubleshooting
### Common Issues
1. **Registry Connection Failed**
- Check if the registry center is started
- Verify network connection and port configuration
2. **Service Call Timeout**
- Adjust `dubbo.provider.timeout` settings
- Check network latency and service performance
3. **Serialization Exception**
- Ensure all model classes implement `Serializable` interface
- Check Jackson configuration
### Debug Logging
Enable debug mode to see detailed logs:
```yaml
logging:
level:
org.apache.dubbo: DEBUG
{{package}}: DEBUG
```
## License
This project is licensed under the [Apache License 2.0](LICENSE).
## Contributing
Issues and Pull Requests are welcome!
## Contact
{{#apiDocumentationUrl}}{{infoEmail}}{{/apiDocumentationUrl}}
---
> This project is automatically generated by OpenAPI Generator, based on Apache Dubbo microservice architecture.

View File

@ -0,0 +1,45 @@
package {{interfacePackage}};
{{#imports}}import {{import}};
{{/imports}}
{{#hasModel}}
import {{modelPackage}}.*;
{{/hasModel}}
import java.util.List;
import java.util.Map;
import java.time.OffsetDateTime;
import java.time.LocalDate;
import java.time.LocalDateTime;
{{#async}}
import java.util.concurrent.CompletableFuture;
{{/async}}
import javax.annotation.Generated;
{{>generatedAnnotation}}
{{#operations}}
public interface {{serviceName}} {
{{#operation}}
/**
* {{summary}}
* {{notes}}
*
{{#allParams}}
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}
{{/allParams}}
* @return {{#returnType}}{{{.}}}{{/returnType}}{{^returnType}}void{{/returnType}}
*/
{{#async}}
CompletableFuture<{{#returnType}}{{{.}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{nickname}}(
{{/async}}
{{^async}}
{{#returnType}}{{{.}}}{{/returnType}}{{^returnType}}void{{/returnType}} {{nickname}}(
{{/async}}
{{#allParams}}
{{{dataType}}} {{paramName}}{{^-last}},{{/-last}}
{{/allParams}}
);
{{/operation}}
}
{{/operations}}

View File

@ -0,0 +1,57 @@
package {{consumerPackage}};
{{#imports}}import {{import}};
{{/imports}}
{{#hasModel}}
import {{modelPackage}}.*;
{{/hasModel}}
{{#operations}}
import {{interfacePackage}}.{{serviceName}};
{{/operations}}
import java.util.List;
import java.util.Map;
import java.time.OffsetDateTime;
import java.time.LocalDate;
import java.time.LocalDateTime;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.*;
{{#async}}
import java.util.concurrent.CompletableFuture;
{{/async}}
import javax.annotation.Generated;
{{>generatedAnnotation}}
{{#operations}}
@RestController
@RequestMapping("/{{baseName}}")
public class {{classname}}Controller {
@DubboReference
private {{serviceName}} {{serviceVarName}};
{{#operation}}
@RequestMapping(method = RequestMethod.{{httpMethod}}, value = "{{#vendorExtensions.x-sub-path}}{{{vendorExtensions.x-sub-path}}}{{/vendorExtensions.x-sub-path}}{{^vendorExtensions.x-sub-path}}/{{/vendorExtensions.x-sub-path}}")
{{#async}}
public CompletableFuture<{{#returnType}}{{{.}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{nickname}}(
{{/async}}
{{^async}}
public {{#returnType}}{{{.}}}{{/returnType}}{{^returnType}}void{{/returnType}} {{nickname}}(
{{/async}}
{{#allParams}}
@RequestParam(name = "{{paramName}}"{{#defaultValue}}, defaultValue = "{{.}}"{{/defaultValue}}) {{{dataType}}} {{paramName}}{{^-last}},{{/-last}}
{{/allParams}}
) {
{{#async}}
return {{serviceVarName}}.{{nickname}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}});
{{/async}}
{{^async}}
{{#returnType}}return {{/returnType}}{{serviceVarName}}.{{nickname}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}});
{{/async}}
}
{{^-last}}
{{/-last}}
{{/operation}}
}
{{/operations}}

View File

@ -0,0 +1,66 @@
package {{providerPackage}};
{{#imports}}import {{import}};
{{/imports}}
{{#hasModel}}
import {{modelPackage}}.*;
{{/hasModel}}
{{#operations}}
import {{interfacePackage}}.{{serviceName}};
{{/operations}}
import java.util.List;
import java.util.Map;
import java.time.OffsetDateTime;
import java.time.LocalDate;
import java.time.LocalDateTime;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
{{#async}}
import java.util.concurrent.CompletableFuture;
{{/async}}
import javax.annotation.Generated;
{{>generatedAnnotation}}
{{#operations}}
@DubboService
public class {{serviceName}}Impl implements {{serviceName}} {
private static final Logger logger = LoggerFactory.getLogger({{serviceName}}Impl.class);
{{#operation}}
@Override
{{#async}}
public CompletableFuture<{{#returnType}}{{{.}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{nickname}}(
{{/async}}
{{^async}}
public {{#returnType}}{{{.}}}{{/returnType}}{{^returnType}}void{{/returnType}} {{nickname}}(
{{/async}}
{{#allParams}}
{{{dataType}}} {{paramName}}{{^-last}},{{/-last}}
{{/allParams}}
) {
logger.info("Dubbo service method {{nickname}} called with parameters: {{#allParams}}{{paramName}}={}{{^-last}}, {{/-last}}{{/allParams}}"{{#allParams}}, {{paramName}}{{/allParams}});
{{#async}}
return CompletableFuture.supplyAsync(() -> {
// TODO: Implement your business logic here
// Replace this with actual implementation
return null;
});
{{/async}}
{{^async}}
// TODO: Implement your business logic here
{{#returnType}}
// Replace this with actual implementation
return null;
{{/returnType}}
{{/async}}
}
{{^-last}}
{{/-last}}
{{/operation}}
}
{{/operations}}

View File

@ -0,0 +1,20 @@
spring:
application:
name: {{artifactId}}-provider
dubbo:
application:
name: {{artifactId}}
logger: slf4j
registry:
address: {{registryAddress}}
# 协议配置
protocol:
name: tri
port: -1 # auto-increment port
logging:
level:
root: INFO
org.apache.dubbo: INFO
{{invokerPackage}}: DEBUG

View File

@ -0,0 +1,13 @@
package {{invokerPackage}};
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class {{testClassName}} {
@Test
void contextLoads() {
}
}

View File

@ -0,0 +1,6 @@
@Generated(value = "{{generatorClass}}"{{^hideGenerationTimestamp}}, date = "{{generatedDate}}"{{/hideGenerationTimestamp}}, comments = "Generator version: {{generatorVersion}}")
{{^hideGenerationTimestamp}}/**
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/{{/hideGenerationTimestamp}}

View File

@ -0,0 +1,15 @@
package {{invokerPackage}};
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@EnableDubbo(scanBasePackages = "{{invokerPackage}}")
public class {{mainClassName}} {
public static void main(String[] args) {
SpringApplication.run({{mainClassName}}.class, args);
}
}

View File

@ -0,0 +1,92 @@
package {{package}};
{{#imports}}import {{import}};
{{/imports}}
import java.util.Objects;
{{#serializableModel}}
import java.io.Serializable;
{{/serializableModel}}
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.annotation.Generated;
import java.time.*;
import java.math.*;
{{#models}}
{{#model}}
{{>generatedAnnotation}}
{{#description}}
/**
* {{.}}
*/
{{/description}}
public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}}{{^parent}}{{#serializableModel}}implements Serializable{{/serializableModel}}{{/parent}} {
{{#serializableModel}}
private static final long serialVersionUID = 1L;
{{/serializableModel}}
{{#vars}}
{{#description}}
/**
* {{.}}
*/
{{/description}}
@JsonProperty("{{baseName}}")
private {{{dataType}}} {{name}}{{#defaultValue}} = {{{.}}}{{/defaultValue}};
{{/vars}}
{{#vars}}
/**
* {{description}}
* @return {{name}}
*/
public {{{dataType}}} {{getter}}() {
return {{name}};
}
public void {{setter}}({{{dataType}}} {{name}}) {
this.{{name}} = {{name}};
}
{{/vars}}
@Override
public boolean equals(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}}){{^-last}} &&
{{/-last}}{{/vars}}{{#parent}} && super.equals(o){{/parent}};{{/hasVars}}{{^hasVars}}
return true;{{/hasVars}}
}
@Override
public int hashCode() {
return Objects.hash({{#vars}}{{name}}{{^-last}}, {{/-last}}{{/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(Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}
{{/model}}
{{/models}}

View File

@ -0,0 +1,141 @@
<?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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>{{groupId}}</groupId>
<artifactId>{{artifactId}}</artifactId>
<version>{{appVersion}}</version>
<packaging>jar</packaging>
<name>{{appName}}</name>
<description>{{appDescription}}</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>{{javaVersion}}</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<dubbo.version>{{dubboVersion}}</dubbo.version>
</properties>
<dependencies>
<!-- Spring Boot Web Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Dubbo Spring Boot Starter -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>${dubbo.version}</version>
</dependency>
<!-- Dubbo -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>
{{#isZookeeperRegistry}}
<!-- Zookeeper -->
{{#isDubbo33Plus}}
<!-- Dubbo 3.3+ -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-zookeeper</artifactId>
<version>${dubbo.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-remoting-zookeeper-curator5</artifactId>
<version>${dubbo.version}</version>
</dependency>
{{/isDubbo33Plus}}
{{^isDubbo33Plus}}
<!-- Dubbo 3.2 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
</dependency>
{{/isDubbo33Plus}}
{{/isZookeeperRegistry}}
{{#isNacosRegistry}}
<!-- Nacos -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-nacos</artifactId>
<version>${dubbo.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>{{nacosClientVersion}}</version>
</dependency>
{{/isNacosRegistry}}
{{^isZookeeperRegistry}}{{^isNacosRegistry}}
<!-- 默认使用Zookeeper -->
{{#isDubbo33Plus}}
<!-- Dubbo 3.3+ -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-zookeeper</artifactId>
<version>${dubbo.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-remoting-zookeeper-curator5</artifactId>
<version>${dubbo.version}</version>
</dependency>
{{/isDubbo33Plus}}
{{^isDubbo33Plus}}
<!-- Dubbo 3.2 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
</dependency>
{{/isDubbo33Plus}}
{{/isNacosRegistry}}{{/isZookeeperRegistry}}
<!-- Test Dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1 @@
{{#isString}}"示例字符串"{{/isString}}{{#isBoolean}}true{{/isBoolean}}{{#isInteger}}1{{/isInteger}}{{#isLong}}1L{{/isLong}}{{#isFloat}}1.0f{{/isFloat}}{{#isDouble}}1.0{{/isDouble}}{{#isBinary}}null{{/isBinary}}{{#isByteArray}}null{{/isByteArray}}{{#isDate}}null{{/isDate}}{{#isDateTime}}null{{/isDateTime}}{{#isArray}}null{{/isArray}}{{#isMap}}null{{/isMap}}{{#returnContainer}}null{{/returnContainer}}{{#isContainer}}null{{/isContainer}}{{^isPrimitiveType}}null{{/isPrimitiveType}}

View File

@ -0,0 +1,33 @@
# IMPORTANT: this file is generated with the option `openapiGeneratorIgnoreList` enabled
# (--openapi-generator-ignore-list in CLI for example) so the entries below are pre-populated based
# on the input provided by the users and this file will be overwritten every time when the option is
# enabled (which is the exact opposite of the default behaviour to not overwrite
# .openapi-generator-ignore if the file exists).
# OpenAPI Generator Ignore
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
# Use this file to prevent files from being overwritten by the generator.
# The patterns follow closely to .gitignore or .dockerignore.
# As an example, the C# client generator defines ApiClient.cs.
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
#ApiClient.cs
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
#foo/*/qux
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
#foo/**/qux
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
# You can also negate patterns with an exclamation (!).
# For example, you can ignore all files in a docs folder with the file extension .md:
#docs/*.md
# Then explicitly reverse the ignore rule for a single file:
#!docs/README.md
# The following entries are pre-populated based on the input obtained via
# the option `openapiGeneratorIgnoreList` (--openapi-generator-ignore-list in CLI for example).
# Dubbo generator explicitly disables .openapi-generator-ignore

View File

@ -0,0 +1,20 @@
README.md
pom.xml
src/main/java/org/openapitools/example/OpenAPIPetstoreApplication.java
src/main/java/org/openapitools/example/api/consumer/PetServiceController.java
src/main/java/org/openapitools/example/api/consumer/StoreServiceController.java
src/main/java/org/openapitools/example/api/consumer/UserServiceController.java
src/main/java/org/openapitools/example/api/interfaces/PetService.java
src/main/java/org/openapitools/example/api/interfaces/StoreService.java
src/main/java/org/openapitools/example/api/interfaces/UserService.java
src/main/java/org/openapitools/example/api/provider/PetServiceImpl.java
src/main/java/org/openapitools/example/api/provider/StoreServiceImpl.java
src/main/java/org/openapitools/example/api/provider/UserServiceImpl.java
src/main/java/org/openapitools/example/model/Category.java
src/main/java/org/openapitools/example/model/ModelApiResponse.java
src/main/java/org/openapitools/example/model/Order.java
src/main/java/org/openapitools/example/model/Pet.java
src/main/java/org/openapitools/example/model/Tag.java
src/main/java/org/openapitools/example/model/User.java
src/main/resources/application.yml
src/test/java/org/openapitools/example/OpenAPIPetstoreApplicationTests.java

View File

@ -0,0 +1 @@
7.16.0-SNAPSHOT

View File

@ -0,0 +1,283 @@
# OpenAPI Petstore
This is a sample server Petstore server. For this sample, you can use the api key &#x60;special-key&#x60; to test the authorization filters.
This is a microservice project based on Apache Dubbo, generated by [OpenAPI Generator](https://openapi-generator.tech).
- API version: 1.0.0
- Package version:
- Generator: org.openapitools.codegen.languages.JavaDubboServerCodegen
## Technology Stack
- **Framework**: Apache Dubbo 3.2.18
- **Java**: 8+
- **Build Tool**: Maven 3.6+
- **Registry**: zookeeper://127.0.0.1:2181
- **Serialization**: Jackson JSON
## System Requirements
Building and running this project requires:
1. Java 8+
2. Maven 3.6+
3. Registry Center (Nacos or Zookeeper)
## Quick Start
### 1. Clone and Build Project
```bash
git clone <your-repo-url>
cd openapi-dubbo-server-petstore
mvn clean compile
```
### 2. Configure Registry Center
#### Using Nacos (Recommended)
```bash
# Download and start Nacos
wget https://github.com/alibaba/nacos/releases/download/2.2.4/nacos-server-2.2.4.tar.gz
tar -xzf nacos-server-2.2.4.tar.gz
cd nacos/bin
# Linux/Mac
./startup.sh -m standalone
# Windows
startup.cmd -m standalone
```
#### Using Zookeeper (Alternative)
```bash
# Download and start Zookeeper
wget https://downloads.apache.org/zookeeper/zookeeper-3.8.2/apache-zookeeper-3.8.2-bin.tar.gz
tar -xzf apache-zookeeper-3.8.2-bin.tar.gz
cd apache-zookeeper-3.8.2-bin
cp conf/zoo_sample.cfg conf/zoo.cfg
bin/zkServer.sh start
```
### 3. Configure Application
Edit the `src/main/resources/application.yml` file:
```yaml
# Dubbo Configuration
dubbo:
application:
name: openapi-dubbo-server-petstore
registry:
# Using Nacos
address: nacos://127.0.0.1:8848
# Or using Zookeeper
# address: zookeeper://127.0.0.1:2181
protocol:
name: dubbo
port: 20880
provider:
timeout: 10000
```
### 4. Start Application
```bash
# Build project
mvn clean compile
# Run main class
mvn exec:java -Dexec.mainClass=".Application"
```
## Project Structure
```
openapi-dubbo-server-petstore/
├── src/main/java//
│ └── Application.java # Main Application Class
├── src/main/resources/
│ └── application.yml # Application Configuration
├── pom.xml # Maven Configuration
└── README.md # Project Documentation
```
## API Interfaces
### Service Interfaces
## Development Guide
### Implement Business Logic
1. Implement specific business logic in the generated `*DubboImpl.java` classes
2. Inject necessary business service dependencies
3. Handle exceptions and error scenarios
### Custom Configuration
1. **Timeout Configuration**: Adjust `dubbo.provider.timeout` in `application.yml`
2. **Thread Pool Configuration**: Configure `dubbo.provider.threads` and other parameters
3. **Serialization Configuration**: Choose appropriate serialization method
### Monitoring and Operations
1. **Health Checks**: Dubbo provides built-in health check endpoints
2. **Metrics Monitoring**: Integrate with Prometheus or other monitoring systems
3. **Log Management**: Configure appropriate log levels and output formats
## Testing
```bash
# Run unit tests
mvn test
# Run integration tests
mvn integration-test
```
## Deployment
### Development Environment
```bash
mvn spring-boot:run
```
### Production Environment
```bash
# Build production package
mvn clean package -Pprod
# Deploy using Docker
docker build -t openapi-dubbo-server-petstore:1.0.0 .
docker run -p 8080:8080 -p 20880:20880 openapi-dubbo-server-petstore:1.0.0
```
## Generator Configuration Options
This project supports the following OpenAPI Generator configuration options:
### Basic Configuration
- `title`: API service title name (Default: "OpenAPI Dubbo")
- `basePackage`: Base package name (Default: "org.openapitools")
- `configPackage`: Configuration class package name (Default: "org.openapitools.configuration")
- `dubboVersion`: Dubbo version (Default: "3.2.0")
### Generation Control
- `interfaceOnly`: Generate interfaces only, no implementation classes (Default: false)
- `serviceInterface`: Generate service interfaces (Default: true)
- `serviceImplementation`: Generate service implementations (Default: true)
- `async`: Use asynchronous methods (Default: false)
- `useTags`: Use tags to create class names (Default: true)
- `useGenericResponse`: Use generic response wrapper (Default: false)
### Registry Configuration
- `registry-address`: Registry address, supports full address format (Default: "zookeeper://127.0.0.1:2181")
- Zookeeper example: `zookeeper://127.0.0.1:2181`
- Nacos example: `nacos://127.0.0.1:8848`
#### 📋 Automatic Dependency Adaptation by Version
The generator automatically selects the correct dependencies based on Dubbo version:
**Dubbo 3.2 and earlier versions**:
- Zookeeper: `dubbo-dependencies-zookeeper` (Aggregation POM)
- Nacos: `dubbo-registry-nacos` + `nacos-client:2.2.4`
**Dubbo 3.3+ versions**:
- Zookeeper: `dubbo-registry-zookeeper` + `dubbo-remoting-zookeeper-curator5`
- Nacos: `dubbo-registry-nacos` + `nacos-client:2.5.0`
### Date-Time Library Configuration
- `dateLibrary`: Date-time library selection (Default: "java8")
- `java8`: Java 8 native JSR310 (Recommended, for JDK 1.8+)
- `java8-localdatetime`: Java 8 using LocalDateTime (For legacy applications only)
- `joda`: Joda time library (For legacy applications only)
- `legacy`: Traditional java.util.Date
### Usage Examples
#### 🔧 Dubbo 3.2 Version Example
```bash
# Using Zookeeper (3.2 version automatically uses dubbo-dependencies-zookeeper)
java -jar openapi-generator-cli.jar generate \
-i /Users/redoom/IdeaProjects/openapi.yaml \
-g java-dubbo \
-o /Users/redoom/IdeaProjects/openapi-test \
--additional-properties=registry-address=zookeeper://127.0.0.1:2181 \
--additional-properties=dubboVersion=3.2.0 \
--additional-properties=dateLibrary=java8
# Using Nacos (3.2 version uses nacos-client:2.2.4)
java -jar openapi-generator-cli.jar generate \
-i /Users/redoom/IdeaProjects/openapi.yaml \
-g java-dubbo \
-o /Users/redoom/IdeaProjects/openapi-test \
--additional-properties=registry-address=nacos://127.0.0.1:8848 \
--additional-properties=dubboVersion=3.2.0 \
--additional-properties=dateLibrary=java8
```
#### 🚀 Dubbo 3.3+ Version Example
```bash
# Using Zookeeper (3.3+ version automatically uses new modular dependencies)
java -jar openapi-generator-cli.jar generate \
-i /Users/redoom/IdeaProjects/openapi.yaml \
-g java-dubbo \
-o /Users/redoom/IdeaProjects/openapi-test \
--additional-properties=registry-address=zookeeper://127.0.0.1:2181 \
--additional-properties=dubboVersion=3.3.0 \
--additional-properties=dateLibrary=java8
# Using Nacos (3.3+ version uses nacos-client:2.5.0)
java -jar openapi-generator-cli.jar generate \
-i /Users/redoom/IdeaProjects/openapi.yaml \
-g java-dubbo \
-o /Users/redoom/IdeaProjects/openapi-test \
--additional-properties=registry-address=nacos://127.0.0.1:8848 \
--additional-properties=dubboVersion=3.3.0 \
--additional-properties=dateLibrary=java8
```
## Troubleshooting
### Common Issues
1. **Registry Connection Failed**
- Check if the registry center is started
- Verify network connection and port configuration
2. **Service Call Timeout**
- Adjust `dubbo.provider.timeout` settings
- Check network latency and service performance
3. **Serialization Exception**
- Ensure all model classes implement `Serializable` interface
- Check Jackson configuration
### Debug Logging
Enable debug mode to see detailed logs:
```yaml
logging:
level:
org.apache.dubbo: DEBUG
: DEBUG
```
## License
This project is licensed under the [Apache License 2.0](LICENSE).
## Contributing
Issues and Pull Requests are welcome!
## Contact
---
> This project is automatically generated by OpenAPI Generator, based on Apache Dubbo microservice architecture.

View File

@ -0,0 +1,87 @@
<?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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.openapitools</groupId>
<artifactId>openapi-dubbo-server-petstore</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>OpenAPI Petstore</name>
<description>This is a sample server Petstore server. For this sample, you can use the api key &#x60;special-key&#x60; to test the authorization filters.</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>17</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<dubbo.version>3.2.18</dubbo.version>
</properties>
<dependencies>
<!-- Spring Boot Web Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Dubbo Spring Boot Starter -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>${dubbo.version}</version>
</dependency>
<!-- Dubbo -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>
<!-- Zookeeper -->
<!-- Dubbo 3.2 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
</dependency>
<!-- Test Dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,15 @@
package org.openapitools.example;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@EnableDubbo(scanBasePackages = "org.openapitools.example")
public class OpenAPIPetstoreApplication {
public static void main(String[] args) {
SpringApplication.run(OpenAPIPetstoreApplication.class, args);
}
}

View File

@ -0,0 +1,86 @@
package org.openapitools.example.api.consumer;
import org.openapitools.example.model.ModelApiResponse;
import org.openapitools.example.model.Pet;
import org.openapitools.example.model.*;
import org.openapitools.example.api.interfaces.PetService;
import java.util.List;
import java.util.Map;
import java.time.OffsetDateTime;
import java.time.LocalDate;
import java.time.LocalDateTime;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Generated;
@Generated(value = "org.openapitools.codegen.languages.JavaDubboServerCodegen", comments = "Generator version: 7.16.0-SNAPSHOT")
@RestController
@RequestMapping("/pet")
public class PetServiceController {
@DubboReference
private PetService petService;
@RequestMapping(method = RequestMethod.POST, value = "/")
public Pet addPet(
@RequestParam(name = "pet") Pet pet
) {
return petService.addPet(pet);
}
@RequestMapping(method = RequestMethod.DELETE, value = "/{petId}")
public void deletePet(
@RequestParam(name = "petId") Long petId,
@RequestParam(name = "apiKey") String apiKey
) {
petService.deletePet(petId, apiKey);
}
@RequestMapping(method = RequestMethod.GET, value = "/findByStatus")
public List<Pet> findPetsByStatus(
@RequestParam(name = "status") List<String> status
) {
return petService.findPetsByStatus(status);
}
@RequestMapping(method = RequestMethod.GET, value = "/findByTags")
public List<Pet> findPetsByTags(
@RequestParam(name = "tags") List<String> tags
) {
return petService.findPetsByTags(tags);
}
@RequestMapping(method = RequestMethod.GET, value = "/{petId}")
public Pet getPetById(
@RequestParam(name = "petId") Long petId
) {
return petService.getPetById(petId);
}
@RequestMapping(method = RequestMethod.PUT, value = "/")
public Pet updatePet(
@RequestParam(name = "pet") Pet pet
) {
return petService.updatePet(pet);
}
@RequestMapping(method = RequestMethod.POST, value = "/{petId}")
public void updatePetWithForm(
@RequestParam(name = "petId") Long petId,
@RequestParam(name = "name") String name,
@RequestParam(name = "status") String status
) {
petService.updatePetWithForm(petId, name, status);
}
@RequestMapping(method = RequestMethod.POST, value = "/{petId}/uploadImage")
public ModelApiResponse uploadFile(
@RequestParam(name = "petId") Long petId,
@RequestParam(name = "additionalMetadata") String additionalMetadata,
@RequestParam(name = "_file") org.springframework.web.multipart.MultipartFile _file
) {
return petService.uploadFile(petId, additionalMetadata, _file);
}
}

View File

@ -0,0 +1,51 @@
package org.openapitools.example.api.consumer;
import org.openapitools.example.model.Order;
import org.openapitools.example.model.*;
import org.openapitools.example.api.interfaces.StoreService;
import java.util.List;
import java.util.Map;
import java.time.OffsetDateTime;
import java.time.LocalDate;
import java.time.LocalDateTime;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Generated;
@Generated(value = "org.openapitools.codegen.languages.JavaDubboServerCodegen", comments = "Generator version: 7.16.0-SNAPSHOT")
@RestController
@RequestMapping("/store")
public class StoreServiceController {
@DubboReference
private StoreService storeService;
@RequestMapping(method = RequestMethod.DELETE, value = "/order/{orderId}")
public void deleteOrder(
@RequestParam(name = "orderId") String orderId
) {
storeService.deleteOrder(orderId);
}
@RequestMapping(method = RequestMethod.GET, value = "/inventory")
public Map<String, Integer> getInventory(
) {
return storeService.getInventory();
}
@RequestMapping(method = RequestMethod.GET, value = "/order/{orderId}")
public Order getOrderById(
@RequestParam(name = "orderId") Long orderId
) {
return storeService.getOrderById(orderId);
}
@RequestMapping(method = RequestMethod.POST, value = "/order")
public Order placeOrder(
@RequestParam(name = "order") Order order
) {
return storeService.placeOrder(order);
}
}

View File

@ -0,0 +1,82 @@
package org.openapitools.example.api.consumer;
import java.time.OffsetDateTime;
import org.openapitools.example.model.User;
import org.openapitools.example.model.*;
import org.openapitools.example.api.interfaces.UserService;
import java.util.List;
import java.util.Map;
import java.time.OffsetDateTime;
import java.time.LocalDate;
import java.time.LocalDateTime;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Generated;
@Generated(value = "org.openapitools.codegen.languages.JavaDubboServerCodegen", comments = "Generator version: 7.16.0-SNAPSHOT")
@RestController
@RequestMapping("/user")
public class UserServiceController {
@DubboReference
private UserService userService;
@RequestMapping(method = RequestMethod.POST, value = "/")
public void createUser(
@RequestParam(name = "user") User user
) {
userService.createUser(user);
}
@RequestMapping(method = RequestMethod.POST, value = "/createWithArray")
public void createUsersWithArrayInput(
@RequestParam(name = "user") List<User> user
) {
userService.createUsersWithArrayInput(user);
}
@RequestMapping(method = RequestMethod.POST, value = "/createWithList")
public void createUsersWithListInput(
@RequestParam(name = "user") List<User> user
) {
userService.createUsersWithListInput(user);
}
@RequestMapping(method = RequestMethod.DELETE, value = "/{username}")
public void deleteUser(
@RequestParam(name = "username") String username
) {
userService.deleteUser(username);
}
@RequestMapping(method = RequestMethod.GET, value = "/{username}")
public User getUserByName(
@RequestParam(name = "username") String username
) {
return userService.getUserByName(username);
}
@RequestMapping(method = RequestMethod.GET, value = "/login")
public String loginUser(
@RequestParam(name = "username") String username,
@RequestParam(name = "password") String password
) {
return userService.loginUser(username, password);
}
@RequestMapping(method = RequestMethod.GET, value = "/logout")
public void logoutUser(
) {
userService.logoutUser();
}
@RequestMapping(method = RequestMethod.PUT, value = "/{username}")
public void updateUser(
@RequestParam(name = "username") String username,
@RequestParam(name = "user") User user
) {
userService.updateUser(username, user);
}
}

View File

@ -0,0 +1,115 @@
package org.openapitools.example.api.interfaces;
import org.openapitools.example.model.ModelApiResponse;
import org.openapitools.example.model.Pet;
import org.openapitools.example.model.*;
import java.util.List;
import java.util.Map;
import java.time.OffsetDateTime;
import java.time.LocalDate;
import java.time.LocalDateTime;
import javax.annotation.Generated;
@Generated(value = "org.openapitools.codegen.languages.JavaDubboServerCodegen", comments = "Generator version: 7.16.0-SNAPSHOT")
public interface PetService {
/**
* Add a new pet to the store
*
*
* @param pet Pet object that needs to be added to the store (required)
* @return Pet
*/
Pet addPet(
Pet pet
);
/**
* Deletes a pet
*
*
* @param petId Pet id to delete (required)
* @param apiKey (optional)
* @return void
*/
void deletePet(
Long petId,
String apiKey
);
/**
* Finds Pets by status
* Multiple status values can be provided with comma separated strings
*
* @param status Status values that need to be considered for filter (required)
* @return List<Pet>
*/
List<Pet> findPetsByStatus(
List<String> status
);
/**
* Finds Pets by tags
* Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
*
* @param tags Tags to filter by (required)
* @return List<Pet>
*/
List<Pet> findPetsByTags(
List<String> tags
);
/**
* Find pet by ID
* Returns a single pet
*
* @param petId ID of pet to return (required)
* @return Pet
*/
Pet getPetById(
Long petId
);
/**
* Update an existing pet
*
*
* @param pet Pet object that needs to be added to the store (required)
* @return Pet
*/
Pet updatePet(
Pet pet
);
/**
* Updates a pet in the store with form data
*
*
* @param petId ID of pet that needs to be updated (required)
* @param name Updated name of the pet (optional)
* @param status Updated status of the pet (optional)
* @return void
*/
void updatePetWithForm(
Long petId,
String name,
String status
);
/**
* uploads an image
*
*
* @param petId ID of pet to update (required)
* @param additionalMetadata Additional data to pass to server (optional)
* @param _file file to upload (optional)
* @return ModelApiResponse
*/
ModelApiResponse uploadFile(
Long petId,
String additionalMetadata,
org.springframework.web.multipart.MultipartFile _file
);
}

View File

@ -0,0 +1,58 @@
package org.openapitools.example.api.interfaces;
import org.openapitools.example.model.Order;
import org.openapitools.example.model.*;
import java.util.List;
import java.util.Map;
import java.time.OffsetDateTime;
import java.time.LocalDate;
import java.time.LocalDateTime;
import javax.annotation.Generated;
@Generated(value = "org.openapitools.codegen.languages.JavaDubboServerCodegen", comments = "Generator version: 7.16.0-SNAPSHOT")
public interface StoreService {
/**
* Delete purchase order by ID
* For valid response try integer IDs with value &lt; 1000. Anything above 1000 or nonintegers will generate API errors
*
* @param orderId ID of the order that needs to be deleted (required)
* @return void
*/
void deleteOrder(
String orderId
);
/**
* Returns pet inventories by status
* Returns a map of status codes to quantities
*
* @return Map<String, Integer>
*/
Map<String, Integer> getInventory(
);
/**
* Find purchase order by ID
* For valid response try integer IDs with value &lt;&#x3D; 5 or &gt; 10. Other values will generate exceptions
*
* @param orderId ID of pet that needs to be fetched (required)
* @return Order
*/
Order getOrderById(
Long orderId
);
/**
* Place an order for a pet
*
*
* @param order order placed for purchasing the pet (required)
* @return Order
*/
Order placeOrder(
Order order
);
}

View File

@ -0,0 +1,107 @@
package org.openapitools.example.api.interfaces;
import java.time.OffsetDateTime;
import org.openapitools.example.model.User;
import org.openapitools.example.model.*;
import java.util.List;
import java.util.Map;
import java.time.OffsetDateTime;
import java.time.LocalDate;
import java.time.LocalDateTime;
import javax.annotation.Generated;
@Generated(value = "org.openapitools.codegen.languages.JavaDubboServerCodegen", comments = "Generator version: 7.16.0-SNAPSHOT")
public interface UserService {
/**
* Create user
* This can only be done by the logged in user.
*
* @param user Created user object (required)
* @return void
*/
void createUser(
User user
);
/**
* Creates list of users with given input array
*
*
* @param user List of user object (required)
* @return void
*/
void createUsersWithArrayInput(
List<User> user
);
/**
* Creates list of users with given input array
*
*
* @param user List of user object (required)
* @return void
*/
void createUsersWithListInput(
List<User> user
);
/**
* Delete user
* This can only be done by the logged in user.
*
* @param username The name that needs to be deleted (required)
* @return void
*/
void deleteUser(
String username
);
/**
* Get user by user name
*
*
* @param username The name that needs to be fetched. Use user1 for testing. (required)
* @return User
*/
User getUserByName(
String username
);
/**
* Logs user into the system
*
*
* @param username The user name for login (required)
* @param password The password for login in clear text (required)
* @return String
*/
String loginUser(
String username,
String password
);
/**
* Logs out current logged in user session
*
*
* @return void
*/
void logoutUser(
);
/**
* Updated user
* This can only be done by the logged in user.
*
* @param username name that need to be deleted (required)
* @param user Updated user object (required)
* @return void
*/
void updateUser(
String username,
User user
);
}

View File

@ -0,0 +1,113 @@
package org.openapitools.example.api.provider;
import org.openapitools.example.model.ModelApiResponse;
import org.openapitools.example.model.Pet;
import org.openapitools.example.model.*;
import org.openapitools.example.api.interfaces.PetService;
import java.util.List;
import java.util.Map;
import java.time.OffsetDateTime;
import java.time.LocalDate;
import java.time.LocalDateTime;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Generated;
@Generated(value = "org.openapitools.codegen.languages.JavaDubboServerCodegen", comments = "Generator version: 7.16.0-SNAPSHOT")
@DubboService
public class PetServiceImpl implements PetService {
private static final Logger logger = LoggerFactory.getLogger(PetServiceImpl.class);
@Override
public Pet addPet(
Pet pet
) {
logger.info("Dubbo service method addPet called with parameters: pet={}", pet);
// TODO: Implement your business logic here
// Replace this with actual implementation
return null;
}
@Override
public void deletePet(
Long petId,
String apiKey
) {
logger.info("Dubbo service method deletePet called with parameters: petId={}, apiKey={}", petId, apiKey);
// TODO: Implement your business logic here
}
@Override
public List<Pet> findPetsByStatus(
List<String> status
) {
logger.info("Dubbo service method findPetsByStatus called with parameters: status={}", status);
// TODO: Implement your business logic here
// Replace this with actual implementation
return null;
}
@Override
public List<Pet> findPetsByTags(
List<String> tags
) {
logger.info("Dubbo service method findPetsByTags called with parameters: tags={}", tags);
// TODO: Implement your business logic here
// Replace this with actual implementation
return null;
}
@Override
public Pet getPetById(
Long petId
) {
logger.info("Dubbo service method getPetById called with parameters: petId={}", petId);
// TODO: Implement your business logic here
// Replace this with actual implementation
return null;
}
@Override
public Pet updatePet(
Pet pet
) {
logger.info("Dubbo service method updatePet called with parameters: pet={}", pet);
// TODO: Implement your business logic here
// Replace this with actual implementation
return null;
}
@Override
public void updatePetWithForm(
Long petId,
String name,
String status
) {
logger.info("Dubbo service method updatePetWithForm called with parameters: petId={}, name={}, status={}", petId, name, status);
// TODO: Implement your business logic here
}
@Override
public ModelApiResponse uploadFile(
Long petId,
String additionalMetadata,
org.springframework.web.multipart.MultipartFile _file
) {
logger.info("Dubbo service method uploadFile called with parameters: petId={}, additionalMetadata={}, _file={}", petId, additionalMetadata, _file);
// TODO: Implement your business logic here
// Replace this with actual implementation
return null;
}
}

View File

@ -0,0 +1,64 @@
package org.openapitools.example.api.provider;
import org.openapitools.example.model.Order;
import org.openapitools.example.model.*;
import org.openapitools.example.api.interfaces.StoreService;
import java.util.List;
import java.util.Map;
import java.time.OffsetDateTime;
import java.time.LocalDate;
import java.time.LocalDateTime;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Generated;
@Generated(value = "org.openapitools.codegen.languages.JavaDubboServerCodegen", comments = "Generator version: 7.16.0-SNAPSHOT")
@DubboService
public class StoreServiceImpl implements StoreService {
private static final Logger logger = LoggerFactory.getLogger(StoreServiceImpl.class);
@Override
public void deleteOrder(
String orderId
) {
logger.info("Dubbo service method deleteOrder called with parameters: orderId={}", orderId);
// TODO: Implement your business logic here
}
@Override
public Map<String, Integer> getInventory(
) {
logger.info("Dubbo service method getInventory called with parameters: ");
// TODO: Implement your business logic here
// Replace this with actual implementation
return null;
}
@Override
public Order getOrderById(
Long orderId
) {
logger.info("Dubbo service method getOrderById called with parameters: orderId={}", orderId);
// TODO: Implement your business logic here
// Replace this with actual implementation
return null;
}
@Override
public Order placeOrder(
Order order
) {
logger.info("Dubbo service method placeOrder called with parameters: order={}", order);
// TODO: Implement your business logic here
// Replace this with actual implementation
return null;
}
}

View File

@ -0,0 +1,101 @@
package org.openapitools.example.api.provider;
import java.time.OffsetDateTime;
import org.openapitools.example.model.User;
import org.openapitools.example.model.*;
import org.openapitools.example.api.interfaces.UserService;
import java.util.List;
import java.util.Map;
import java.time.OffsetDateTime;
import java.time.LocalDate;
import java.time.LocalDateTime;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Generated;
@Generated(value = "org.openapitools.codegen.languages.JavaDubboServerCodegen", comments = "Generator version: 7.16.0-SNAPSHOT")
@DubboService
public class UserServiceImpl implements UserService {
private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
@Override
public void createUser(
User user
) {
logger.info("Dubbo service method createUser called with parameters: user={}", user);
// TODO: Implement your business logic here
}
@Override
public void createUsersWithArrayInput(
List<User> user
) {
logger.info("Dubbo service method createUsersWithArrayInput called with parameters: user={}", user);
// TODO: Implement your business logic here
}
@Override
public void createUsersWithListInput(
List<User> user
) {
logger.info("Dubbo service method createUsersWithListInput called with parameters: user={}", user);
// TODO: Implement your business logic here
}
@Override
public void deleteUser(
String username
) {
logger.info("Dubbo service method deleteUser called with parameters: username={}", username);
// TODO: Implement your business logic here
}
@Override
public User getUserByName(
String username
) {
logger.info("Dubbo service method getUserByName called with parameters: username={}", username);
// TODO: Implement your business logic here
// Replace this with actual implementation
return null;
}
@Override
public String loginUser(
String username,
String password
) {
logger.info("Dubbo service method loginUser called with parameters: username={}, password={}", username, password);
// TODO: Implement your business logic here
// Replace this with actual implementation
return null;
}
@Override
public void logoutUser(
) {
logger.info("Dubbo service method logoutUser called with parameters: ");
// TODO: Implement your business logic here
}
@Override
public void updateUser(
String username,
User user
) {
logger.info("Dubbo service method updateUser called with parameters: username={}, user={}", username, user);
// TODO: Implement your business logic here
}
}

View File

@ -0,0 +1,87 @@
package org.openapitools.example.model;
import java.util.Objects;
import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.annotation.Generated;
import java.time.*;
import java.math.*;
@Generated(value = "org.openapitools.codegen.languages.JavaDubboServerCodegen", comments = "Generator version: 7.16.0-SNAPSHOT")
/**
* A category for a pet
*/
public class Category implements Serializable {
private static final long serialVersionUID = 1L;
@JsonProperty("id")
private Long id;
@JsonProperty("name")
private String name;
/**
*
* @return id
*/
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
/**
*
* @return name
*/
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Category category = (Category) o;
return Objects.equals(this.id, category.id) &&
Objects.equals(this.name, category.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class Category {\n");
sb.append(" id: ").append(toIndentedString(id)).append("\n");
sb.append(" name: ").append(toIndentedString(name)).append("\n");
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(Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}

View File

@ -0,0 +1,104 @@
package org.openapitools.example.model;
import java.util.Objects;
import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.annotation.Generated;
import java.time.*;
import java.math.*;
@Generated(value = "org.openapitools.codegen.languages.JavaDubboServerCodegen", comments = "Generator version: 7.16.0-SNAPSHOT")
/**
* Describes the result of uploading an image resource
*/
public class ModelApiResponse implements Serializable {
private static final long serialVersionUID = 1L;
@JsonProperty("code")
private Integer code;
@JsonProperty("type")
private String type;
@JsonProperty("message")
private String message;
/**
*
* @return code
*/
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
/**
*
* @return type
*/
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
/**
*
* @return message
*/
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ModelApiResponse _apiResponse = (ModelApiResponse) o;
return Objects.equals(this.code, _apiResponse.code) &&
Objects.equals(this.type, _apiResponse.type) &&
Objects.equals(this.message, _apiResponse.message);
}
@Override
public int hashCode() {
return Objects.hash(code, type, message);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class ModelApiResponse {\n");
sb.append(" code: ").append(toIndentedString(code)).append("\n");
sb.append(" type: ").append(toIndentedString(type)).append("\n");
sb.append(" message: ").append(toIndentedString(message)).append("\n");
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(Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}

View File

@ -0,0 +1,159 @@
package org.openapitools.example.model;
import java.time.OffsetDateTime;
import java.util.Objects;
import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.annotation.Generated;
import java.time.*;
import java.math.*;
@Generated(value = "org.openapitools.codegen.languages.JavaDubboServerCodegen", comments = "Generator version: 7.16.0-SNAPSHOT")
/**
* An order for a pets from the pet store
*/
public class Order implements Serializable {
private static final long serialVersionUID = 1L;
@JsonProperty("id")
private Long id;
@JsonProperty("petId")
private Long petId;
@JsonProperty("quantity")
private Integer quantity;
@JsonProperty("shipDate")
private OffsetDateTime shipDate;
/**
* Order Status
*/
@JsonProperty("status")
private String status;
@JsonProperty("complete")
private Boolean complete = false;
/**
*
* @return id
*/
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
/**
*
* @return petId
*/
public Long getPetId() {
return petId;
}
public void setPetId(Long petId) {
this.petId = petId;
}
/**
*
* @return quantity
*/
public Integer getQuantity() {
return quantity;
}
public void setQuantity(Integer quantity) {
this.quantity = quantity;
}
/**
*
* @return shipDate
*/
public OffsetDateTime getShipDate() {
return shipDate;
}
public void setShipDate(OffsetDateTime shipDate) {
this.shipDate = shipDate;
}
/**
* Order Status
* @return status
*/
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
/**
*
* @return complete
*/
public Boolean getComplete() {
return complete;
}
public void setComplete(Boolean complete) {
this.complete = complete;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Order order = (Order) o;
return Objects.equals(this.id, order.id) &&
Objects.equals(this.petId, order.petId) &&
Objects.equals(this.quantity, order.quantity) &&
Objects.equals(this.shipDate, order.shipDate) &&
Objects.equals(this.status, order.status) &&
Objects.equals(this.complete, order.complete);
}
@Override
public int hashCode() {
return Objects.hash(id, petId, quantity, shipDate, status, complete);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class Order {\n");
sb.append(" id: ").append(toIndentedString(id)).append("\n");
sb.append(" petId: ").append(toIndentedString(petId)).append("\n");
sb.append(" quantity: ").append(toIndentedString(quantity)).append("\n");
sb.append(" shipDate: ").append(toIndentedString(shipDate)).append("\n");
sb.append(" status: ").append(toIndentedString(status)).append("\n");
sb.append(" complete: ").append(toIndentedString(complete)).append("\n");
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(Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}

View File

@ -0,0 +1,161 @@
package org.openapitools.example.model;
import org.openapitools.example.model.Category;
import org.openapitools.example.model.Tag;
import java.util.*;
import java.util.Objects;
import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.annotation.Generated;
import java.time.*;
import java.math.*;
@Generated(value = "org.openapitools.codegen.languages.JavaDubboServerCodegen", comments = "Generator version: 7.16.0-SNAPSHOT")
/**
* A pet for sale in the pet store
*/
public class Pet implements Serializable {
private static final long serialVersionUID = 1L;
@JsonProperty("id")
private Long id;
@JsonProperty("category")
private Category category;
@JsonProperty("name")
private String name;
@JsonProperty("photoUrls")
private List<String> photoUrls = new ArrayList<>();
@JsonProperty("tags")
private List<Tag> tags = new ArrayList<>();
/**
* pet status in the store
*/
@JsonProperty("status")
private String status;
/**
*
* @return id
*/
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
/**
*
* @return category
*/
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
/**
*
* @return name
*/
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
*
* @return photoUrls
*/
public List<String> getPhotoUrls() {
return photoUrls;
}
public void setPhotoUrls(List<String> photoUrls) {
this.photoUrls = photoUrls;
}
/**
*
* @return tags
*/
public List<Tag> getTags() {
return tags;
}
public void setTags(List<Tag> tags) {
this.tags = tags;
}
/**
* pet status in the store
* @return status
*/
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Pet pet = (Pet) o;
return Objects.equals(this.id, pet.id) &&
Objects.equals(this.category, pet.category) &&
Objects.equals(this.name, pet.name) &&
Objects.equals(this.photoUrls, pet.photoUrls) &&
Objects.equals(this.tags, pet.tags) &&
Objects.equals(this.status, pet.status);
}
@Override
public int hashCode() {
return Objects.hash(id, category, name, photoUrls, tags, status);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class Pet {\n");
sb.append(" id: ").append(toIndentedString(id)).append("\n");
sb.append(" category: ").append(toIndentedString(category)).append("\n");
sb.append(" name: ").append(toIndentedString(name)).append("\n");
sb.append(" photoUrls: ").append(toIndentedString(photoUrls)).append("\n");
sb.append(" tags: ").append(toIndentedString(tags)).append("\n");
sb.append(" status: ").append(toIndentedString(status)).append("\n");
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(Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}

View File

@ -0,0 +1,87 @@
package org.openapitools.example.model;
import java.util.Objects;
import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.annotation.Generated;
import java.time.*;
import java.math.*;
@Generated(value = "org.openapitools.codegen.languages.JavaDubboServerCodegen", comments = "Generator version: 7.16.0-SNAPSHOT")
/**
* A tag for a pet
*/
public class Tag implements Serializable {
private static final long serialVersionUID = 1L;
@JsonProperty("id")
private Long id;
@JsonProperty("name")
private String name;
/**
*
* @return id
*/
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
/**
*
* @return name
*/
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Tag tag = (Tag) o;
return Objects.equals(this.id, tag.id) &&
Objects.equals(this.name, tag.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class Tag {\n");
sb.append(" id: ").append(toIndentedString(id)).append("\n");
sb.append(" name: ").append(toIndentedString(name)).append("\n");
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(Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}

View File

@ -0,0 +1,192 @@
package org.openapitools.example.model;
import java.util.Objects;
import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.annotation.Generated;
import java.time.*;
import java.math.*;
@Generated(value = "org.openapitools.codegen.languages.JavaDubboServerCodegen", comments = "Generator version: 7.16.0-SNAPSHOT")
/**
* A User who is purchasing from the pet store
*/
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@JsonProperty("id")
private Long id;
@JsonProperty("username")
private String username;
@JsonProperty("firstName")
private String firstName;
@JsonProperty("lastName")
private String lastName;
@JsonProperty("email")
private String email;
@JsonProperty("password")
private String password;
@JsonProperty("phone")
private String phone;
/**
* User Status
*/
@JsonProperty("userStatus")
private Integer userStatus;
/**
*
* @return id
*/
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
/**
*
* @return username
*/
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
/**
*
* @return firstName
*/
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
/**
*
* @return lastName
*/
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
/**
*
* @return email
*/
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
/**
*
* @return password
*/
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
/**
*
* @return phone
*/
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
/**
* User Status
* @return userStatus
*/
public Integer getUserStatus() {
return userStatus;
}
public void setUserStatus(Integer userStatus) {
this.userStatus = userStatus;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
User user = (User) o;
return Objects.equals(this.id, user.id) &&
Objects.equals(this.username, user.username) &&
Objects.equals(this.firstName, user.firstName) &&
Objects.equals(this.lastName, user.lastName) &&
Objects.equals(this.email, user.email) &&
Objects.equals(this.password, user.password) &&
Objects.equals(this.phone, user.phone) &&
Objects.equals(this.userStatus, user.userStatus);
}
@Override
public int hashCode() {
return Objects.hash(id, username, firstName, lastName, email, password, phone, userStatus);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class User {\n");
sb.append(" id: ").append(toIndentedString(id)).append("\n");
sb.append(" username: ").append(toIndentedString(username)).append("\n");
sb.append(" firstName: ").append(toIndentedString(firstName)).append("\n");
sb.append(" lastName: ").append(toIndentedString(lastName)).append("\n");
sb.append(" email: ").append(toIndentedString(email)).append("\n");
sb.append(" password: ").append(toIndentedString(password)).append("\n");
sb.append(" phone: ").append(toIndentedString(phone)).append("\n");
sb.append(" userStatus: ").append(toIndentedString(userStatus)).append("\n");
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(Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}

View File

@ -0,0 +1,20 @@
spring:
application:
name: openapi-dubbo-server-petstore-provider
dubbo:
application:
name: openapi-dubbo-server-petstore
logger: slf4j
registry:
address: zookeeper://127.0.0.1:2181
# 协议配置
protocol:
name: tri
port: -1 # auto-increment port
logging:
level:
root: INFO
org.apache.dubbo: INFO
org.openapitools.example: DEBUG

View File

@ -0,0 +1,13 @@
package org.openapitools.example;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class OpenAPIPetstoreApplicationTests {
@Test
void contextLoads() {
}
}