Skip to content

Commit

Permalink
Merge pull request #9576 from ishaigor/master
Browse files Browse the repository at this point in the history
Fixing support for references in Maps
  • Loading branch information
HugoMario authored Jul 23, 2019
2 parents 2b134ac + 25a6696 commit 5fdfaa4
Show file tree
Hide file tree
Showing 5 changed files with 302 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1159,8 +1159,9 @@ public String getSwaggerType(Property p) {
try {
RefProperty r = (RefProperty) p;
datatype = r.get$ref();
if (datatype.indexOf("#/definitions/") == 0) {
datatype = datatype.substring("#/definitions/".length());
// '#/definitions' or ../../../../relative-ref/nested/directory/definitions/photos.yml#/definitions/
if (datatype.indexOf("#/definitions/") >= 0) {
datatype = datatype.substring(datatype.indexOf("#/definitions/") + "#/definitions/".length());
}
} catch (Exception e) {
LOGGER.warn("Error obtaining the datatype from RefProperty:" + p + ". Datatype default to Object");
Expand Down Expand Up @@ -2006,7 +2007,7 @@ protected void setNonArrayMapProperty(CodegenProperty property, String type) {
/**
* Override with any special handling of response codes
* @param responses Swagger Operation's responses
* @return default method response or <tt>null</tt> if not found
* @return default method response or &lt;tt&gt;null&lt;/tt&gt; if not found
*/
protected Response findMethodResponse(Map<String, Response> responses) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,51 @@ public void multiInheritanceOfComposedModelTest() {
Assert.assertEquals(child.parent, "ChildOfComposedParent");
}

@Test(description = "use relative $ref for definitions of parameters")
public void relativeDefinitionsInParameterTest() {
final Swagger model = parseAndPrepareSwagger("src/test/resources/2_0/relative-ref/nested/directory/main/relative-refs.yml");
final DefaultCodegen codegen = new DefaultCodegen();
final String path = "/photo/getPhotos";
final Operation p = model.getPaths().get(path).getPost();
CodegenOperation op = codegen.fromOperation(path, "post", p, model.getDefinitions(), model);

Assert.assertNotNull(op);
Assert.assertNotNull(op.imports);
Assert.assertTrue(op.imports.contains("Photo"));
Assert.assertTrue(op.imports.contains("PhotosRequest"));

}

@Test(description = "use relative $ref for definitions of response")
public void relativeDefinitionsInResponseTest() {
final Swagger model = parseAndPrepareSwagger("src/test/resources/2_0/relative-ref/nested/directory/main/relative-refs.yml");
final DefaultCodegen codegen = new DefaultCodegen();
final String path = "/photo/{id}";
final Operation p = model.getPaths().get(path).getGet();
CodegenOperation op = codegen.fromOperation(path, "get", p, model.getDefinitions(), model);

Assert.assertNotNull(op);
Assert.assertNotNull(op.imports);
Assert.assertTrue(op.imports.contains("Photo"));
Assert.assertTrue(op.imports.contains("integer"));

}

@Test(description = "use relative $ref for definitions of response")
public void relativeDefinitionsMapInResponseTest() {
final Swagger model = parseAndPrepareSwagger("src/test/resources/2_0/relative-ref/nested/directory/main/relative-refs.yml");
final DefaultCodegen codegen = new DefaultCodegen();
final String path = "/photo/thumbnails";
final Operation p = model.getPaths().get(path).getPost();
CodegenOperation op = codegen.fromOperation(path, "post", p, model.getDefinitions(), model);

Assert.assertNotNull(op);
Assert.assertNotNull(op.imports);
Assert.assertTrue(op.imports.contains("Photo"));
Assert.assertTrue(op.imports.contains("PhotoThumbnailsRequest"));

}

@Test(description = "use operation consumes and produces")
public void localConsumesAndProducesTest() {
final Swagger model = parseAndPrepareSwagger("src/test/resources/2_0/globalConsumesAndProduces.json");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.swagger.codegen;

import io.swagger.codegen.config.CodegenConfigurator;
import io.swagger.codegen.languages.JavaClientCodegen;
import io.swagger.models.ExternalDocs;
import io.swagger.models.Swagger;
Expand Down Expand Up @@ -225,7 +226,54 @@ public void testIssue9132() throws Exception {

}

private boolean containsOverloadedComments(File file, String ...search) throws IOException {
@Test
public void testRelativeRefs() throws IOException {
final File output = folder.getRoot();

CodegenConfigurator codegenConfigurator = new CodegenConfigurator();
codegenConfigurator.setInputSpec("src/test/resources/2_0/relative-ref/nested/directory/main/relative-refs.yml");
codegenConfigurator.setOutputDir(output.getAbsolutePath());
codegenConfigurator.setLang("java");

Map<String, Object> additionalProperties = new HashMap<>();
additionalProperties.put("dateLibrary", "java8");
additionalProperties.put("library", "feign");
additionalProperties.put("apiTests", false);
additionalProperties.put("hideGenerationTimestamp", true);
additionalProperties.put("invokerPackage", "com.mycompany.generated.client");
additionalProperties.put("modelPackage", "com.mycompany.generated.client.model");
additionalProperties.put("apiPackage", "com.mycompany.generated.client.api");

codegenConfigurator.setAdditionalProperties(additionalProperties);

Map<String, String> importMapping = new HashMap<>();

importMapping.put("LocalDateTime", "java.time.LocalDateTime");
importMapping.put("LocalTime", "java.time.LocalTime");
importMapping.put("DayOfWeek", "java.time.DayOfWeek");
importMapping.put("Duration", "java.time.Duration");
importMapping.put("ChronoUnit", "java.time.temporal.ChronoUnit");
importMapping.put("Currency", "java.util.Currency");
importMapping.put("LocalDate", "java.time.LocalDate");
importMapping.put("Locale", "java.util.Locale");
importMapping.put("ZoneId", "java.time.ZoneId");

codegenConfigurator.setImportMappings(importMapping);

DefaultGenerator generator = new DefaultGenerator();
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.API_TESTS, "false");
generator.setGeneratorPropertyDefault(CodegenConstants.API_DOCS, "false");

//generate
generator.opts(codegenConfigurator.toClientOptInput()).generate();
final File defaultApi = new File(output, "src/main/java/com/mycompany/generated/client/api/DefaultApi.java");
assertTrue(defaultApi.exists());
assertFalse(containsSearchStrings(defaultApi,"RelativeRefnesteddirectorydefinitionsphotosYmldefinitionsPhoto"));
}

private boolean containsSearchStrings(File file, String ...search) throws IOException {
for (String line : Files.readAllLines(file.toPath(), Charset.defaultCharset())) {
if (StringUtils.containsAny(line, search)) {
return true;
Expand All @@ -235,6 +283,10 @@ private boolean containsOverloadedComments(File file, String ...search) throws I
return false;
}

private boolean containsOverloadedComments(File file, String ...search) throws IOException {
return containsSearchStrings(file, search);
}

@Test
public void testOverloadingTemplateFiles() throws Exception {
final File output = folder.getRoot();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
swagger: '2.0'
info:
title: Photos API
description: Photo service

schemes:
- http

produces:
- application/json

# prefix for all paths
# for breaking changes, we need to change the basePath and add a second swagger file
basePath: /v1

paths:
/photo/photos:
post:
operationId: getPhotos
description: Retrieve photos by ids
parameters:
- name: photosRequest
in: body
required: true
description: The photos being requested
schema:
$ref: '#/definitions/PhotosRequest'
responses:
200:
description: A collection of Photos
schema:
type: array
items:
$ref: '#/definitions/Photo'

definitions:
Photo:
properties:
id:
type: integer
format: int32
description: The photo id (always present in the response)
caption:
type: string
description: |
Caption to be shown for the photo in the UI.
uploadDate:
type: string
format: date
description: The upload date for the image (requested using PhotoField.UPLOAD_DATE)
uploadDateTime:
type: string
format: date-time
description: The upload date-time (in UTC) for the image (requested using PhotoField.UPLOAD_DATETIME)

PhotosRequest:
required:
- photoIds
- photoFields
properties:
photoIds:
type: array
items:
type: integer
format: int32
photoFields:
description: |
The fields of a photo object to be retrieved.
If none are specified, only the id comes back
type: array
items:
$ref: '#/definitions/PhotoField'

PhotoField:
type: string
enum:
- CAPTION
- UPLOAD_DATE
- UPLOAD_DATETIME

PhotoThumbnailsRequest:
required:
- ids
- photoFields
properties:
ids:
type: array
items:
type: integer
format: int32
photoFields:
description: |
The fields of a photo object to be retrieved.
If none are specified, only the id comes back
type: array
items:
$ref: '#/definitions/PhotoField'
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
swagger: '2.0'
info:
title: API Definition with Relative models
description: This is an example
schemes:
- https
- http

produces:
- application/json

basePath: /v1

paths:
/photo/getPhotos:
post:
operationId: getPhotos
description: Retrieve photos by ids
parameters:
- name: photosRequest
in: body
required: true
description: The photos being requested
schema:
$ref: '../../../../relative-ref/nested/directory/definitions/photos.yml#/definitions/PhotosRequest'
responses:
200:
description: A collection of Photos
schema:
type: array
items:
$ref: '../../../../relative-ref/nested/directory/definitions/photos.yml#/definitions/Photo'

/photo/{id}:
get:
operationId: get photo by Id
description: Retrieve photo by id
parameters:
- name: "id"
in: "path"
description: "id"
required: true
type: integer
format: int32
responses:
200:
description: A collection of Photos
schema:
type: array
items:
$ref: '../../../../relative-ref/nested/directory/definitions/photos.yml#/definitions/Photo'

/photo/getPhotoPreview/{id}:
post:
operationId: getPhotoPreview
description: get thumbnail preview of a photo
parameters:
- name: id
in: path
type: integer
minimum: 1
required: true
description: the id of photo thumbnail requested
responses:
200:
description: the response containing a preview thumbnail, along with some additional information about the photo
schema:
$ref: '#/definitions/PhotoPreview'

/photo/thumbnails:
post:
operationId: getThumbnails
description: Retrieve photo thumbnails by ids
parameters:
- name: photoThumbnailsRequest
in: body
required: true
description: The photos being requested
schema:
$ref: '../../../../relative-ref/nested/directory/definitions/photos.yml#/definitions/PhotoThumbnailsRequest'
responses:
200:
description: |
A map of id -> photo for requested ids.
schema:
type: object
additionalProperties:
$ref: '../../../../relative-ref/nested/directory/definitions/photos.yml#/definitions/Photo'

definitions:
PhotoPreview:
type: object
properties:
id:
description: the id of the newly inserted photo
type: integer
format: int32
caption:
description: the caption of the photo
type: string
thumbnail:
description: The media binary of thumbnail
type: string
format: byte

0 comments on commit 5fdfaa4

Please sign in to comment.