Skip to content

Commit

Permalink
Migrate from Swagger v1 to v2 (#2)
Browse files Browse the repository at this point in the history
* Convert Swagger to SpringDoc & OpenAPI

* Drop springdoc tag where not applicable

* Add missing license headers

* Move SpringDoc recipes to openrewrite/rewrite-spring

- openrewrite/rewrite-spring#470

* Implement and test ConvertApiResponseCodesToStrings

* Consistently use package including swagger

* Update categories

* Trigger validation of Yaml recipes with a test
  • Loading branch information
timtebeek authored Feb 10, 2024
1 parent 9971ef1 commit eed4590
Show file tree
Hide file tree
Showing 9 changed files with 381 additions and 114 deletions.
3 changes: 3 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,8 @@ dependencies {

testImplementation("org.junit.jupiter:junit-jupiter-engine:latest.release")

testRuntimeOnly("io.swagger:swagger-annotations:1.6.13")
testRuntimeOnly("io.swagger.core.v3:swagger-annotations:2.2.20")

testRuntimeOnly("org.gradle:gradle-tooling-api:latest.release")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright 2024 the original author or authors.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* https://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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.openrewrite.openapi.swagger;

import org.openrewrite.ExecutionContext;
import org.openrewrite.Preconditions;
import org.openrewrite.Recipe;
import org.openrewrite.TreeVisitor;
import org.openrewrite.internal.ListUtils;
import org.openrewrite.java.AnnotationMatcher;
import org.openrewrite.java.JavaIsoVisitor;
import org.openrewrite.java.search.UsesType;
import org.openrewrite.java.tree.Expression;
import org.openrewrite.java.tree.J;
import org.openrewrite.java.tree.JavaType;

public class ConvertApiResponseCodesToStrings extends Recipe {

private static final AnnotationMatcher ANNOTATION_MATCHER = new AnnotationMatcher("@io.swagger.v3.oas.annotations.responses.ApiResponse");

@Override
public String getDisplayName() {
return "Convert API response codes to strings";
}

@Override
public String getDescription() {
return "Convert API response codes to strings.";
}

@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
// https://docs.swagger.io/swagger-core/v1.5.0/apidocs/io/swagger/annotations/ApiResponse.html
// https://docs.swagger.io/swagger-core/v2.0.0/apidocs/io/swagger/v3/oas/annotations/responses/ApiResponse.html
return Preconditions.check(
new UsesType<>("io.swagger.v3.oas.annotations.responses.ApiResponse", true),
new JavaIsoVisitor<ExecutionContext>() {
@Override
public J.Annotation visitAnnotation(J.Annotation annotation, ExecutionContext ctx) {
J.Annotation an = super.visitAnnotation(annotation, ctx);
if (ANNOTATION_MATCHER.matches(an)) {
return an.withArguments(ListUtils.map(an.getArguments(), this::maybeReplaceResponseCodeTypeAndValue));
}
return an;
}

private Expression maybeReplaceResponseCodeTypeAndValue(Expression arg) {
if (arg instanceof J.Assignment) {
J.Assignment assignment = (J.Assignment) arg;
boolean matchesField = assignment.getVariable() instanceof J.Identifier &&
"responseCode".equals(((J.Identifier) assignment.getVariable()).getSimpleName());
boolean usesNumberLiteral = assignment.getAssignment() instanceof J.Literal &&
((J.Literal) assignment.getAssignment()).getValue() instanceof Number;
if (matchesField && usesNumberLiteral) {
J.Literal assignedLiteral = (J.Literal) assignment.getAssignment();
return assignment
.withType(JavaType.Primitive.String)
.withAssignment(assignedLiteral
.withValue(String.valueOf(assignedLiteral.getValue()))
.withValueSource("\"" + assignedLiteral.getValue() + "\"")
.withType(JavaType.Primitive.String));
}
}
return arg;
}
}
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
@NonNullApi
@NonNullFields
package org.openrewrite.openapi;
package org.openrewrite.openapi.swagger;

import org.openrewrite.internal.lang.NonNullApi;
import org.openrewrite.internal.lang.NonNullFields;
7 changes: 6 additions & 1 deletion src/main/resources/META-INF/rewrite/category.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,9 @@
type: specs.openrewrite.org/v1beta/category
name: OpenAPI
packageName: org.openrewrite.openapi
description: Recipes to perform [OpenAPI](https://openapi.com/) migration tasks.
description: Recipes to perform [OpenAPI](https://www.openapis.org/) migration tasks.
---
type: specs.openrewrite.org/v1beta/category
name: Swagger
packageName: org.openrewrite.openapi.swagger
description: Recipes to perform [Swagger](https://swagger.io/) migration tasks.
26 changes: 0 additions & 26 deletions src/main/resources/META-INF/rewrite/openapi-3.yml

This file was deleted.

178 changes: 178 additions & 0 deletions src/main/resources/META-INF/rewrite/swagger-2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
#
# Copyright 2024 the original author or authors.
# <p>
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# <p>
# https://www.apache.org/licenses/LICENSE-2.0
# <p>
# 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.
#

type: specs.openrewrite.org/v1beta/recipe
name: org.openrewrite.openapi.swagger.SwaggerToOpenAPI
displayName: Migrate from Swagger to OpenAPI
description: Migrate from Swagger to OpenAPI.
tags:
- swagger
- openapi
recipeList:
# https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Annotations
# https://springdoc.org/#migrating-from-springfox
- org.openrewrite.java.ChangeType:
oldFullyQualifiedTypeName: io.swagger.annotations.Tag
newFullyQualifiedTypeName: io.swagger.v3.oas.annotations.tags.Tag
- org.openrewrite.openapi.swagger.MigrateApiOperationToOperation
- org.openrewrite.openapi.swagger.MigrateApiResponsesToApiResponses
- org.openrewrite.openapi.swagger.MigrateApiImplicitParamsToParameters
- org.openrewrite.openapi.swagger.MigrateApiToTag
- org.openrewrite.openapi.swagger.MigrateApiParamToParameter
- org.openrewrite.openapi.swagger.MigrateApiModelPropertyToSchema
- org.openrewrite.java.ChangeType:
oldFullyQualifiedTypeName: io.swagger.annotations.ApiModel
newFullyQualifiedTypeName: io.swagger.v3.oas.annotations.media.Schema

# todo add swagger-core to common-dependencies

---
type: specs.openrewrite.org/v1beta/recipe
name: org.openrewrite.openapi.swagger.MigrateApiOperationToOperation
displayName: Migrate from @ApiOperation to @Operation
description: Converts the @ApiOperation annotation to @Operation and converts the directly mappable attributes
and removes the others.
tags:
- swagger
- openapi
recipeList:
- org.openrewrite.java.ChangeType:
oldFullyQualifiedTypeName: io.swagger.annotations.ApiOperation
newFullyQualifiedTypeName: io.swagger.v3.oas.annotations.Operation
- org.openrewrite.java.ChangeAnnotationAttributeName:
annotationType: io.swagger.v3.oas.annotations.Operation
oldAttributeName: "notes"
newAttributeName: "description"
- org.openrewrite.java.ChangeAnnotationAttributeName:
annotationType: io.swagger.v3.oas.annotations.Operation
oldAttributeName: "value"
newAttributeName: "summary"
- org.openrewrite.java.RemoveAnnotationAttribute:
annotationType: io.swagger.v3.oas.annotations.Operation
attributeName: response
- org.openrewrite.java.RemoveAnnotationAttribute:
annotationType: io.swagger.v3.oas.annotations.Operation
attributeName: consumes
- org.openrewrite.java.RemoveAnnotationAttribute:
annotationType: io.swagger.v3.oas.annotations.Operation
attributeName: produces

---
type: specs.openrewrite.org/v1beta/recipe
name: org.openrewrite.openapi.swagger.MigrateApiResponsesToApiResponses
displayName: Migrate from @ApiResponses to @ApiResponses
description: Changes the namespace of the @ApiResponses and @ApiResponse annotations and converts its attributes
(ex. code -> responseCode, message -> description).
tags:
- swagger
- openapi
recipeList:
- org.openrewrite.java.ChangeType:
oldFullyQualifiedTypeName: io.swagger.annotations.ApiResponses
newFullyQualifiedTypeName: io.swagger.v3.oas.annotations.responses.ApiResponses
- org.openrewrite.java.ChangeType:
oldFullyQualifiedTypeName: io.swagger.annotations.ApiResponse
newFullyQualifiedTypeName: io.swagger.v3.oas.annotations.responses.ApiResponse
- org.openrewrite.java.ChangeAnnotationAttributeName:
annotationType: io.swagger.v3.oas.annotations.responses.ApiResponse
oldAttributeName: "code"
newAttributeName: "responseCode"
- org.openrewrite.java.ChangeAnnotationAttributeName:
annotationType: io.swagger.v3.oas.annotations.responses.ApiResponse
oldAttributeName: "message"
newAttributeName: "description"
- org.openrewrite.openapi.swagger.ConvertApiResponseCodesToStrings

---
type: specs.openrewrite.org/v1beta/recipe
name: org.openrewrite.openapi.swagger.MigrateApiImplicitParamsToParameters
displayName: Migrate from @ApiImplicitParams to @Parameters
description: Converts @ApiImplicitParams to @Parameters and the @ApiImplicitParam annotation to @Parameter and converts
the directly mappable attributes and removes the others.
tags:
- swagger
- openapi
recipeList:
- org.openrewrite.java.ChangeType:
oldFullyQualifiedTypeName: io.swagger.annotations.ApiImplicitParams
newFullyQualifiedTypeName: io.swagger.v3.oas.annotations.Parameters
- org.openrewrite.java.ChangeType:
oldFullyQualifiedTypeName: io.swagger.annotations.ApiImplicitParam
newFullyQualifiedTypeName: io.swagger.v3.oas.annotations.Parameter
- org.openrewrite.java.ChangeAnnotationAttributeName:
annotationType: io.swagger.v3.oas.annotations.Parameter
oldAttributeName: "value"
newAttributeName: "description"
- org.openrewrite.java.RemoveAnnotationAttribute:
annotationType: io.swagger.v3.oas.annotations.Parameter
attributeName: dataType
- org.openrewrite.java.RemoveAnnotationAttribute:
annotationType: io.swagger.v3.oas.annotations.Parameter
attributeName: paramType
- org.openrewrite.java.RemoveAnnotationAttribute:
annotationType: io.swagger.v3.oas.annotations.Parameter
attributeName: allowMultiple

---
type: specs.openrewrite.org/v1beta/recipe
name: org.openrewrite.openapi.swagger.MigrateApiToTag
displayName: Migrate from @Api to @Tag
description: Converts @Api to @Tag annotation and converts the directly mappable attributes and removes the others.
tags:
- swagger
- openapi
recipeList:
- org.openrewrite.java.ChangeAnnotationAttributeName:
annotationType: io.swagger.annotations.Api
oldAttributeName: "value"
newAttributeName: "name"
- org.openrewrite.java.ChangeType:
oldFullyQualifiedTypeName: io.swagger.annotations.Api
newFullyQualifiedTypeName: io.swagger.v3.oas.annotations.tags.Tag

---
type: specs.openrewrite.org/v1beta/recipe
name: org.openrewrite.openapi.swagger.MigrateApiParamToParameter
displayName: Migrate from @ApiParam to @Parameter
description: Converts the @ApiParam annotation to @Parameter and converts the directly mappable attributes.
tags:
- swagger
- openapi
recipeList:
- org.openrewrite.java.ChangeType:
oldFullyQualifiedTypeName: io.swagger.annotations.ApiParam
newFullyQualifiedTypeName: io.swagger.v3.oas.annotations.Parameter
- org.openrewrite.java.ChangeAnnotationAttributeName:
annotationType: io.swagger.v3.oas.annotations.Parameter
oldAttributeName: "value"
newAttributeName: "description"

---
type: specs.openrewrite.org/v1beta/recipe
name: org.openrewrite.openapi.swagger.MigrateApiModelPropertyToSchema
displayName: Migrate from @ApiModelProperty to @Schema
description: Converts the @ApiModelProperty annotation to @Schema and converts the "value" attribute to "description".
tags:
- swagger
- openapi
recipeList:
- org.openrewrite.java.ChangeType:
oldFullyQualifiedTypeName: io.swagger.annotations.ApiModelProperty
newFullyQualifiedTypeName: io.swagger.v3.oas.annotations.media.Schema
- org.openrewrite.java.ChangeAnnotationAttributeName:
annotationType: io.swagger.v3.oas.annotations.media.Schema
oldAttributeName: "value"
newAttributeName: "description"
Loading

0 comments on commit eed4590

Please sign in to comment.