Skip to content

Commit

Permalink
[SCB-2020]support @example to add examples to API
Browse files Browse the repository at this point in the history
  • Loading branch information
liubao68 committed Jun 23, 2020
1 parent 5cee981 commit 2b4c904
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 2 deletions.
Expand Up @@ -16,6 +16,10 @@
* limitations under the License.
*/

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;

import org.apache.servicecomb.core.BootListener;
import org.apache.servicecomb.demo.TestMgr;
import org.apache.servicecomb.registry.RegistrationManager;
Expand All @@ -26,14 +30,37 @@
*/
@Component
public class ConsumerTestsAfterBootup implements BootListener {
public void testRegisterPath() {
private void testRegisterPath() {
TestMgr.check(RegistrationManager.INSTANCE.getMicroservice().getPaths().size(), 0);
}

private void testSchemaContent() {
String content = RegistrationManager.INSTANCE.getMicroservice().getSchemaMap().get("SpringMVCSchema");
TestMgr.check(content.replaceAll("\\s", ""),
readFile("SpringMVCSchema.yaml").replaceAll("[\\s#]", ""));
}

private String readFile(String restController) {
// test code, make simple
try {
InputStream inputStream = this.getClass().getResource("/" + restController).openStream();
byte[] buffer = new byte[2048 * 10];
inputStream.skip(1000);
int len = inputStream.read(buffer);
TestMgr.check(2048 * 10 > len, true);
inputStream.close();
return new String(buffer, 0, len, Charset.forName("UTF-8"));
} catch (IOException e) {
TestMgr.failed(e.getMessage(), e);
return null;
}
}

@Override
public void onBootEvent(BootEvent event) {
if (event.getEventType() == BootListener.EventType.AFTER_REGISTRY) {
testRegisterPath();
testSchemaContent();
if (!TestMgr.isSuccess()) {
TestMgr.summary();
throw new IllegalStateException("some tests are failed. ");
Expand Down
@@ -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.demo.springmvc.client;

import javax.servlet.http.HttpServletRequest;

import org.apache.servicecomb.provider.rest.common.RestSchema;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.Example;
import io.swagger.annotations.ExampleProperty;

@RestSchema(schemaId = "SpringMVCSchema")
@RequestMapping("/springMvcSchema")
public class SpringMVCSchema {
@ApiResponses({
@ApiResponse(code = 200, response = String.class, message = "success",
examples = @Example({
@ExampleProperty(value = "wget http://localhost/springMvcSchema/testApiExample", mediaType = "text"),
@ExampleProperty(value = "{name:hello}", mediaType = "application/json"),
@ExampleProperty(value = "{name:hello}", mediaType = "json")})
)})
@RequestMapping(path = "/testApiExample", method = RequestMethod.POST)
public String testApiExample(@RequestBody String name, HttpServletRequest request) {
return null;
}
}
@@ -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.
## ---------------------------------------------------------------------------

################################################################################
################################################################################
################################################################################
################################################################################

---
swagger: "2.0"
info:
version: "1.0.0"
title: "swagger definition for org.apache.servicecomb.demo.springmvc.client.SpringMVCSchema"
x-java-interface: "gen.swagger.SpringMVCSchemaIntf"
basePath: "/springMvcSchema"
schemes:
- "http"
consumes:
- "application/json"
produces:
- "application/json"
paths:
/testApiExample:
post:
operationId: "testApiExample"
parameters:
- in: "body"
name: "name"
required: true
schema:
type: "string"
responses:
"200":
description: "success"
examples:
text: "wget http://localhost/springMvcSchema/testApiExample"
application/json: "{name:hello}"
json: "{name:hello}"
schema:
type: "string"
Expand Up @@ -30,6 +30,7 @@

import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ExampleProperty;
import io.swagger.annotations.ResponseHeader;
import io.swagger.converter.ModelConverters;
import io.swagger.models.Model;
Expand Down Expand Up @@ -79,6 +80,7 @@ private static ResponseConfig convert(ApiResponse apiResponse) {
responseConfig.setResponseContainer(apiResponse.responseContainer());
responseConfig.setResponseReference(apiResponse.reference());
responseConfig.setResponseHeaders(apiResponse.responseHeaders());
responseConfig.setExamples(apiResponse.examples());
return responseConfig;
}

Expand Down Expand Up @@ -150,7 +152,7 @@ private static void generateResponse(Swagger swagger, ResponseConfig responseCon
response.setResponseSchema(model);
}
response.setDescription(responseConfig.getDescription());

addExamplesToResponse(response, responseConfig);
if (responseConfig.getResponseHeaders() != null) {
Map<String, Property> headers = generateResponseHeader(swagger, responseConfig.getResponseHeaders());
response.setHeaders(headers);
Expand All @@ -159,6 +161,22 @@ private static void generateResponse(Swagger swagger, ResponseConfig responseCon
responseConfig.setResponse(response);
}

private static void addExamplesToResponse(Response response, ResponseConfig responseConfig) {
if (responseConfig.getExamples() != null) {
for (ExampleProperty property : responseConfig.getExamples().value()) {
if (StringUtils.isEmpty(property.mediaType()) && StringUtils.isEmpty(property.value())) {
// @ApiResponse default value has one element, but type and value is empty.
// ignore this default value.
continue;
}
if (StringUtils.isEmpty(property.mediaType())) {
throw new IllegalStateException("media type is required in examples. e.g. 'text', 'json'.");
}
response.example(property.mediaType(), property.value());
}
}
}

private static Map<String, Property> generateResponseHeader(Swagger swagger,
List<ResponseHeaderConfig> responseHeaders) {
Map<String, Property> headers = new HashMap<>();
Expand Down
Expand Up @@ -21,6 +21,7 @@

import org.apache.servicecomb.swagger.generator.core.processor.annotation.AnnotationUtils;

import io.swagger.annotations.Example;
import io.swagger.annotations.ResponseHeader;
import io.swagger.models.Response;

Expand All @@ -36,6 +37,8 @@ public class ResponseConfig extends ResponseConfigBase {
// 根据本config生成的response
private Response response;

private Example examples;

public int getCode() {
return code;
}
Expand Down Expand Up @@ -69,4 +72,12 @@ public Response getResponse() {
public void setResponse(Response response) {
this.response = response;
}

public Example getExamples() {
return examples;
}

public void setExamples(Example examples) {
this.examples = examples;
}
}

0 comments on commit 2b4c904

Please sign in to comment.