add oas-generator to generate openapi v3

Signed-off-by: kakulisen <18813972746@163.com>
diff --git a/oas-generator/oas-generator-core/pom.xml b/oas-generator/oas-generator-core/pom.xml
new file mode 100644
index 0000000..1a7a35c
--- /dev/null
+++ b/oas-generator/oas-generator-core/pom.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <parent>
+    <artifactId>oas-generator</artifactId>
+    <groupId>org.apache.servicecomb.toolkit</groupId>
+    <version>0.2.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>oas-generator-core</artifactId>
+
+  <properties>
+    <swagger.version>2.0.9</swagger.version>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>io.swagger.core.v3</groupId>
+      <artifactId>swagger-models</artifactId>
+      <version>${swagger.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>io.swagger.core.v3</groupId>
+      <artifactId>swagger-annotations</artifactId>
+      <version>${swagger.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>io.swagger.core.v3</groupId>
+      <artifactId>swagger-core</artifactId>
+      <version>${swagger.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.12</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.ow2.asm</groupId>
+      <artifactId>asm</artifactId>
+      <version>7.2</version>
+    </dependency>
+
+  </dependencies>
+
+
+</project>
\ No newline at end of file
diff --git a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/HttpStatus.java b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/HttpStatus.java
new file mode 100644
index 0000000..00a12e3
--- /dev/null
+++ b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/HttpStatus.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.toolkit.generator;
+
+public class HttpStatus {
+
+  public static String OK = "200";
+
+}
diff --git a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/MediaTypeConst.java b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/MediaTypeConst.java
new file mode 100644
index 0000000..624e143
--- /dev/null
+++ b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/MediaTypeConst.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.generator;
+
+/**
+ * Common media type constants
+ *
+ * @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7">HTTP/1.1 section 3.7</a>
+ */
+public class MediaTypeConst {
+
+  public final static String WILDCARD = "*/*";
+
+  public final static String APPLICATION_XML = "application/xml";
+
+  public final static String APPLICATION_ATOM_XML = "application/atom+xml";
+
+  public final static String APPLICATION_XHTML_XML = "application/xhtml+xml";
+
+  public final static String APPLICATION_SVG_XML = "application/svg+xml";
+
+  public final static String APPLICATION_JSON = "application/json";
+
+  public final static String APPLICATION_FORM_URLENCODED = "application/x-www-form-urlencoded";
+
+  public final static String MULTIPART_FORM_DATA = "multipart/form-data";
+
+  public final static String APPLICATION_OCTET_STREAM = "application/octet-stream";
+
+  public final static String TEXT_PLAIN = "text/plain";
+
+  public final static String TEXT_XML = "text/xml";
+
+  public final static String TEXT_HTML = "text/html";
+
+  public final static String SERVER_SENT_EVENTS = "text/event-stream";
+
+  public final static String APPLICATION_JSON_PATCH_JSON = "application/json-patch+json";
+}
diff --git a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/OasContext.java b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/OasContext.java
new file mode 100644
index 0000000..3be7edb
--- /dev/null
+++ b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/OasContext.java
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.generator;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.servicecomb.toolkit.generator.parser.api.OpenApiAnnotationParser;
+
+import io.swagger.v3.oas.models.Components;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.PathItem;
+import io.swagger.v3.oas.models.PathItem.HttpMethod;
+import io.swagger.v3.oas.models.Paths;
+import io.swagger.v3.oas.models.info.Info;
+import io.swagger.v3.oas.models.servers.Server;
+
+public class OasContext {
+
+  private OpenAPI openAPI;
+
+  private String basePath;
+
+  private Class<?> cls;
+
+  private List<OperationContext> operationList = new ArrayList<>();
+
+  private OpenApiAnnotationParser parser;
+
+  public OasContext(OpenApiAnnotationParser parser) {
+    this(new OpenAPI(), parser);
+  }
+
+  public OasContext(OpenAPI openAPI, OpenApiAnnotationParser parser) {
+    this.openAPI = openAPI;
+    this.parser = parser;
+  }
+
+  public OpenAPI toOpenAPI() {
+    ensurePaths();
+    for (OperationContext operationCtx : operationList) {
+      if (!operationCtx.hasOperation()) {
+        continue;
+      }
+
+      if (openAPI.getPaths() == null) {
+        openAPI.setPaths(new Paths());
+      }
+
+      PathItem pathItem = openAPI.getPaths().get(operationCtx.getPath());
+      if (pathItem == null) {
+        pathItem = new PathItem();
+        openAPI.path(operationCtx.getPath(), pathItem);
+      }
+      pathItem.operation(HttpMethod.valueOf(operationCtx.getHttpMethod()), operationCtx.toOperation());
+    }
+
+    // 如果没有restful资源则返回null
+    if (openAPI.getPaths() == null || openAPI.getPaths().size() == 0) {
+      return null;
+    }
+
+    openAPI.info(new Info().title("gen").version("1.0.0"));
+
+    correctBasepath();
+    correctComponents();
+
+    openAPI.servers(Collections.singletonList(new Server().url(basePath)));
+
+    return openAPI;
+  }
+
+  private void correctComponents() {
+    Components nullComponents = new Components();
+    if (nullComponents.equals(getComponents())) {
+      openAPI.setComponents(null);
+    }
+  }
+
+  private void correctBasepath() {
+    if (StringUtils.isEmpty(basePath)) {
+      basePath = "/";
+    }
+
+    if (!basePath.startsWith("/")) {
+      basePath = "/" + basePath;
+    }
+  }
+
+  public Components getComponents() {
+    if (openAPI.getComponents() == null) {
+      openAPI.setComponents(new Components());
+    }
+    return openAPI.getComponents();
+  }
+
+  private void ensurePaths() {
+    if (openAPI.getPaths() == null) {
+      openAPI.setPaths(new Paths());
+    }
+  }
+
+  public OpenApiAnnotationParser getParser() {
+    return parser;
+  }
+
+  public void setParser(OpenApiAnnotationParser parser) {
+    this.parser = parser;
+  }
+
+  public OpenAPI getOpenAPI() {
+    return openAPI;
+  }
+
+  public String getBasePath() {
+    return basePath;
+  }
+
+  public Class<?> getCls() {
+    return cls;
+  }
+
+  public void setCls(Class<?> cls) {
+    this.cls = cls;
+  }
+
+  public void setBasePath(String basePath) {
+    this.basePath = basePath;
+  }
+
+  public void addOperation(OperationContext operation) {
+    operationList.add(operation);
+  }
+}
diff --git a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/OasGenerator.java b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/OasGenerator.java
new file mode 100644
index 0000000..540f320
--- /dev/null
+++ b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/OasGenerator.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.generator;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.ServiceLoader;
+import java.util.Set;
+
+import org.apache.servicecomb.toolkit.generator.parser.api.OpenApiAnnotationParser;
+
+import io.swagger.v3.oas.models.OpenAPI;
+
+public class OasGenerator {
+
+  private static List<OpenApiAnnotationParser> parserList = new ArrayList<>();
+
+  static {
+    ServiceLoader.load(OpenApiAnnotationParser.class).forEach(parserList::add);
+  }
+
+  public OpenAPI generate(Class<?> cls) {
+
+    Optional<OpenApiAnnotationParser> parserOptional = parserList.stream().filter(parser -> parser.canProcess(cls))
+        .findFirst();
+
+    if (!parserOptional.isPresent()) {
+      return null;
+    }
+    OasContext context = new OasContext(parserOptional.get());
+    parserOptional.get().parser(cls, context);
+    return context.toOpenAPI();
+  }
+
+  public List<OpenAPI> generate(Set<Class> classes) {
+
+    List<OpenAPI> openApiList = new ArrayList<>();
+    for (Class cls : classes) {
+      OpenAPI openAPI = generate(cls);
+      if (openAPI != null) {
+        openApiList.add(openAPI);
+      }
+    }
+
+    return openApiList;
+  }
+}
diff --git a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/OperationContext.java b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/OperationContext.java
new file mode 100644
index 0000000..b8bca12
--- /dev/null
+++ b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/OperationContext.java
@@ -0,0 +1,192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.generator;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.servicecomb.toolkit.generator.parser.api.OpenApiAnnotationParser;
+import org.apache.servicecomb.toolkit.generator.util.ModelConverter;
+
+import io.swagger.v3.oas.models.Components;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.Operation;
+import io.swagger.v3.oas.models.media.Content;
+import io.swagger.v3.oas.models.media.MediaType;
+import io.swagger.v3.oas.models.media.Schema;
+import io.swagger.v3.oas.models.parameters.Parameter;
+import io.swagger.v3.oas.models.responses.ApiResponse;
+import io.swagger.v3.oas.models.responses.ApiResponses;
+
+public class OperationContext {
+
+  private OasContext parentContext;
+
+  private Method method;
+
+  private Operation operation = new Operation();
+
+  private String operationId;
+
+  private String path;
+
+  private String httpMethod;
+
+  private ApiResponses apiResponses = new ApiResponses();
+
+  private List<ParameterContext> parameterContextList = new ArrayList<>();
+
+  private OpenApiAnnotationParser parser;
+
+  public OperationContext(Method method, OasContext parentContext) {
+    this.parentContext = parentContext;
+    this.method = method;
+    this.parser = parentContext.getParser();
+    this.parentContext.addOperation(this);
+  }
+
+  public void addParameter(ParameterContext context) {
+    parameterContextList.add(context);
+  }
+
+  public OpenApiAnnotationParser getParser() {
+    return parser;
+  }
+
+  public boolean hasOperation() {
+    return httpMethod != null && method != null;
+  }
+
+  public Operation toOperation() {
+
+    if (!hasOperation()) {
+      return null;
+    }
+
+    if (StringUtils.isEmpty(operationId)) {
+      operationId = method.getName();
+    }
+
+    operation.operationId(operationId);
+    correctResponse(apiResponses);
+    operation.setResponses(apiResponses);
+
+    // 处理参数
+    List<Parameter> parameterList = parameterContextList.stream()
+        .map(parameterContext -> parameterContext.toOasParameter())
+        .filter(parameter -> parameter != null)
+        .collect(Collectors.toList());
+
+    if (parameterList.size() > 0) {
+      operation.parameters(parameterList);
+    }
+
+    return operation;
+  }
+
+  public void correctResponse(ApiResponses apiResponses) {
+
+    if (apiResponses == null) {
+      return;
+    }
+    // 处理响应
+    // 没有注解被处理
+    if (apiResponses.get(HttpStatus.OK) == null) {
+      ApiResponse apiResponse = new ApiResponse();
+
+      Class<?> returnType = method.getReturnType();
+      if (returnType == Void.TYPE || returnType == Void.class) {
+        return;
+      }
+
+      MediaType mediaType = new MediaType();
+
+      Schema refSchema = ModelConverter.getSchema(returnType, getComponents());
+      mediaType.schema(refSchema);
+
+      Content content = new Content();
+      content.addMediaType(MediaTypeConst.TEXT_PLAIN, mediaType);
+
+      apiResponse.description("OK");
+      apiResponse.setContent(content);
+      apiResponses.addApiResponse(HttpStatus.OK, apiResponse);
+    }
+  }
+
+  public Components getComponents() {
+    return parentContext.getComponents();
+  }
+
+  public void addResponse(String key, ApiResponse response) {
+    apiResponses.addApiResponse(key, response);
+  }
+
+  public ApiResponses getApiResponses() {
+    return apiResponses;
+  }
+
+  public void setApiResponses(ApiResponses apiResponses) {
+    this.apiResponses = apiResponses;
+  }
+
+  public String getOperationId() {
+    return operationId;
+  }
+
+  public void setOperationId(String operationId) {
+    this.operationId = operationId;
+  }
+
+  public String getPath() {
+    return path;
+  }
+
+  public void setPath(String path) {
+    this.path = path;
+  }
+
+  public Operation getOperation() {
+    return operation;
+  }
+
+  public OpenAPI getOpenAPI() {
+    return parentContext.getOpenAPI();
+  }
+
+  public Method getMethod() {
+    return method;
+  }
+
+  public OasContext getOpenApiContext() {
+    return parentContext;
+  }
+
+  public String getHttpMethod() {
+    return httpMethod;
+  }
+
+  public void setHttpMethod(String httpMethod) {
+    if (this.httpMethod != null) {
+      throw new IllegalArgumentException(String.format("too many http method in the method %s", method.getName()));
+    }
+    this.httpMethod = httpMethod.toUpperCase();
+  }
+}
diff --git a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/ParameterContext.java b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/ParameterContext.java
new file mode 100644
index 0000000..15e6721
--- /dev/null
+++ b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/ParameterContext.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.generator;
+
+import java.lang.reflect.Parameter;
+import java.lang.reflect.Type;
+
+import org.apache.servicecomb.toolkit.generator.util.ModelConverter;
+import org.apache.servicecomb.toolkit.generator.util.ParamUtils;
+
+import io.swagger.v3.oas.annotations.enums.ParameterIn;
+import io.swagger.v3.oas.models.Components;
+import io.swagger.v3.oas.models.media.Schema;
+
+public class ParameterContext {
+
+  private OperationContext parentContext;
+
+  private boolean required;
+
+  private String name;
+
+  Parameter parameter;
+
+  private Object defaultValue;
+
+
+  io.swagger.v3.oas.models.parameters.Parameter oasParameter = new io.swagger.v3.oas.models.parameters.Parameter();
+
+  public ParameterContext(OperationContext parentContext, Parameter parameter) {
+    this.parentContext = parentContext;
+    this.parameter = parameter;
+    this.parentContext.addParameter(this);
+  }
+
+
+  public io.swagger.v3.oas.models.parameters.Parameter toOasParameter() {
+
+    if (parameter == null) {
+      return null;
+    }
+    ensureName();
+    if (oasParameter.getSchema() == null) {
+      Schema refSchema = ModelConverter.getSchema(parameter.getType(), getComponents());
+      oasParameter.schema(refSchema);
+    }
+
+    if (oasParameter.getIn() == null) {
+      oasParameter.setIn(ParameterIn.QUERY.toString());
+    }
+
+    if (defaultValue != null) {
+      required = false;
+      oasParameter.getSchema().setDefault(defaultValue);
+    }
+
+    oasParameter.setRequired(required);
+
+    return oasParameter;
+  }
+
+  private void ensureName() {
+    if (name == null) {
+      // 尝试获取实际参数名
+      name = ParamUtils.getParamterName(parentContext.getMethod(), parameter);
+    }
+
+    if (name == null) {
+      name = parameter.getName();
+    }
+
+    oasParameter.setName(name);
+  }
+
+  public OperationContext getOperationContext() {
+    return parentContext;
+  }
+
+  public Type getActualType() {
+    return parameter.getParameterizedType();
+  }
+
+  public Object getDefaultValue() {
+    return defaultValue;
+  }
+
+  public void setDefaultValue(Object defaultValue) {
+    this.defaultValue = defaultValue;
+  }
+
+  public Components getComponents() {
+    return parentContext.getComponents();
+  }
+
+  public io.swagger.v3.oas.models.parameters.Parameter getOasParameter() {
+    return oasParameter;
+  }
+
+  public Parameter getParameter() {
+    return parameter;
+  }
+
+  public void setParameter(Parameter parameter) {
+    this.parameter = parameter;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+  public boolean isRequired() {
+    return required;
+  }
+
+  public void setRequired(boolean required) {
+    this.required = required;
+  }
+
+  public void setType(String type) {
+    oasParameter.setIn(type);
+  }
+}
diff --git a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/AnnotationProcessor.java b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/AnnotationProcessor.java
new file mode 100644
index 0000000..5827b55
--- /dev/null
+++ b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/AnnotationProcessor.java
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.generator.annotation;
+
+public interface AnnotationProcessor<Annotation, Context> {
+  void process(Annotation annotation, Context context);
+}
diff --git a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/ApiResponseMethodAnnotationProcessor.java b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/ApiResponseMethodAnnotationProcessor.java
new file mode 100644
index 0000000..3cbbe0a
--- /dev/null
+++ b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/ApiResponseMethodAnnotationProcessor.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.generator.annotation;
+
+import java.util.Optional;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.servicecomb.toolkit.generator.OperationContext;
+
+import io.swagger.v3.oas.annotations.headers.Header;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.models.media.MediaType;
+
+public class ApiResponseMethodAnnotationProcessor implements
+    MethodAnnotationProcessor<ApiResponse, OperationContext> {
+  @Override
+  public void process(ApiResponse response, OperationContext context) {
+
+    io.swagger.v3.oas.models.responses.ApiResponse apiResponse = new io.swagger.v3.oas.models.responses.ApiResponse();
+
+    Content[] contentAnnotations = response.content();
+    Optional.ofNullable(contentAnnotations).ifPresent(contents -> {
+      for (Content contentAnnotation : contents) {
+        io.swagger.v3.oas.models.media.Content content = new io.swagger.v3.oas.models.media.Content();
+        MediaType mediaType = new MediaType();
+        content.addMediaType(contentAnnotation.mediaType(), mediaType);
+        apiResponse.setContent(content);
+      }
+    });
+
+    if (StringUtils.isNotEmpty(response.description())) {
+      apiResponse.setDescription(response.description());
+    }
+
+    Header[] headersAnnotation = response.headers();
+    Optional.ofNullable(headersAnnotation).ifPresent(headers -> {
+      for (Header headerAnnotation : headers) {
+        io.swagger.v3.oas.models.headers.Header header = new io.swagger.v3.oas.models.headers.Header();
+        header.description(headerAnnotation.description());
+        header.deprecated(headerAnnotation.deprecated());
+        apiResponse.addHeaderObject(headerAnnotation.name(), header);
+      }
+    });
+
+    context.addResponse(response.responseCode(), apiResponse);
+  }
+}
diff --git a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/ApiResponsesMethodAnnotationProcessor.java b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/ApiResponsesMethodAnnotationProcessor.java
new file mode 100644
index 0000000..54747ae
--- /dev/null
+++ b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/ApiResponsesMethodAnnotationProcessor.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.generator.annotation;
+
+import java.util.Arrays;
+
+import org.apache.servicecomb.toolkit.generator.OperationContext;
+
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+
+public class ApiResponsesMethodAnnotationProcessor implements
+    MethodAnnotationProcessor<ApiResponses, OperationContext> {
+  @Override
+  public void process(ApiResponses responses, OperationContext context) {
+
+    MethodAnnotationProcessor apiResponseAnnotationProcessor = context.getParser()
+        .findMethodAnnotationProcessor(ApiResponse.class);
+
+    if (apiResponseAnnotationProcessor != null) {
+      Arrays.stream(responses.value()).forEach(response -> apiResponseAnnotationProcessor.process(response, context));
+    }
+  }
+}
diff --git a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/ClassAnnotationProcessor.java b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/ClassAnnotationProcessor.java
new file mode 100644
index 0000000..55d11be
--- /dev/null
+++ b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/ClassAnnotationProcessor.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.generator.annotation;
+
+public interface ClassAnnotationProcessor<Annotation, Context> extends AnnotationProcessor<Annotation, Context> {
+}
diff --git a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/MethodAnnotationProcessor.java b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/MethodAnnotationProcessor.java
new file mode 100644
index 0000000..cff77a6
--- /dev/null
+++ b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/MethodAnnotationProcessor.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.generator.annotation;
+
+public interface MethodAnnotationProcessor<Annotation, Context> extends AnnotationProcessor<Annotation, Context> {
+}
diff --git a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/ModelInterceptor.java b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/ModelInterceptor.java
new file mode 100644
index 0000000..8415e1a
--- /dev/null
+++ b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/ModelInterceptor.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.generator.annotation;
+
+import io.swagger.v3.oas.models.Components;
+import io.swagger.v3.oas.models.media.Schema;
+
+public interface ModelInterceptor {
+
+  int order();
+
+  Schema process(Class<?> cls, Components components);
+}
diff --git a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/OperationMethodAnnotationProcessor.java b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/OperationMethodAnnotationProcessor.java
new file mode 100644
index 0000000..517ea5b
--- /dev/null
+++ b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/OperationMethodAnnotationProcessor.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.generator.annotation;
+
+import org.apache.servicecomb.toolkit.generator.OperationContext;
+
+import io.swagger.v3.oas.annotations.ExternalDocumentation;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.extensions.Extension;
+import io.swagger.v3.oas.annotations.parameters.RequestBody;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import io.swagger.v3.oas.annotations.servers.Server;
+
+public class OperationMethodAnnotationProcessor implements MethodAnnotationProcessor<Operation, OperationContext> {
+
+  @Override
+  public void process(Operation annotation, OperationContext context) {
+
+    context.setOperationId(annotation.operationId());
+    String s = annotation.operationId();
+    boolean deprecated = annotation.deprecated();
+    String description = annotation.description();
+    Extension[] extensions = annotation.extensions();
+    ExternalDocumentation externalDocumentation = annotation.externalDocs();
+    RequestBody requestBody = annotation.requestBody();
+    ApiResponse[] responses = annotation.responses();
+    String method = annotation.method();
+    Server[] servers = annotation.servers();
+    SecurityRequirement[] security = annotation.security();
+    String[] tags = annotation.tags();
+    String summary = annotation.summary();
+    Parameter[] parameters = annotation.parameters();
+
+//    context.getOpenAPI().setPaths();
+
+    // responseReference未解析
+    // hidden未解析
+    // authorizations未解析
+  }
+}
diff --git a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/ParamAnnotationProcessor.java b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/ParamAnnotationProcessor.java
new file mode 100644
index 0000000..5b2b393
--- /dev/null
+++ b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/ParamAnnotationProcessor.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.generator.annotation;
+
+public interface ParamAnnotationProcessor<Annotation, ParameterContext> extends AnnotationProcessor<Annotation, ParameterContext> {
+}
diff --git a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/ParameterAnnotationProcessor.java b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/ParameterAnnotationProcessor.java
new file mode 100644
index 0000000..139bb0b
--- /dev/null
+++ b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/annotation/ParameterAnnotationProcessor.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.generator.annotation;
+
+import java.lang.reflect.Type;
+import java.util.Arrays;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.servicecomb.toolkit.generator.ParameterContext;
+
+import io.swagger.v3.core.util.ParameterProcessor;
+import io.swagger.v3.core.util.ReflectionUtils;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Schema;
+
+public class ParameterAnnotationProcessor implements ParamAnnotationProcessor<Parameter, ParameterContext> {
+
+  @Override
+  public void process(Parameter parameter, ParameterContext parameterContext) {
+
+    Schema schema = parameter.schema();
+    Type type = parameterContext.getActualType();
+    if (schema != null) {
+
+      if (StringUtils.isNotEmpty(schema.type())) {
+        parameterContext.setType(schema.type());
+        type = ReflectionUtils.typeFromString(schema.type());
+      }
+    }
+
+    ParameterProcessor
+        .applyAnnotations(parameterContext.getOasParameter(), type, Arrays.asList(parameter),
+            parameterContext.getComponents(),
+            null, null, null);
+
+    parameterContext.setRequired(parameter.required());
+  }
+}
diff --git a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/parser/AbstractAnnotationParser.java b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/parser/AbstractAnnotationParser.java
new file mode 100644
index 0000000..5b3a4fa
--- /dev/null
+++ b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/parser/AbstractAnnotationParser.java
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.generator.parser;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.servicecomb.toolkit.generator.OasContext;
+import org.apache.servicecomb.toolkit.generator.OperationContext;
+import org.apache.servicecomb.toolkit.generator.ParameterContext;
+import org.apache.servicecomb.toolkit.generator.annotation.AnnotationProcessor;
+import org.apache.servicecomb.toolkit.generator.annotation.ApiResponseMethodAnnotationProcessor;
+import org.apache.servicecomb.toolkit.generator.annotation.ApiResponsesMethodAnnotationProcessor;
+import org.apache.servicecomb.toolkit.generator.annotation.ClassAnnotationProcessor;
+import org.apache.servicecomb.toolkit.generator.annotation.MethodAnnotationProcessor;
+import org.apache.servicecomb.toolkit.generator.annotation.OperationMethodAnnotationProcessor;
+import org.apache.servicecomb.toolkit.generator.annotation.ParamAnnotationProcessor;
+import org.apache.servicecomb.toolkit.generator.annotation.ParameterAnnotationProcessor;
+import org.apache.servicecomb.toolkit.generator.parser.api.OpenApiAnnotationParser;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+
+public abstract class AbstractAnnotationParser implements OpenApiAnnotationParser {
+
+  private Class<?> cls;
+
+  private OasContext context;
+
+  protected Map<Class, ClassAnnotationProcessor> classAnnotationMap = new HashMap<>();
+
+  protected Map<Class, MethodAnnotationProcessor> methodAnnotationMap = new HashMap<>();
+
+  protected Map<Class, ParamAnnotationProcessor> parameterAnnotationMap = new HashMap<>();
+
+  public AbstractAnnotationParser() {
+    initMethodAnnotationProcessor();
+    initClassAnnotationProcessor();
+    initParameterAnnotationProcessor();
+  }
+
+  @Override
+  public void parser(Class<?> cls, OasContext context) {
+
+    this.cls = cls;
+    this.context = context;
+
+    if (!canProcess(cls)) {
+      return;
+    }
+
+    for (Annotation clsAnnotation : cls.getAnnotations()) {
+      AnnotationProcessor annotationProcessor = classAnnotationMap.get(clsAnnotation.annotationType());
+      if (annotationProcessor == null) {
+        continue;
+      }
+      annotationProcessor.process(clsAnnotation, context);
+    }
+    postParseClassAnnotaion(context);
+
+    List<Method> methods = Arrays.asList(cls.getDeclaredMethods());
+    methods.sort(Comparator.comparing(Method::getName));
+    for (Method m : methods) {
+      OperationContext operationContext = new OperationContext(m, context);
+      for (Annotation methodAnnotation : m.getAnnotations()) {
+        MethodAnnotationProcessor annotationProcessor = methodAnnotationMap.get(methodAnnotation.annotationType());
+        if (annotationProcessor != null) {
+          annotationProcessor.process(methodAnnotation, operationContext);
+        }
+      }
+
+      postParseMethodAnnotation(operationContext);
+
+      java.lang.reflect.Parameter[] parameters = m.getParameters();
+
+      for (java.lang.reflect.Parameter parameter : parameters) {
+        ParameterContext parameterContext = new ParameterContext(operationContext, parameter);
+        for (Annotation paramAnnotation : parameter.getAnnotations()) {
+          ParamAnnotationProcessor paramAnnotationProcessor = parameterAnnotationMap
+              .get(paramAnnotation.annotationType());
+          if (paramAnnotationProcessor != null) {
+            paramAnnotationProcessor.process(paramAnnotation, parameterContext);
+          }
+        }
+        postParseParameterAnnotation(parameterContext);
+      }
+    }
+  }
+
+  @Override
+  public void postParseClassAnnotaion(OasContext context) {
+  }
+
+  @Override
+  public void postParseMethodAnnotation(OperationContext context) {
+  }
+
+  @Override
+  public void postParseParameterAnnotation(ParameterContext context) {
+  }
+
+  public void initMethodAnnotationProcessor() {
+    methodAnnotationMap.put(Operation.class, new OperationMethodAnnotationProcessor());
+    methodAnnotationMap.put(ApiResponse.class, new ApiResponseMethodAnnotationProcessor());
+    methodAnnotationMap.put(ApiResponses.class, new ApiResponsesMethodAnnotationProcessor());
+  }
+
+  public void initClassAnnotationProcessor() {
+
+  }
+
+  public void initParameterAnnotationProcessor() {
+    parameterAnnotationMap.put(Parameter.class, new ParameterAnnotationProcessor());
+  }
+
+  @Override
+  public ClassAnnotationProcessor findClassAnnotationProcessor(Class<? extends Annotation> annotationType) {
+    return classAnnotationMap.get(annotationType);
+  }
+
+  @Override
+  public MethodAnnotationProcessor findMethodAnnotationProcessor(Class<? extends Annotation> annotationType) {
+    return methodAnnotationMap.get(annotationType);
+  }
+
+  @Override
+  public ParamAnnotationProcessor findParameterAnnotationProcessor(Class<? extends Annotation> annotationType) {
+    return parameterAnnotationMap.get(annotationType);
+  }
+}
diff --git a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/parser/api/OpenApiAnnotationParser.java b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/parser/api/OpenApiAnnotationParser.java
new file mode 100644
index 0000000..1fbdd9e
--- /dev/null
+++ b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/parser/api/OpenApiAnnotationParser.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.generator.parser.api;
+
+import java.lang.annotation.Annotation;
+
+import org.apache.servicecomb.toolkit.generator.OasContext;
+import org.apache.servicecomb.toolkit.generator.OperationContext;
+import org.apache.servicecomb.toolkit.generator.ParameterContext;
+import org.apache.servicecomb.toolkit.generator.annotation.ClassAnnotationProcessor;
+import org.apache.servicecomb.toolkit.generator.annotation.MethodAnnotationProcessor;
+import org.apache.servicecomb.toolkit.generator.annotation.ParamAnnotationProcessor;
+
+public interface OpenApiAnnotationParser {
+
+  /**
+   *
+   * @param cls
+   * @param context
+   */
+  void parser(Class<?> cls, OasContext context);
+
+  /**
+   * 用于排序, 对于同一个类,同时只能为springmvc或者jaxrs其中一种
+   * @return
+   */
+  int getOrder();
+
+  boolean canProcess(Class<?> cls);
+
+  void postParseClassAnnotaion(OasContext context);
+
+  void postParseMethodAnnotation(OperationContext context);
+
+  void postParseParameterAnnotation(ParameterContext context);
+
+  ClassAnnotationProcessor findClassAnnotationProcessor(Class<? extends Annotation> annotationType);
+
+  MethodAnnotationProcessor findMethodAnnotationProcessor(Class<? extends Annotation> annotationType);
+
+  ParamAnnotationProcessor findParameterAnnotationProcessor(Class<? extends Annotation> annotationType);
+}
diff --git a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/util/ArrayModelConverter.java b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/util/ArrayModelConverter.java
new file mode 100644
index 0000000..f52c57d
--- /dev/null
+++ b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/util/ArrayModelConverter.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.generator.util;
+
+import java.util.Iterator;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.type.TypeFactory;
+
+import io.swagger.v3.core.converter.AnnotatedType;
+import io.swagger.v3.core.converter.ModelConverter;
+import io.swagger.v3.core.converter.ModelConverterContext;
+import io.swagger.v3.core.jackson.AbstractModelConverter;
+import io.swagger.v3.oas.models.media.ArraySchema;
+import io.swagger.v3.oas.models.media.Schema;
+
+public class ArrayModelConverter extends AbstractModelConverter {
+
+  protected ArrayModelConverter(ObjectMapper mapper) {
+    super(mapper);
+  }
+
+  @Override
+  public Schema resolve(AnnotatedType type, ModelConverterContext context, Iterator<ModelConverter> chain) {
+
+    String typeName = _typeName(TypeFactory.defaultInstance().constructType(type.getType()));
+
+    ArraySchema schema;
+    if ("Array".equals(typeName)) {
+      schema = new ArraySchema();
+      if (!(type.getType() instanceof Class)) {
+        return null;
+      }
+      Schema itemSchema = context.resolve(new AnnotatedType(((Class) type.getType()).getComponentType()));
+      schema.setItems(itemSchema);
+      return schema;
+    }
+    return super.resolve(type, context, chain);
+  }
+}
diff --git a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/util/LocalVariableVisitor.java b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/util/LocalVariableVisitor.java
new file mode 100644
index 0000000..b7f19c1
--- /dev/null
+++ b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/util/LocalVariableVisitor.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.generator.util;
+
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Type;
+
+public class LocalVariableVisitor extends MethodVisitor {
+
+  private boolean isStatic;
+
+  private String[] parameterNames;
+
+  private final int[] lvtSlotIndex;
+
+  private final Type[] args;
+
+  public LocalVariableVisitor(int api, String desc, boolean isStatic, String[] parameterNames) {
+    super(api);
+    this.isStatic = isStatic;
+    this.parameterNames = parameterNames;
+    this.args = Type.getArgumentTypes(desc);
+    this.lvtSlotIndex = computeLvtSlotIndices(isStatic, this.args);
+  }
+
+  @Override
+  public void visitLocalVariable(String name, String descriptor, String signature, Label start, Label end,
+      int index) {
+
+    for (int i = 0; i < this.lvtSlotIndex.length; i++) {
+      if (this.lvtSlotIndex[i] == index) {
+        this.parameterNames[i] = name;
+      }
+    }
+    super.visitLocalVariable(name, descriptor, signature, start, end, index);
+  }
+
+  int[] computeLvtSlotIndices(boolean isStatic, Type[] paramTypes) {
+    int[] lvtIndex = new int[paramTypes.length];
+    int nextIndex = (isStatic ? 0 : 1);
+    for (int i = 0; i < paramTypes.length; i++) {
+      lvtIndex[i] = nextIndex;
+      if (isWideType(paramTypes[i])) {
+        nextIndex += 2;
+      } else {
+        nextIndex++;
+      }
+    }
+    return lvtIndex;
+  }
+
+  private boolean isWideType(Type aType) {
+    return (aType == Type.LONG_TYPE || aType == Type.DOUBLE_TYPE);
+  }
+}
diff --git a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/util/ModelConverter.java b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/util/ModelConverter.java
new file mode 100644
index 0000000..0370c31
--- /dev/null
+++ b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/util/ModelConverter.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.generator.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.ServiceLoader;
+
+import org.apache.servicecomb.toolkit.generator.annotation.ModelInterceptor;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+
+import io.swagger.v3.core.converter.AnnotatedType;
+import io.swagger.v3.core.converter.ModelConverterContextImpl;
+import io.swagger.v3.core.jackson.ModelResolver;
+import io.swagger.v3.core.util.PrimitiveType;
+import io.swagger.v3.core.util.RefUtils;
+import io.swagger.v3.oas.models.Components;
+import io.swagger.v3.oas.models.media.ArraySchema;
+import io.swagger.v3.oas.models.media.Schema;
+
+public class ModelConverter {
+
+  private static final ModelConverterContextImpl context;
+
+  private static final List<ModelInterceptor> interceptorMgr = new ArrayList<>();
+
+  static {
+
+    ServiceLoader.load(ModelInterceptor.class).forEach(ModelConverter::registerInterceptor);
+
+    ArrayModelConverter arrayModelConverter = new ArrayModelConverter(mapper());
+    ModelResolver modelResolver = new ModelResolver(mapper());
+
+    context = new ModelConverterContextImpl(Arrays.asList(arrayModelConverter, modelResolver));
+  }
+
+  public static void registerInterceptor(ModelInterceptor interceptor) {
+    interceptorMgr.add(interceptor);
+    interceptorMgr.sort(Comparator.comparingInt(ModelInterceptor::order));
+  }
+
+  public static Schema getSchema(Class<?> cls) {
+    return getSchema(cls, null);
+  }
+
+  public static Schema getSchema(Class<?> cls, Components components) {
+
+    for (ModelInterceptor interceptor : interceptorMgr) {
+      Schema schema = interceptor.process(cls, components);
+      if (schema != null) {
+        return schema;
+      }
+    }
+
+    Schema schema = PrimitiveType.createProperty(cls);
+    if (schema == null) {
+      schema = context
+          .resolve(new AnnotatedType(cls));
+    }
+
+    if (components == null) {
+      return schema;
+    }
+
+    Schema refSchema = schema;
+
+    if (shouldExtractRef(schema)) {
+      ensureSchemaNameExist(schema);
+      schema.$ref(null);
+      components.addSchemas(schema.getName(), schema);
+      refSchema = new Schema();
+      refSchema.set$ref(RefUtils.constructRef(schema.getName()));
+    }
+
+    if (schema instanceof ArraySchema) {
+      ArraySchema arraySchema = (ArraySchema) schema;
+      Schema itemSchema = arraySchema.getItems();
+      if (shouldExtractRef(itemSchema)) {
+        ensureSchemaNameExist(itemSchema);
+        itemSchema.$ref(null);
+        components.addSchemas(itemSchema.getName(), itemSchema);
+
+        Schema itemRefSchema = new Schema();
+        itemRefSchema.set$ref(RefUtils.constructRef(itemSchema.getName()));
+        arraySchema.setItems(itemRefSchema);
+      }
+
+      refSchema = arraySchema;
+    }
+
+    return refSchema;
+  }
+
+  private static void ensureSchemaNameExist(Schema schema) {
+    if (schema.getName() != null) {
+      return;
+    }
+
+    if (schema.get$ref() != null) {
+      schema.setName((String) RefUtils.extractSimpleName(schema.get$ref()).getKey());
+      return;
+    }
+  }
+
+  public static boolean shouldExtractRef(Schema schema) {
+    if (schema.getName() != null || schema.get$ref() != null) {
+      return true;
+    }
+    return false;
+  }
+
+
+  public static ObjectMapper mapper() {
+    ObjectMapper mapper = new ObjectMapper();
+    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+    mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
+    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+
+    return mapper;
+  }
+}
diff --git a/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/util/ParamUtils.java b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/util/ParamUtils.java
new file mode 100644
index 0000000..9093630
--- /dev/null
+++ b/oas-generator/oas-generator-core/src/main/java/org/apache/servicecomb/toolkit/generator/util/ParamUtils.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.generator.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Parameter;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+public class ParamUtils {
+
+  private static final String STATIC_CLASS_INIT = "<clinit>";
+
+  public static final Map<Method, String[]> paramterCache = new HashMap();
+
+  public static String getParamterName(Method method, Parameter parameter) {
+
+    String[] parameterNames = paramterCache.get(method);
+
+    if (parameterNames == null) {
+      parameterNames = initParamterNames(method);
+      if (parameterNames == null) {
+        return null;
+      }
+    }
+
+    int paramIndex = getParamIndex(method, parameter);
+    if (paramIndex >= 0) {
+      return parameterNames[paramIndex];
+    }
+
+    return null;
+  }
+
+  private static int getParamIndex(Method method, Parameter parameter) {
+    Parameter[] parameters = method.getParameters();
+    for (int i = 0; i < parameters.length; i++) {
+      if (parameters[i].equals(parameter)) {
+        return i;
+      }
+    }
+    return -1;
+  }
+
+  private static String[] initParamterNames(Method m) {
+
+    boolean isStatic = Modifier.isStatic(m.getModifiers());
+    String[] paramterNames = new String[m.getParameterCount()];
+
+    try {
+
+      String className = m.getDeclaringClass().getName();
+      String classRawName = className.replace('.', '/') + ".class";
+
+      InputStream is = null;
+      ClassLoader classLoader = m.getDeclaringClass().getClassLoader();
+      if (classLoader != null) {
+        is = classLoader.getResourceAsStream(classRawName);
+      } else {
+        is = m.getDeclaringClass().getResourceAsStream(classRawName);
+      }
+
+      if (is == null) {
+        return null;
+      }
+      ClassReader clsReader = new ClassReader(is);
+      ClassWriter clsWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+
+      clsReader.accept(new ClassVisitor(Opcodes.ASM7, clsWriter) {
+        @Override
+        public MethodVisitor visitMethod(int access, String name, String descriptor, String signature,
+            String[] exceptions) {
+          MethodVisitor methodVisitor = super.visitMethod(access, name, descriptor, signature, exceptions);
+          if (!m.getName().equals(name) || !descriptor.equals(Type.getMethodDescriptor(m))) {
+            return methodVisitor;
+          }
+
+          if (!isSyntheticOrBridged(access) && !STATIC_CLASS_INIT.equals(name)) {
+            return new LocalVariableVisitor(this.api, descriptor, isStatic, paramterNames);
+          }
+
+          return methodVisitor;
+        }
+      }, 0);
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+
+    paramterCache.put(m, paramterNames);
+
+    return paramterNames;
+  }
+
+  private static boolean isSyntheticOrBridged(int access) {
+    return (((access & Opcodes.ACC_SYNTHETIC) | (access & Opcodes.ACC_BRIDGE)) > 0);
+  }
+}
diff --git a/oas-generator/oas-generator-core/src/test/java/org/apache/servicecomb/toolkit/generator/AnnotationProcessorTest.java b/oas-generator/oas-generator-core/src/test/java/org/apache/servicecomb/toolkit/generator/AnnotationProcessorTest.java
new file mode 100644
index 0000000..c6bbf56
--- /dev/null
+++ b/oas-generator/oas-generator-core/src/test/java/org/apache/servicecomb/toolkit/generator/AnnotationProcessorTest.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.generator;
+
+import java.lang.reflect.Method;
+
+import org.apache.servicecomb.toolkit.generator.annotation.ApiResponseMethodAnnotationProcessor;
+import org.apache.servicecomb.toolkit.generator.annotation.ApiResponsesMethodAnnotationProcessor;
+import org.apache.servicecomb.toolkit.generator.annotation.OperationMethodAnnotationProcessor;
+import org.apache.servicecomb.toolkit.generator.annotation.ParameterAnnotationProcessor;
+import org.apache.servicecomb.toolkit.generator.parser.AbstractAnnotationParser;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import io.swagger.v3.oas.models.media.StringSchema;
+
+public class AnnotationProcessorTest {
+
+  @Test
+  public void processApiResponseAnnotation() {
+
+    OasContext oasContext = new OasContext(null);
+    OperationContext context = new OperationContext(null, oasContext);
+    ApiResponseMethodAnnotationProcessor apiResProcessor = new ApiResponseMethodAnnotationProcessor();
+    ApiResponse apiResponse = Mockito.mock(ApiResponse.class);
+    Content[] contents = new Content[1];
+    contents[0] = Mockito.mock(Content.class);
+    Mockito.when(contents[0].mediaType()).thenReturn(MediaTypeConst.APPLICATION_JSON);
+    Mockito.when(apiResponse.content()).thenReturn(contents);
+    Mockito.when(apiResponse.responseCode()).thenReturn("200");
+    apiResProcessor.process(apiResponse, context);
+
+    Assert.assertNotNull(context.getApiResponses().get("200"));
+    Assert.assertNull(context.getApiResponses().get("500"));
+  }
+
+  @Test
+  public void processApiResponsesAnnotation() {
+
+    OasContext oasContext = new OasContext(new AbstractAnnotationParser() {
+      @Override
+      public int getOrder() {
+        return 0;
+      }
+
+      @Override
+      public boolean canProcess(Class<?> cls) {
+        return true;
+      }
+    });
+
+    OperationContext context = new OperationContext(null, oasContext);
+    ApiResponsesMethodAnnotationProcessor apiRessProcessor = new ApiResponsesMethodAnnotationProcessor();
+    ApiResponses apiResponses = Mockito.mock(ApiResponses.class);
+    Content[] contents = new Content[1];
+    contents[0] = Mockito.mock(Content.class);
+    Mockito.when(contents[0].mediaType()).thenReturn(MediaTypeConst.APPLICATION_JSON);
+    ApiResponse apiResponse = Mockito.mock(ApiResponse.class);
+    Mockito.when(apiResponse.content()).thenReturn(contents);
+    Mockito.when(apiResponse.responseCode()).thenReturn("200");
+    Mockito.when(apiResponses.value()).thenReturn(new ApiResponse[] {apiResponse});
+
+    apiRessProcessor.process(apiResponses, context);
+
+    Assert.assertNotNull(context.getApiResponses().get("200"));
+    Assert.assertNull(context.getApiResponses().get("500"));
+  }
+
+  @Test
+  public void processOperationAnnotation() {
+
+    OasContext oasContext = new OasContext(null);
+    OperationContext context = new OperationContext(null, oasContext);
+    OperationMethodAnnotationProcessor operationMethodAnnotationProcessor = new OperationMethodAnnotationProcessor();
+    Operation operation = Mockito.mock(Operation.class);
+    operationMethodAnnotationProcessor.process(operation, context);
+  }
+
+
+  @Test
+  public void processParameterAnnotation() throws NoSuchMethodException, IllegalAccessException,
+      InstantiationException {
+
+    OasContext oasContext = new OasContext(null);
+    Method parameterMethod = ParameterClass.class.getMethod("parameter", String.class);
+    OperationContext operationContext = new OperationContext(parameterMethod, oasContext);
+    java.lang.reflect.Parameter[] parameters = parameterMethod.getParameters();
+    Assert.assertEquals(parameters.length, 1);
+    java.lang.reflect.Parameter parameter = parameters[0];
+    Parameter parameterDeclaredAnnotation = parameter.getDeclaredAnnotation(Parameter.class);
+
+    ParameterContext parameterContext = new ParameterContext(operationContext, parameter);
+    ParameterAnnotationProcessor parameterAnnotationProcessor = new ParameterAnnotationProcessor();
+
+    parameterAnnotationProcessor.process(parameterDeclaredAnnotation, parameterContext);
+    io.swagger.v3.oas.models.parameters.Parameter oasParameter = parameterContext.toOasParameter();
+    Assert.assertEquals("param", oasParameter.getName());
+    Assert.assertEquals(StringSchema.class, oasParameter.getSchema().getClass());
+    Assert.assertTrue(parameterContext.isRequired());
+    Assert.assertEquals(operationContext, parameterContext.getOperationContext());
+    Assert.assertNull(parameterContext.getDefaultValue());
+  }
+
+  class ParameterClass {
+    public void parameter(@Parameter(required = true) String param) {
+    }
+  }
+}
diff --git a/oas-generator/oas-generator-core/src/test/java/org/apache/servicecomb/toolkit/generator/OasGeneratorTest.java b/oas-generator/oas-generator-core/src/test/java/org/apache/servicecomb/toolkit/generator/OasGeneratorTest.java
new file mode 100644
index 0000000..d454d7d
--- /dev/null
+++ b/oas-generator/oas-generator-core/src/test/java/org/apache/servicecomb/toolkit/generator/OasGeneratorTest.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.generator;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Parameter;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import io.swagger.v3.oas.annotations.enums.ParameterIn;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.PathItem.HttpMethod;
+
+public class OasGeneratorTest {
+
+  @Test
+  public void generatorOas() {
+
+    Set<Class> classSet = new HashSet<>();
+    classSet.add(NoResource.class);
+    classSet.add(OneResource.class);
+    OasGenerator generator = new OasGenerator();
+    generator.generate(classSet);
+  }
+
+  @Test
+  public void constructOasContext() throws NoSuchMethodException {
+    OasContext oasContext = new OasContext(null);
+
+    Method method = OneResource.class.getMethod("name", String.class);
+    OperationContext operationContext = new OperationContext(method, oasContext);
+    operationContext.setHttpMethod(HttpMethod.GET.name());
+    operationContext.setOperationId(method.getName());
+    operationContext.setPath("/operation");
+
+    oasContext.addOperation(operationContext);
+    oasContext.setCls(method.getDeclaringClass());
+    oasContext.setBasePath("/oas");
+    oasContext.setParser(null);
+
+    Assert.assertEquals("/oas", oasContext.getBasePath());
+    Assert.assertEquals(method.getDeclaringClass(), oasContext.getCls());
+    Assert.assertNull(oasContext.getParser());
+
+    Assert.assertEquals("/operation", operationContext.getPath());
+    Assert.assertEquals(HttpMethod.GET.name(), operationContext.getHttpMethod());
+    Assert.assertEquals(oasContext.getComponents(), operationContext.getComponents());
+    Assert.assertEquals(null, operationContext.getApiResponses().getDefault());
+    Assert.assertEquals(oasContext.getOpenAPI(), operationContext.getOpenAPI());
+
+    Parameter parameter = method.getParameters()[0];
+    ParameterContext parameterContext = new ParameterContext(operationContext, parameter);
+    parameterContext.setName(parameter.getName());
+    parameterContext.setRequired(true);
+    parameterContext.setType(ParameterIn.QUERY.toString());
+
+    Assert.assertEquals(parameter.getName(), parameterContext.getName());
+
+    OpenAPI openAPI = oasContext.toOpenAPI();
+    Assert.assertNotNull(openAPI);
+  }
+
+  class NoResource {
+
+  }
+
+  class OneResource {
+    public String name(String name) {
+      return name;
+    }
+  }
+}
diff --git a/oas-generator/oas-generator-core/src/test/java/org/apache/servicecomb/toolkit/generator/ParserTest.java b/oas-generator/oas-generator-core/src/test/java/org/apache/servicecomb/toolkit/generator/ParserTest.java
new file mode 100644
index 0000000..c0b37e3
--- /dev/null
+++ b/oas-generator/oas-generator-core/src/test/java/org/apache/servicecomb/toolkit/generator/ParserTest.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.generator;
+
+import org.apache.servicecomb.toolkit.generator.parser.AbstractAnnotationParser;
+import org.junit.Test;
+
+import io.swagger.v3.oas.annotations.OpenAPIDefinition;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+
+public class ParserTest {
+
+  @Test
+  public void parse() {
+    AbstractAnnotationParser parser = new TestParser();
+
+    parser.parser(UnParser.class, new OasContext(parser));
+  }
+
+  class TestParser extends AbstractAnnotationParser {
+
+    @Override
+    public int getOrder() {
+      return 0;
+    }
+
+    @Override
+    public boolean canProcess(Class<?> cls) {
+      return true;
+    }
+  }
+
+  @OpenAPIDefinition
+  class UnParser {
+    @ApiResponse
+    public String name(String name) {
+      return name;
+    }
+  }
+}
diff --git a/oas-generator/oas-generator-core/src/test/java/org/apache/servicecomb/toolkit/generator/UtilsTest.java b/oas-generator/oas-generator-core/src/test/java/org/apache/servicecomb/toolkit/generator/UtilsTest.java
new file mode 100644
index 0000000..224dbf9
--- /dev/null
+++ b/oas-generator/oas-generator-core/src/test/java/org/apache/servicecomb/toolkit/generator/UtilsTest.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.generator;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Parameter;
+
+import org.apache.servicecomb.toolkit.generator.annotation.ModelInterceptor;
+import org.apache.servicecomb.toolkit.generator.util.ModelConverter;
+import org.apache.servicecomb.toolkit.generator.util.ParamUtils;
+import org.junit.Assert;
+import org.junit.Test;
+
+import io.swagger.v3.oas.models.Components;
+import io.swagger.v3.oas.models.media.ArraySchema;
+import io.swagger.v3.oas.models.media.Schema;
+import io.swagger.v3.oas.models.media.StringSchema;
+
+public class UtilsTest {
+
+  @Test
+  public void getParameterName() throws NoSuchMethodException {
+
+    Method method = ParameterClass.class.getMethod("method", String.class);
+    Parameter parameter = method.getParameters()[0];
+    String paramterName = ParamUtils.getParamterName(method, parameter);
+    Assert.assertEquals("param", paramterName);
+  }
+
+  @Test
+  public void getSchema() {
+    Schema schema = ModelConverter.getSchema(String.class);
+    Assert.assertEquals(StringSchema.class, schema.getClass());
+
+    schema = ModelConverter.getSchema(ParameterClass.class);
+    Assert.assertEquals(Schema.class, schema.getClass());
+
+    schema = ModelConverter.getSchema(String[].class);
+    Assert.assertEquals(ArraySchema.class, schema.getClass());
+
+    Components components = new Components();
+    schema = ModelConverter.getSchema(ParameterClass[].class, components);
+    Assert.assertEquals(ArraySchema.class, schema.getClass());
+
+    schema = ModelConverter.getSchema(ParameterClass.class, components);
+    Assert.assertNotNull(schema.get$ref());
+
+    ModelConverter.registerInterceptor(new ModelInterceptor() {
+      @Override
+      public int order() {
+        return 0;
+      }
+
+      @Override
+      public Schema process(Class<?> cls, Components components) {
+        return new Schema().name("unknown");
+      }
+    });
+
+    schema = ModelConverter.getSchema(ParameterClass.class);
+    Assert.assertEquals("unknown", schema.getName());
+  }
+
+  class ParameterClass {
+    public void method(String param) {
+    }
+  }
+}
diff --git a/oas-generator/pom.xml b/oas-generator/pom.xml
new file mode 100644
index 0000000..123ec2c
--- /dev/null
+++ b/oas-generator/pom.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <parent>
+    <artifactId>toolkit</artifactId>
+    <groupId>org.apache.servicecomb.toolkit</groupId>
+    <version>0.2.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <packaging>pom</packaging>
+  <modules>
+    <module>oas-generator-core</module>
+  </modules>
+
+  <artifactId>oas-generator</artifactId>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-module-junit4</artifactId>
+      <version>1.6.2</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-api-mockito</artifactId>
+      <version>1.6.2</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.8.1</version>
+        <configuration>
+          <target>1.8</target>
+          <source>1.8</source>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+</project>
\ No newline at end of file