You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2020/11/27 01:37:25 UTC

[servicecomb-java-chassis] branch master updated: Scb 2128 support dynamic single value enum (#2080)

This is an automated email from the ASF dual-hosted git repository.

liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git


The following commit(s) were added to refs/heads/master by this push:
     new 4f58467  Scb 2128 support dynamic single value enum (#2080)
4f58467 is described below

commit 4f5846753c83e184aaecd87a713a47b74810e473
Author: wujimin <wu...@huawei.com>
AuthorDate: Fri Nov 27 09:37:18 2020 +0800

    Scb 2128 support dynamic single value enum (#2080)
    
    * [SCB-2128] support dynamic single value enum
    
    * [SCB-2128] enhance swagger generator of jdk enum and dynamic enum
---
 .../demo/springmvc/server/CodeFirstSpringmvc.java  |   2 +-
 .../foundation/common/base/DynamicEnum.java        |  42 +++++----
 .../foundation/common/base/DynamicEnumCache.java   |  82 ++++++++++++++++
 .../foundation/common/base/EnumUtils.java          |  46 +++++++++
 .../foundation/common/base/DynamicEnumTest.java    |  87 +++++++++++++++++
 .../deserializer/scalar/EnumsReadSchemas.java      |  20 ++++
 .../schema/serializer/scalar/EnumWriteSchemas.java |   7 ++
 .../apache/servicecomb/it/schema/DynamicColor.java |  42 +++++++++
 .../apache/servicecomb/it/junit/ITJUnitUtils.java  |   4 +
 .../it/testcase/TestDataTypePrimitive.java         |  37 ++++++++
 .../servicecomb/it/schema/DataTypeJaxrsSchema.java |  12 +++
 .../servicecomb/it/schema/DataTypePojoSchema.java  |   4 +
 .../apache/servicecomb/swagger/SwaggerUtils.java   |  14 ++-
 .../swagger/extend/ModelResolverExt.java           |  27 ++++++
 .../swagger/extend/PropertyModelConverterExt.java  |  59 ++++++++++++
 .../servicecomb/swagger/extend/SwaggerEnum.java    | 103 +++++++++++++++++++++
 .../introspector/JsonPropertyIntrospector.java     |  17 +++-
 .../core/processor/annotation/AnnotationUtils.java |   4 +-
 .../processor/parameter/EnumPostProcessor.java     |  93 +++++++++++++++++++
 .../response/DefaultResponseTypeProcessor.java     |   4 +-
 ...cecomb.swagger.generator.OperationPostProcessor |  18 ++++
 .../src/test/resources/schemas/allMethod.yaml      |   1 +
 .../src/test/resources/schemas/allType.yaml        |   1 +
 .../src/test/resources/schemas/multiParam.yaml     |   1 +
 .../servicecomb/swagger/generator/jaxrs/Echo.java  |  25 ++++-
 .../swagger/generator/jaxrs/TestJaxrs.java         |  10 ++
 .../generator/jaxrs/model/enums/DynamicStatus.java |  43 +++++++++
 .../jaxrs/model/enums/DynamicStatusBeanParam.java  |  27 ++++++
 .../jaxrs/model/enums/DynamicStatusModel.java      |  24 +++++
 .../generator/jaxrs/model/enums/JdkStatus.java     |  27 ++++++
 .../jaxrs/model/enums/JdkStatusBeanParam.java      |  27 ++++++
 .../jaxrs/model/enums/JdkStatusModel.java          |  24 +++++
 .../test/resources/schemas/dynamicStatusEnum.yaml  |  81 ++++++++++++++++
 .../src/test/resources/schemas/jdkStatusEnum.yaml  |  78 ++++++++++++++++
 34 files changed, 1065 insertions(+), 28 deletions(-)

diff --git a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java
index 3ffe1a3..52fbe6d 100644
--- a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java
+++ b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java
@@ -335,7 +335,7 @@ public class CodeFirstSpringmvc {
     return name;
   }
 
-  enum NameType {
+  public enum NameType {
     abc,
     def
   }
diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/introspector/JsonPropertyIntrospector.java b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/base/DynamicEnum.java
similarity index 50%
copy from swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/introspector/JsonPropertyIntrospector.java
copy to foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/base/DynamicEnum.java
index 0c55074..7889332 100644
--- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/introspector/JsonPropertyIntrospector.java
+++ b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/base/DynamicEnum.java
@@ -14,30 +14,38 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.servicecomb.foundation.common.base;
 
-package org.apache.servicecomb.swagger.extend.introspector;
+import java.util.Objects;
 
-import org.apache.commons.lang3.StringUtils;
+import com.fasterxml.jackson.annotation.JsonValue;
 
-import com.fasterxml.jackson.annotation.JsonProperty;
+public abstract class DynamicEnum<T> {
+  private T value;
 
-import io.swagger.jackson.SwaggerAnnotationIntrospector;
-
-public class JsonPropertyIntrospector extends SwaggerAnnotationIntrospector {
+  public DynamicEnum(T value) {
+    this.value = value;
+  }
 
-  private static final long serialVersionUID = 4157263023893695762L;
+  @JsonValue
+  public T getValue() {
+    return value;
+  }
 
-  @SuppressWarnings("deprecation")
   @Override
-  public String findEnumValue(Enum<?> value) {
-    try {
-      JsonProperty annotation = value.getClass().getField(value.name()).getAnnotation(JsonProperty.class);
-      if (null == annotation || StringUtils.isEmpty(annotation.value())) {
-        return super.findEnumValue(value);
-      }
-      return annotation.value();
-    } catch (NoSuchFieldException e) {
-      return super.findEnumValue(value);
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
     }
+    DynamicEnum<?> that = (DynamicEnum<?>) o;
+    return Objects.equals(value, that.value);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(value);
   }
 }
diff --git a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/base/DynamicEnumCache.java b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/base/DynamicEnumCache.java
new file mode 100644
index 0000000..ff50aa5
--- /dev/null
+++ b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/base/DynamicEnumCache.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.foundation.common.base;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.ParameterizedType;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DynamicEnumCache<T extends DynamicEnum<?>> {
+  private static final Logger LOGGER = LoggerFactory.getLogger(DynamicEnumCache.class);
+
+  private final Class<T> cls;
+
+  private final Map<Object, T> values;
+
+  /**
+   *
+   * @param cls
+   */
+  private final Constructor<T> constructor;
+
+  public DynamicEnumCache(Class<T> cls) {
+    try {
+      this.cls = cls;
+      this.constructor = initFactory();
+      this.values = initValues();
+    } catch (Exception e) {
+      throw new IllegalStateException("failed to init dynamic enum, class=" + cls.getName(), e);
+    }
+  }
+
+  private Constructor<T> initFactory() throws NoSuchMethodException {
+    ParameterizedType superClass = (ParameterizedType) cls.getGenericSuperclass();
+    Class<?> argument = (Class<?>) superClass.getActualTypeArguments()[0];
+    return cls.getConstructor(argument);
+  }
+
+  @SuppressWarnings("unchecked")
+  private Map<Object, T> initValues() {
+    Map<Object, T> values = new LinkedHashMap<>();
+    EnumUtils.findEnumFields(cls)
+        .map(field -> (T) EnumUtils.readEnum(field))
+        .forEach(oneEnum -> values.put(oneEnum.getValue(), oneEnum));
+    return Collections.unmodifiableMap(values);
+  }
+
+  public T fromValue(Object value) {
+    if (value == null) {
+      return null;
+    }
+
+    T instance = values.get(value);
+    try {
+      // do not cache unknown value to avoid attach
+      // if need to cache unknown value, should avoid cache too many values
+      return instance != null ? instance : constructor.newInstance(value);
+    } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
+      LOGGER.error("failed to create enum, class={}, value={}.", cls.getName(), value);
+      return null;
+    }
+  }
+}
diff --git a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/base/EnumUtils.java b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/base/EnumUtils.java
new file mode 100644
index 0000000..e845bc3
--- /dev/null
+++ b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/base/EnumUtils.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.foundation.common.base;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.stream.Stream;
+
+public interface EnumUtils {
+  @SuppressWarnings("unchecked")
+  static <T> T readEnum(Field enumField) {
+    try {
+      return (T) enumField.get(null);
+    } catch (IllegalAccessException e) {
+      throw new IllegalStateException("failed to read enum, field=" + enumField, e);
+    }
+  }
+
+  static boolean isEnumField(Class<?> cls, Field field) {
+    return Modifier.isStatic(field.getModifiers()) && cls.equals(field.getType());
+  }
+
+  static Stream<Field> findEnumFields(Class<?> cls) {
+    return Arrays.stream(cls.getFields())
+        .filter(field -> isEnumField(cls, field));
+  }
+
+  static boolean isDynamicEnum(Class<?> cls) {
+    return DynamicEnum.class.isAssignableFrom(cls);
+  }
+}
diff --git a/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/base/DynamicEnumTest.java b/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/base/DynamicEnumTest.java
new file mode 100644
index 0000000..91d1e2c
--- /dev/null
+++ b/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/base/DynamicEnumTest.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.foundation.common.base;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+
+import io.vertx.core.json.Json;
+import io.vertx.core.json.jackson.DatabindCodec;
+
+class DynamicEnumTest {
+  static final String UNKNOWN_COLOR = "\"UNKNOWN-COLOR\"";
+
+  static class Color extends DynamicEnum<String> {
+    public static final Color RED = new Color("RED");
+
+    public static final Color BLUE = new Color("BLUE");
+
+    private static final DynamicEnumCache<Color> CACHE = new DynamicEnumCache<>(Color.class);
+
+    public Color(String value) {
+      super(value);
+    }
+
+    @JsonCreator
+    public static Color fromValue(String value) {
+      return CACHE.fromValue(value);
+    }
+  }
+
+  static class ColorModel {
+    public Color color;
+  }
+
+  @Test
+  void should_encode() {
+    assertThat(Json.encode(Color.RED)).isEqualTo("\"RED\"");
+  }
+
+  @Test
+  void should_be_null_when_convert_from_null() {
+    assertThat(DatabindCodec.mapper().convertValue(null, Color.class)).isNull();
+  }
+
+  @Test
+  void should_be_null_when_decode_from_null() {
+    ColorModel model = Json.decodeValue(Json.encode(new ColorModel()), ColorModel.class);
+    assertThat(model.color).isNull();
+  }
+
+  @Test
+  void should_decode_from_known_value() {
+    Color color = Json.decodeValue(Json.encode(Color.RED), Color.class);
+    assertThat(color).isEqualTo(Color.RED);
+  }
+
+  @Test
+  void should_decode_from_unknown_value() {
+    Color color = Json.decodeValue(UNKNOWN_COLOR, Color.class);
+    assertThat(color).isEqualTo(Color.fromValue("UNKNOWN-COLOR"));
+  }
+
+  @Test
+  void should_not_cache_unknown_value() {
+    Color value1 = Json.decodeValue(UNKNOWN_COLOR, Color.class);
+    Color value2 = Json.decodeValue(UNKNOWN_COLOR, Color.class);
+    assertThat(value1).isNotSameAs(value2);
+  }
+}
\ No newline at end of file
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/scalar/EnumsReadSchemas.java b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/scalar/EnumsReadSchemas.java
index 1ca9fed..64022ac 100644
--- a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/scalar/EnumsReadSchemas.java
+++ b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/scalar/EnumsReadSchemas.java
@@ -18,6 +18,7 @@ package org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.
 
 import java.io.IOException;
 
+import org.apache.servicecomb.foundation.common.base.DynamicEnum;
 import org.apache.servicecomb.foundation.common.utils.bean.IntSetter;
 import org.apache.servicecomb.foundation.common.utils.bean.Setter;
 import org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;
@@ -46,6 +47,10 @@ public class EnumsReadSchemas {
       return new IntPrimitiveEnumSchema<>(protoField, propertyDescriptor);
     }
 
+    if (javaType.isTypeOrSubTypeOf(DynamicEnum.class)) {
+      return new DynamicEnumSchema<>(protoField, propertyDescriptor);
+    }
+
     ProtoUtils.throwNotSupportMerge(protoField, propertyDescriptor.getJavaType());
     return null;
   }
@@ -79,6 +84,21 @@ public class EnumsReadSchemas {
     }
   }
 
+  private static class DynamicEnumSchema<T> extends FieldSchema<T> {
+    public DynamicEnumSchema(Field protoField, PropertyDescriptor propertyDescriptor) {
+      super(protoField, propertyDescriptor.getJavaType());
+    }
+
+    @Override
+    public int mergeFrom(InputEx input, T message) throws IOException {
+      throw new IllegalStateException(
+          String.format("currently, protobuf not support dynamic enum, type=%s, proto field=%s:%s",
+              javaType.getRawClass().getName(),
+              ((Type) protoField.getParent()).getCanonicalName(),
+              protoField.getName()));
+    }
+  }
+
   private static class IntEnumSchema<T> extends FieldSchema<T> {
     private final Setter<T, Integer> setter;
 
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/scalar/EnumWriteSchemas.java b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/scalar/EnumWriteSchemas.java
index b7d0754..071c68e 100644
--- a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/scalar/EnumWriteSchemas.java
+++ b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/scalar/EnumWriteSchemas.java
@@ -18,6 +18,7 @@ package org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.sc
 
 import java.io.IOException;
 
+import org.apache.servicecomb.foundation.common.base.DynamicEnum;
 import org.apache.servicecomb.foundation.common.utils.bean.Getter;
 import org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;
 import org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;
@@ -80,6 +81,12 @@ public class EnumWriteSchemas {
         return;
       }
 
+      if (value instanceof DynamicEnum) {
+        // protobuf can not support unknown enum, because protobuf encode enum as tag value
+        writeTo(output, ((DynamicEnum<?>) value).getValue());
+        return;
+      }
+
       if (value instanceof Number) {
         // need to check if it is a valid number
         // because maybe come from http request
diff --git a/integration-tests/it-common/src/main/java/org/apache/servicecomb/it/schema/DynamicColor.java b/integration-tests/it-common/src/main/java/org/apache/servicecomb/it/schema/DynamicColor.java
new file mode 100644
index 0000000..c1d394a
--- /dev/null
+++ b/integration-tests/it-common/src/main/java/org/apache/servicecomb/it/schema/DynamicColor.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.it.schema;
+
+import org.apache.servicecomb.foundation.common.base.DynamicEnum;
+import org.apache.servicecomb.foundation.common.base.DynamicEnumCache;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+
+public class DynamicColor extends DynamicEnum<String> {
+  public static final DynamicColor RED = new DynamicColor("RED");
+
+  public static final DynamicColor YELLOW = new DynamicColor("YELLOW");
+
+  public static final DynamicColor BLUE = new DynamicColor("BLUE");
+
+  private static final DynamicEnumCache<DynamicColor> CACHE = new DynamicEnumCache<>(DynamicColor.class);
+
+  public DynamicColor(String value) {
+    super(value);
+  }
+
+  @JsonCreator
+  public static DynamicColor fromValue(String value) {
+    return CACHE.fromValue(value);
+  }
+}
diff --git a/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/junit/ITJUnitUtils.java b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/junit/ITJUnitUtils.java
index fbf0b7c..4b7f207 100644
--- a/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/junit/ITJUnitUtils.java
+++ b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/junit/ITJUnitUtils.java
@@ -215,4 +215,8 @@ public final class ITJUnitUtils {
       throw new IllegalStateException(e);
     }
   }
+
+  public static boolean isRestTransport() {
+    return Const.RESTFUL.equals(transport);
+  }
 }
diff --git a/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/testcase/TestDataTypePrimitive.java b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/testcase/TestDataTypePrimitive.java
index 0f0eae8..3d89740 100644
--- a/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/testcase/TestDataTypePrimitive.java
+++ b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/testcase/TestDataTypePrimitive.java
@@ -26,6 +26,7 @@ import org.apache.servicecomb.foundation.test.scaffolding.model.Color;
 import org.apache.servicecomb.it.Consumers;
 import org.apache.servicecomb.it.extend.engine.ITSCBRestTemplate;
 import org.apache.servicecomb.it.junit.ITJUnitUtils;
+import org.apache.servicecomb.it.schema.DynamicColor;
 import org.junit.Test;
 import org.springframework.http.HttpEntity;
 import org.springframework.http.HttpHeaders;
@@ -52,6 +53,8 @@ public class TestDataTypePrimitive {
     float floatAdd(float num1, float num2);
 
     Color enumBody(Color color);
+
+    DynamicColor dynamicEnum(DynamicColor color);
   }
 
   public interface DataTypeRestIntf {
@@ -117,6 +120,8 @@ public class TestDataTypePrimitive {
     // enum
     Color enumBody(Color color);
 
+    DynamicColor dynamicEnum(DynamicColor color);
+
     // query array
     String queryArr(String[] queryArr);
 
@@ -226,6 +231,13 @@ public class TestDataTypePrimitive {
   }
 
   @Test
+  public void dynamic_enum_pojo_intf() {
+    if (ITJUnitUtils.isRestTransport()) {
+      assertEquals(DynamicColor.BLUE, consumersPojo.getIntf().dynamicEnum(DynamicColor.BLUE));
+    }
+  }
+
+  @Test
   public void enumBody_pojo_rt() {
     Map<String, Color> body = new HashMap<>();
     body.put("color", Color.BLUE);
@@ -234,6 +246,16 @@ public class TestDataTypePrimitive {
   }
 
   @Test
+  public void dynamic_enum_pojo_rt() {
+    if (ITJUnitUtils.isRestTransport()) {
+      Map<String, DynamicColor> body = new HashMap<>();
+      body.put("color", DynamicColor.BLUE);
+      assertEquals(DynamicColor.BLUE,
+          consumersPojo.getSCBRestTemplate().postForObject("/dynamicEnum", body, DynamicColor.class));
+    }
+  }
+
+  @Test
   public void intPath_jaxrs_intf() {
     assertEquals(10, consumersJaxrs.getIntf().intPath(10));
   }
@@ -588,12 +610,27 @@ public class TestDataTypePrimitive {
   }
 
   @Test
+  public void dynamic_enum_jaxrs_intf() {
+    if (ITJUnitUtils.isRestTransport()) {
+      assertEquals(DynamicColor.BLUE, consumersJaxrs.getIntf().dynamicEnum(DynamicColor.BLUE));
+    }
+  }
+
+  @Test
   public void enumBody_jaxrs_rt() {
     assertEquals(Color.BLUE,
         consumersJaxrs.getSCBRestTemplate().postForObject("/enumBody", Color.BLUE, Color.class));
   }
 
   @Test
+  public void dynamic_enum_jaxrs_rt() {
+    if (ITJUnitUtils.isRestTransport()) {
+      assertEquals(DynamicColor.BLUE,
+          consumersJaxrs.getSCBRestTemplate().postForObject("/dynamicEnum", DynamicColor.BLUE, DynamicColor.class));
+    }
+  }
+
+  @Test
   public void intPath_springmvc_intf() {
     assertEquals(10, consumersSpringmvc.getIntf().intPath(10));
   }
diff --git a/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/DataTypeJaxrsSchema.java b/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/DataTypeJaxrsSchema.java
index ab821ea..41a9a50 100644
--- a/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/DataTypeJaxrsSchema.java
+++ b/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/DataTypeJaxrsSchema.java
@@ -216,6 +216,12 @@ public class DataTypeJaxrsSchema {
     return color;
   }
 
+  @Path("dynamicEnum")
+  @POST
+  public DynamicColor dynamicEnum(DynamicColor color) {
+    return color;
+  }
+
   // query array
   @Path("queryArr")
   @GET
@@ -253,6 +259,12 @@ public class DataTypeJaxrsSchema {
     return Arrays.toString(queryArr) + queryArr.length;
   }
 
+  @Path("queryArrJSON")
+  @GET
+  public String queryArrJSON(@ApiParam(collectionFormat = "json") @QueryParam("queryArr") String[] queryArr) {
+    return Arrays.toString(queryArr) + queryArr.length;
+  }
+
   @Path("requestHeaders")
   @GET
   public List<String> getRequestHeaders(@HeaderParam(value = "x_cse_test") String testServiceCombHeader,
diff --git a/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/DataTypePojoSchema.java b/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/DataTypePojoSchema.java
index 23dc575..81589ef 100644
--- a/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/DataTypePojoSchema.java
+++ b/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/DataTypePojoSchema.java
@@ -59,4 +59,8 @@ public class DataTypePojoSchema {
   public Color enumBody(Color color) {
     return color;
   }
+
+  public DynamicColor dynamicEnum(DynamicColor color) {
+    return color;
+  }
 }
diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/SwaggerUtils.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/SwaggerUtils.java
index 29fdb87..d06dc20 100644
--- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/SwaggerUtils.java
+++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/SwaggerUtils.java
@@ -40,8 +40,10 @@ import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.ClassUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.math.NumberUtils;
+import org.apache.servicecomb.foundation.common.base.DynamicEnum;
 import org.apache.servicecomb.foundation.common.exceptions.ServiceCombException;
 import org.apache.servicecomb.foundation.common.utils.ReflectUtils;
+import org.apache.servicecomb.swagger.extend.PropertyModelConverterExt;
 import org.apache.servicecomb.swagger.generator.SwaggerConst;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -68,7 +70,6 @@ import io.swagger.models.properties.MapProperty;
 import io.swagger.models.properties.ObjectProperty;
 import io.swagger.models.properties.Property;
 import io.swagger.models.properties.RefProperty;
-import io.swagger.models.utils.PropertyModelConverter;
 import io.swagger.util.Yaml;
 
 public final class SwaggerUtils {
@@ -205,7 +206,12 @@ public final class SwaggerUtils {
   }
 
   public static void addDefinitions(Swagger swagger, Type paramType) {
-    Map<String, Model> models = ModelConverters.getInstance().readAll(paramType);
+    JavaType javaType = TypeFactory.defaultInstance().constructType(paramType);
+    if (javaType.isTypeOrSubTypeOf(DynamicEnum.class)) {
+      return;
+    }
+
+    Map<String, Model> models = ModelConverters.getInstance().readAll(javaType);
     for (Entry<String, Model> entry : models.entrySet()) {
       if (null != swagger.getDefinitions()) {
         Model tempModel = swagger.getDefinitions().get(entry.getKey());
@@ -232,7 +238,7 @@ public final class SwaggerUtils {
   }
 
   public static boolean isBean(Model model) {
-    return isBean(new PropertyModelConverter().modelToProperty(model));
+    return isBean(PropertyModelConverterExt.toProperty(model));
   }
 
   public static boolean isBean(Property property) {
@@ -392,7 +398,7 @@ public final class SwaggerUtils {
     }
 
     JavaType javaType = TypeFactory.defaultInstance().constructType(type);
-    if (javaType.isContainerType() || javaType.isEnumType()) {
+    if (javaType.isContainerType() || javaType.isEnumType() || javaType.isTypeOrSubTypeOf(DynamicEnum.class)) {
       return false;
     }
 
diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/ModelResolverExt.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/ModelResolverExt.java
index 4bf0db9..cbb67d4 100644
--- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/ModelResolverExt.java
+++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/ModelResolverExt.java
@@ -23,10 +23,13 @@ import java.lang.reflect.Type;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 import org.apache.commons.lang3.StringUtils;
+import org.apache.servicecomb.foundation.common.base.DynamicEnum;
+import org.apache.servicecomb.foundation.common.base.EnumUtils;
 import org.apache.servicecomb.foundation.common.exceptions.ServiceCombException;
 import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
 import org.apache.servicecomb.swagger.converter.property.StringPropertyConverter;
@@ -48,8 +51,10 @@ import io.swagger.converter.ModelConverterContext;
 import io.swagger.jackson.ModelResolver;
 import io.swagger.models.Model;
 import io.swagger.models.ModelImpl;
+import io.swagger.models.properties.IntegerProperty;
 import io.swagger.models.properties.Property;
 import io.swagger.models.properties.StringProperty;
+import io.swagger.util.PrimitiveType;
 
 public class ModelResolverExt extends ModelResolver {
   private Map<Class<?>, PropertyCreator> propertyCreatorMap = new HashMap<>();
@@ -164,6 +169,10 @@ public class ModelResolverExt extends ModelResolver {
       return creator.createProperty();
     }
 
+    if (EnumUtils.isDynamicEnum(propType.getRawClass())) {
+      return resolveDynamicEnum(propType);
+    }
+
     Property property = super.resolveProperty(propType, context, annotations, next);
     if (StringProperty.class.isInstance(property)) {
       if (StringPropertyConverter.isEnum((StringProperty) property)) {
@@ -172,4 +181,22 @@ public class ModelResolverExt extends ModelResolver {
     }
     return property;
   }
+
+  private Property resolveDynamicEnum(JavaType propType) {
+    Class<?> enumClass = propType.getRawClass();
+    Class<?> enumValueClass = propType.findTypeParameters(DynamicEnum.class)[0].getRawClass();
+    Property property = PrimitiveType.createProperty(enumValueClass);
+
+    if (property instanceof StringProperty) {
+      List<String> enums = SwaggerEnum.DYNAMIC.readEnumValues(enumClass);
+      ((StringProperty) property).setEnum(enums);
+    }
+
+    if (property instanceof IntegerProperty) {
+      List<Integer> enums = SwaggerEnum.DYNAMIC.readEnumValues(enumClass);
+      ((IntegerProperty) property).setEnum(enums);
+    }
+
+    return property;
+  }
 }
diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/PropertyModelConverterExt.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/PropertyModelConverterExt.java
new file mode 100644
index 0000000..1a876c8
--- /dev/null
+++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/PropertyModelConverterExt.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.swagger.extend;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import io.swagger.models.Model;
+import io.swagger.models.ModelImpl;
+import io.swagger.models.properties.IntegerProperty;
+import io.swagger.models.properties.Property;
+import io.swagger.models.utils.PropertyModelConverter;
+
+public class PropertyModelConverterExt extends PropertyModelConverter {
+  public static Model toModel(Property property) {
+    return new PropertyModelConverterExt().propertyToModel(property);
+  }
+
+  public static Property toProperty(Model model) {
+    return new PropertyModelConverterExt().modelToProperty(model);
+  }
+
+  @Override
+  public Model propertyToModel(Property property) {
+    Model model = super.propertyToModel(property);
+    copyNumberEnumToModel(property, model);
+    return model;
+  }
+
+  public void copyNumberEnumToModel(Property property, Model model) {
+    if (!(property instanceof IntegerProperty) || !(model instanceof ModelImpl)) {
+      return;
+    }
+
+    List<Integer> intEnum = ((IntegerProperty) property).getEnum();
+    if (intEnum == null) {
+      return;
+    }
+
+    List<String> _enum = intEnum.stream()
+        .map(value -> value.toString())
+        .collect(Collectors.toList());
+    ((ModelImpl) model).setEnum(_enum);
+  }
+}
diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/SwaggerEnum.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/SwaggerEnum.java
new file mode 100644
index 0000000..fd85009
--- /dev/null
+++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/SwaggerEnum.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.swagger.extend;
+
+import static org.apache.servicecomb.foundation.common.utils.StringBuilderUtils.appendLine;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.servicecomb.foundation.common.base.DynamicEnum;
+import org.apache.servicecomb.foundation.common.base.EnumUtils;
+
+import io.swagger.annotations.ApiModelProperty;
+import io.swagger.annotations.ApiParam;
+import io.swagger.util.Json;
+
+public enum SwaggerEnum {
+  JDK {
+    @SuppressWarnings({"unchecked", "deprecation"})
+    @Override
+    protected <T> T readEnumValue(Field enumField) {
+      Enum<?> enumValue = EnumUtils.readEnum(enumField);
+      return (T) Json.mapper().getSerializationConfig().getAnnotationIntrospector().findEnumValue(enumValue);
+    }
+  },
+  DYNAMIC {
+    @Override
+    protected <T> T readEnumValue(Field enumField) {
+      DynamicEnum<T> enumValue = EnumUtils.readEnum(enumField);
+      return enumValue.getValue();
+    }
+  };
+
+  public String findPropertyDescription(Class<?> enumClass, Annotation[] annotations) {
+    StringBuilder sb = new StringBuilder();
+
+    String propertyDescription = readDescription(annotations, null);
+    if (StringUtils.isNotEmpty(propertyDescription)) {
+      appendLine(sb, propertyDescription);
+    }
+
+    EnumUtils.findEnumFields(enumClass).forEach(enumField -> {
+      Object enumValue = readEnumValue(enumField);
+      String description = readDescription(enumField.getAnnotations(), "");
+      appendLine(sb, "- %s: %s", enumValue, description);
+    });
+
+    return sb.toString();
+  }
+
+  public <T> List<T> readEnumValues(Class<?> enumClass) {
+    return EnumUtils.findEnumFields(enumClass)
+        .map(this::<T>readEnumValue)
+        .collect(Collectors.toList());
+  }
+
+  protected abstract <T> T readEnumValue(Field enumField);
+
+  @SuppressWarnings("unchecked")
+  private <T extends Annotation> T findAnnotation(Annotation[] annotations, Class<T> cls) {
+    if (annotations == null) {
+      return null;
+    }
+
+    return Arrays.stream(annotations)
+        .filter(annotation -> cls.isAssignableFrom(annotation.getClass()))
+        .map(annotation -> (T) annotation)
+        .findAny()
+        .orElse(null);
+  }
+
+  private String readDescription(Annotation[] annotations, String defaultDescription) {
+    ApiModelProperty apiModelProperty = findAnnotation(annotations, ApiModelProperty.class);
+    if (apiModelProperty != null && StringUtils.isNotEmpty(apiModelProperty.value())) {
+      return apiModelProperty.value();
+    }
+
+    ApiParam apiParam = findAnnotation(annotations, ApiParam.class);
+    if (apiParam != null && StringUtils.isNotEmpty(apiParam.value())) {
+      return apiParam.value();
+    }
+
+    return defaultDescription;
+  }
+}
diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/introspector/JsonPropertyIntrospector.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/introspector/JsonPropertyIntrospector.java
index 0c55074..85dd938 100644
--- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/introspector/JsonPropertyIntrospector.java
+++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/introspector/JsonPropertyIntrospector.java
@@ -18,13 +18,15 @@
 package org.apache.servicecomb.swagger.extend.introspector;
 
 import org.apache.commons.lang3.StringUtils;
+import org.apache.servicecomb.foundation.common.base.EnumUtils;
+import org.apache.servicecomb.swagger.extend.SwaggerEnum;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.introspect.Annotated;
 
 import io.swagger.jackson.SwaggerAnnotationIntrospector;
 
 public class JsonPropertyIntrospector extends SwaggerAnnotationIntrospector {
-
   private static final long serialVersionUID = 4157263023893695762L;
 
   @SuppressWarnings("deprecation")
@@ -40,4 +42,17 @@ public class JsonPropertyIntrospector extends SwaggerAnnotationIntrospector {
       return super.findEnumValue(value);
     }
   }
+
+  @Override
+  public String findPropertyDescription(Annotated annotated) {
+    Class<?> enumClass = annotated.getRawType();
+    if (enumClass.isEnum()) {
+      return SwaggerEnum.JDK.findPropertyDescription(enumClass, annotated.getAnnotated().getAnnotations());
+    }
+    if (EnumUtils.isDynamicEnum(enumClass)) {
+      return SwaggerEnum.DYNAMIC.findPropertyDescription(enumClass, annotated.getAnnotated().getAnnotations());
+    }
+
+    return super.findPropertyDescription(annotated);
+  }
 }
diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/AnnotationUtils.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/AnnotationUtils.java
index 0f00b58..e4cea34 100644
--- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/AnnotationUtils.java
+++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/AnnotationUtils.java
@@ -24,6 +24,7 @@ import java.util.Map;
 
 import org.apache.commons.lang3.ClassUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.servicecomb.swagger.extend.PropertyModelConverterExt;
 import org.apache.servicecomb.swagger.generator.core.processor.annotation.models.ResponseConfig;
 import org.apache.servicecomb.swagger.generator.core.processor.annotation.models.ResponseConfigBase;
 import org.apache.servicecomb.swagger.generator.core.processor.annotation.models.ResponseHeaderConfig;
@@ -40,7 +41,6 @@ import io.swagger.models.Swagger;
 import io.swagger.models.properties.ArrayProperty;
 import io.swagger.models.properties.MapProperty;
 import io.swagger.models.properties.Property;
-import io.swagger.models.utils.PropertyModelConverter;
 import io.swagger.util.ReflectionUtils;
 
 public final class AnnotationUtils {
@@ -148,7 +148,7 @@ public final class AnnotationUtils {
 
     Property property = generateResponseProperty(swagger, responseConfig);
     if (property != null) {
-      Model model = new PropertyModelConverter().propertyToModel(property);
+      Model model = PropertyModelConverterExt.toModel(property);
       response.setResponseSchema(model);
     }
     response.setDescription(responseConfig.getDescription());
diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/parameter/EnumPostProcessor.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/parameter/EnumPostProcessor.java
new file mode 100644
index 0000000..9402ea0
--- /dev/null
+++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/parameter/EnumPostProcessor.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.swagger.generator.core.processor.parameter;
+
+import static org.apache.servicecomb.swagger.extend.SwaggerEnum.DYNAMIC;
+import static org.apache.servicecomb.swagger.extend.SwaggerEnum.JDK;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import javax.ws.rs.core.Response.Status;
+
+import org.apache.servicecomb.foundation.common.base.DynamicEnum;
+import org.apache.servicecomb.swagger.extend.SwaggerEnum;
+import org.apache.servicecomb.swagger.generator.OperationPostProcessor;
+import org.apache.servicecomb.swagger.generator.ParameterGenerator;
+import org.apache.servicecomb.swagger.generator.core.AbstractOperationGenerator;
+import org.apache.servicecomb.swagger.generator.core.AbstractSwaggerGenerator;
+
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.type.TypeFactory;
+
+import io.swagger.models.parameters.AbstractSerializableParameter;
+
+public class EnumPostProcessor implements OperationPostProcessor {
+  @Override
+  public boolean shouldProcess(AbstractSwaggerGenerator swaggerGenerator,
+      AbstractOperationGenerator operationGenerator) {
+    return true;
+  }
+
+  @Override
+  public void process(AbstractSwaggerGenerator swaggerGenerator, AbstractOperationGenerator operationGenerator) {
+    for (ParameterGenerator parameterGenerator : operationGenerator.getParameterGenerators()) {
+      if (parameterGenerator.getGeneratedParameter() instanceof AbstractSerializableParameter) {
+        processParameterDescription(parameterGenerator);
+      }
+    }
+
+    processResponseModelDescription(operationGenerator);
+  }
+
+  private void processParameterDescription(ParameterGenerator parameterGenerator) {
+    JavaType genericType = parameterGenerator.getGenericType();
+    Annotation[] annotations = parameterGenerator.getAnnotations().toArray(new Annotation[0]);
+    String description = generateDescription(genericType, annotations);
+    if (description != null) {
+      AbstractSerializableParameter<?> parameter = (AbstractSerializableParameter<?>) parameterGenerator
+          .getGeneratedParameter();
+      parameter.setDescription(description);
+    }
+  }
+
+  private String generateDescription(Type type, Annotation[] annotations) {
+    JavaType javaType = TypeFactory.defaultInstance().constructType(type);
+    if (javaType.isEnumType()) {
+      return generateDescription(JDK, javaType.getRawClass(), annotations);
+    }
+
+    if (javaType.isTypeOrSubTypeOf(DynamicEnum.class)) {
+      return generateDescription(DYNAMIC, javaType.getRawClass(), annotations);
+    }
+
+    return null;
+  }
+
+  private String generateDescription(SwaggerEnum swaggerEnum, Class<?> enumClass, Annotation[] annotations) {
+    return swaggerEnum.findPropertyDescription(enumClass, annotations);
+  }
+
+  public void processResponseModelDescription(AbstractOperationGenerator operationGenerator) {
+    String description = generateDescription(operationGenerator.getMethod().getReturnType(), null);
+    if (description != null) {
+      operationGenerator.getOperation().getResponses().get(String.valueOf(Status.OK.getStatusCode()))
+          .getResponseSchema()
+          .setDescription(description);
+    }
+  }
+}
diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/response/DefaultResponseTypeProcessor.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/response/DefaultResponseTypeProcessor.java
index 7f4c8cb..37ddad5 100644
--- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/response/DefaultResponseTypeProcessor.java
+++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/response/DefaultResponseTypeProcessor.java
@@ -24,6 +24,7 @@ import java.lang.reflect.Type;
 import javax.servlet.http.Part;
 
 import org.apache.servicecomb.swagger.SwaggerUtils;
+import org.apache.servicecomb.swagger.extend.PropertyModelConverterExt;
 import org.apache.servicecomb.swagger.generator.OperationGenerator;
 import org.apache.servicecomb.swagger.generator.ResponseTypeProcessor;
 import org.apache.servicecomb.swagger.generator.SwaggerGenerator;
@@ -31,7 +32,6 @@ import org.apache.servicecomb.swagger.generator.SwaggerGenerator;
 import io.swagger.converter.ModelConverters;
 import io.swagger.models.Model;
 import io.swagger.models.properties.Property;
-import io.swagger.models.utils.PropertyModelConverter;
 import io.swagger.util.ReflectionUtils;
 
 public class DefaultResponseTypeProcessor implements ResponseTypeProcessor {
@@ -88,6 +88,6 @@ public class DefaultResponseTypeProcessor implements ResponseTypeProcessor {
     }
     SwaggerUtils.addDefinitions(swaggerGenerator.getSwagger(), responseType);
     Property property = ModelConverters.getInstance().readAsProperty(responseType);
-    return new PropertyModelConverter().propertyToModel(property);
+    return PropertyModelConverterExt.toModel(property);
   }
 }
diff --git a/swagger/swagger-generator/generator-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.OperationPostProcessor b/swagger/swagger-generator/generator-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.OperationPostProcessor
new file mode 100644
index 0000000..3d854fa
--- /dev/null
+++ b/swagger/swagger-generator/generator-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.OperationPostProcessor
@@ -0,0 +1,18 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+org.apache.servicecomb.swagger.generator.core.processor.parameter.EnumPostProcessor
\ No newline at end of file
diff --git a/swagger/swagger-generator/generator-core/src/test/resources/schemas/allMethod.yaml b/swagger/swagger-generator/generator-core/src/test/resources/schemas/allMethod.yaml
index 329f360..5390865 100644
--- a/swagger/swagger-generator/generator-core/src/test/resources/schemas/allMethod.yaml
+++ b/swagger/swagger-generator/generator-core/src/test/resources/schemas/allMethod.yaml
@@ -592,6 +592,7 @@ definitions:
         format: "double"
       enumValue:
         type: "string"
+        description: "- RED: \n- YELLOW: \n- BLUE: \n"
         enum:
         - "RED"
         - "YELLOW"
diff --git a/swagger/swagger-generator/generator-core/src/test/resources/schemas/allType.yaml b/swagger/swagger-generator/generator-core/src/test/resources/schemas/allType.yaml
index 12f1f8f..c980230 100644
--- a/swagger/swagger-generator/generator-core/src/test/resources/schemas/allType.yaml
+++ b/swagger/swagger-generator/generator-core/src/test/resources/schemas/allType.yaml
@@ -83,6 +83,7 @@ definitions:
         format: "double"
       enumValue:
         type: "string"
+        description: "- RED: \n- YELLOW: \n- BLUE: \n"
         enum:
         - "RED"
         - "YELLOW"
diff --git a/swagger/swagger-generator/generator-core/src/test/resources/schemas/multiParam.yaml b/swagger/swagger-generator/generator-core/src/test/resources/schemas/multiParam.yaml
index 3f80849..8e69b26 100644
--- a/swagger/swagger-generator/generator-core/src/test/resources/schemas/multiParam.yaml
+++ b/swagger/swagger-generator/generator-core/src/test/resources/schemas/multiParam.yaml
@@ -87,6 +87,7 @@ definitions:
         format: "double"
       enumValue:
         type: "string"
+        description: "- RED: \n- YELLOW: \n- BLUE: \n"
         enum:
         - "RED"
         - "YELLOW"
diff --git a/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/Echo.java b/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/Echo.java
index 9dbc531..a0a10f8 100644
--- a/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/Echo.java
+++ b/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/Echo.java
@@ -44,15 +44,22 @@ import org.apache.servicecomb.swagger.generator.jaxrs.model.BeanParamDefaultBody
 import org.apache.servicecomb.swagger.generator.jaxrs.model.BeanParamInvalidDefaultBody;
 import org.apache.servicecomb.swagger.generator.jaxrs.model.BeanParamWithJsonIgnoredTagged;
 import org.apache.servicecomb.swagger.generator.jaxrs.model.BeanParamWithPart;
+import org.apache.servicecomb.swagger.generator.jaxrs.model.enums.DynamicStatus;
+import org.apache.servicecomb.swagger.generator.jaxrs.model.enums.DynamicStatusBeanParam;
+import org.apache.servicecomb.swagger.generator.jaxrs.model.enums.DynamicStatusModel;
+import org.apache.servicecomb.swagger.generator.jaxrs.model.enums.JdkStatus;
+import org.apache.servicecomb.swagger.generator.jaxrs.model.enums.JdkStatusBeanParam;
+import org.apache.servicecomb.swagger.generator.jaxrs.model.enums.JdkStatusModel;
 
 import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
 import io.swagger.annotations.ApiResponse;
 
 @Path(value = "Echo")
 public class Echo {
   @PATCH
   public void patch() {
-    
+
   }
 
   @POST
@@ -176,4 +183,20 @@ public class Echo {
   public List<List<String>> nestedListString(List<List<String>> param) {
     return param;
   }
+
+  @Path("/dynamicStatusEnum")
+  @POST
+  public DynamicStatus dynamicStatusEnum(@BeanParam DynamicStatusBeanParam statusBeanParam,
+      @QueryParam("status") @ApiParam(value = "dynamic desc direct") DynamicStatus status,
+      DynamicStatusModel model) {
+    return null;
+  }
+
+  @Path("/jdkStatusEnum")
+  @POST
+  public JdkStatus jdkStatusEnum(@BeanParam JdkStatusBeanParam statusBeanParam,
+      @QueryParam("status") @ApiParam(value = "jdk desc direct") JdkStatus status,
+      JdkStatusModel model) {
+    return null;
+  }
 }
diff --git a/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/TestJaxrs.java b/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/TestJaxrs.java
index 440e808..c487fed 100644
--- a/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/TestJaxrs.java
+++ b/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/TestJaxrs.java
@@ -144,6 +144,16 @@ public class TestJaxrs {
   }
 
   @Test
+  public void should_support_dynamic_enum() {
+    UnitTestSwaggerUtils.testSwagger("schemas/dynamicStatusEnum.yaml", Echo.class, "dynamicStatusEnum");
+  }
+
+  @Test
+  public void should_support_jdk_enum() {
+    UnitTestSwaggerUtils.testSwagger("schemas/jdkStatusEnum.yaml", Echo.class, "jdkStatusEnum");
+  }
+
+  @Test
   public void beanParamComplexField() {
     UnitTestSwaggerUtils.testException(
         "generate swagger operation failed, method=org.apache.servicecomb.swagger.generator.jaxrs.Echo:beanParamComplexField.",
diff --git a/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/enums/DynamicStatus.java b/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/enums/DynamicStatus.java
new file mode 100644
index 0000000..3f930f7
--- /dev/null
+++ b/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/enums/DynamicStatus.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.swagger.generator.jaxrs.model.enums;
+
+import org.apache.servicecomb.foundation.common.base.DynamicEnum;
+import org.apache.servicecomb.foundation.common.base.DynamicEnumCache;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+
+import io.swagger.annotations.ApiModelProperty;
+
+public class DynamicStatus extends DynamicEnum<Integer> {
+  @ApiModelProperty(value = "dynamic bad request")
+  public static final DynamicStatus BAD_REQUEST = new DynamicStatus(400);
+
+  @ApiModelProperty(value = "dynamic not found")
+  public static final DynamicStatus NOT_FOUND = new DynamicStatus(404);
+
+  private static final DynamicEnumCache<DynamicStatus> CACHE = new DynamicEnumCache<>(DynamicStatus.class);
+
+  public DynamicStatus(Integer value) {
+    super(value);
+  }
+
+  @JsonCreator
+  public static DynamicStatus fromValue(int value) {
+    return CACHE.fromValue(value);
+  }
+}
diff --git a/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/enums/DynamicStatusBeanParam.java b/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/enums/DynamicStatusBeanParam.java
new file mode 100644
index 0000000..8cd280c
--- /dev/null
+++ b/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/enums/DynamicStatusBeanParam.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.swagger.generator.jaxrs.model.enums;
+
+import javax.ws.rs.QueryParam;
+
+import io.swagger.annotations.ApiParam;
+
+public class DynamicStatusBeanParam {
+  @ApiParam(value = "dynamic desc aggr")
+  @QueryParam("status-aggr")
+  public DynamicStatus queryStatus;
+}
diff --git a/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/enums/DynamicStatusModel.java b/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/enums/DynamicStatusModel.java
new file mode 100644
index 0000000..b920940
--- /dev/null
+++ b/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/enums/DynamicStatusModel.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.swagger.generator.jaxrs.model.enums;
+
+import io.swagger.annotations.ApiModelProperty;
+
+public class DynamicStatusModel {
+  @ApiModelProperty(value = "dynamic status model")
+  public DynamicStatus status;
+}
diff --git a/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/enums/JdkStatus.java b/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/enums/JdkStatus.java
new file mode 100644
index 0000000..1517160
--- /dev/null
+++ b/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/enums/JdkStatus.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.swagger.generator.jaxrs.model.enums;
+
+import io.swagger.annotations.ApiModelProperty;
+
+public enum JdkStatus {
+  @ApiModelProperty(value = "jdk bad request")
+  BAD_REQUEST,
+
+  @ApiModelProperty(value = "jdk not found")
+  NOT_FOUND
+}
diff --git a/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/enums/JdkStatusBeanParam.java b/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/enums/JdkStatusBeanParam.java
new file mode 100644
index 0000000..a6437c5
--- /dev/null
+++ b/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/enums/JdkStatusBeanParam.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.swagger.generator.jaxrs.model.enums;
+
+import javax.ws.rs.QueryParam;
+
+import io.swagger.annotations.ApiParam;
+
+public class JdkStatusBeanParam {
+  @ApiParam(value = "jdk desc aggr")
+  @QueryParam("status-aggr")
+  public JdkStatus queryStatus;
+}
diff --git a/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/enums/JdkStatusModel.java b/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/enums/JdkStatusModel.java
new file mode 100644
index 0000000..6656ec7
--- /dev/null
+++ b/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/model/enums/JdkStatusModel.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.swagger.generator.jaxrs.model.enums;
+
+import io.swagger.annotations.ApiModelProperty;
+
+public class JdkStatusModel {
+  @ApiModelProperty(value = "jdk status model")
+  public JdkStatus status;
+}
diff --git a/swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/dynamicStatusEnum.yaml b/swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/dynamicStatusEnum.yaml
new file mode 100644
index 0000000..906054f
--- /dev/null
+++ b/swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/dynamicStatusEnum.yaml
@@ -0,0 +1,81 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements.  See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License.  You may obtain a copy of the License at
+##
+##      http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+
+---
+swagger: "2.0"
+info:
+  version: "1.0.0"
+  title: "swagger definition for org.apache.servicecomb.swagger.generator.jaxrs.Echo"
+  x-java-interface: "gen.cse.ms.ut.EchoIntf"
+basePath: "/Echo"
+consumes:
+- "application/json"
+produces:
+- "application/json"
+paths:
+  /dynamicStatusEnum:
+    post:
+      operationId: "dynamicStatusEnum"
+      parameters:
+      - name: "status-aggr"
+        in: "query"
+        description: "dynamic desc aggr\n- 400: dynamic bad request\n- 404: dynamic\
+          \ not found\n"
+        required: false
+        type: "integer"
+        format: "int32"
+        enum:
+        - 400
+        - 404
+      - name: "status"
+        in: "query"
+        description: "dynamic desc direct\n- 400: dynamic bad request\n- 404: dynamic\
+          \ not found\n"
+        required: false
+        type: "integer"
+        format: "int32"
+        enum:
+        - 400
+        - 404
+      - in: "body"
+        name: "model"
+        required: false
+        schema:
+          $ref: "#/definitions/DynamicStatusModel"
+      responses:
+        "200":
+          description: "response of 200"
+          schema:
+            type: "integer"
+            format: "int32"
+            description: "- 400: dynamic bad request\n- 404: dynamic not found\n"
+            enum:
+            - "400"
+            - "404"
+definitions:
+  DynamicStatusModel:
+    type: "object"
+    properties:
+      status:
+        type: "integer"
+        format: "int32"
+        description: "dynamic status model\n- 400: dynamic bad request\n- 404: dynamic\
+          \ not found\n"
+        enum:
+        - 400
+        - 404
+    x-java-class: "org.apache.servicecomb.swagger.generator.jaxrs.model.enums.DynamicStatusModel"
diff --git a/swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/jdkStatusEnum.yaml b/swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/jdkStatusEnum.yaml
new file mode 100644
index 0000000..67efb0d
--- /dev/null
+++ b/swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/jdkStatusEnum.yaml
@@ -0,0 +1,78 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements.  See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License.  You may obtain a copy of the License at
+##
+##      http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+
+---
+swagger: "2.0"
+info:
+  version: "1.0.0"
+  title: "swagger definition for org.apache.servicecomb.swagger.generator.jaxrs.Echo"
+  x-java-interface: "gen.cse.ms.ut.EchoIntf"
+basePath: "/Echo"
+consumes:
+- "application/json"
+produces:
+- "application/json"
+paths:
+  /jdkStatusEnum:
+    post:
+      operationId: "jdkStatusEnum"
+      parameters:
+      - name: "status-aggr"
+        in: "query"
+        description: "jdk desc aggr\n- BAD_REQUEST: jdk bad request\n- NOT_FOUND:\
+          \ jdk not found\n"
+        required: false
+        type: "string"
+        enum:
+        - "BAD_REQUEST"
+        - "NOT_FOUND"
+      - name: "status"
+        in: "query"
+        description: "jdk desc direct\n- BAD_REQUEST: jdk bad request\n- NOT_FOUND:\
+          \ jdk not found\n"
+        required: false
+        type: "string"
+        enum:
+        - "BAD_REQUEST"
+        - "NOT_FOUND"
+      - in: "body"
+        name: "model"
+        required: false
+        schema:
+          $ref: "#/definitions/JdkStatusModel"
+      responses:
+        "200":
+          description: "response of 200"
+          schema:
+            type: "string"
+            description: "- BAD_REQUEST: jdk bad request\n- NOT_FOUND: jdk not found\n"
+            enum:
+            - "BAD_REQUEST"
+            - "NOT_FOUND"
+            x-java-class: "org.apache.servicecomb.swagger.generator.jaxrs.model.enums.JdkStatus"
+definitions:
+  JdkStatusModel:
+    type: "object"
+    properties:
+      status:
+        type: "string"
+        description: "jdk status model\n- BAD_REQUEST: jdk bad request\n- NOT_FOUND:\
+          \ jdk not found\n"
+        enum:
+        - "BAD_REQUEST"
+        - "NOT_FOUND"
+    x-java-class: "org.apache.servicecomb.swagger.generator.jaxrs.model.enums.JdkStatusModel"