Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

isRemovingUnreferencedDefinitions removes $ref used in oneOf. #4812

Open
Xarno opened this issue Dec 17, 2024 · 0 comments
Open

isRemovingUnreferencedDefinitions removes $ref used in oneOf. #4812

Xarno opened this issue Dec 17, 2024 · 0 comments

Comments

@Xarno
Copy link

Xarno commented Dec 17, 2024

Used Version of Swagger-core: 2.2.27

Maybe a followup to: #3303

I created a custom spec filter to split our doc in public / non public api. And had hoped the „isRemovingUnreferencedDefinitions“ removes all references to then filtered $ref.
Sadly it filters also used refs from the oneOf annotation field.

Api Data Classes which use oneOf

    data class ApiSuggestionGroupsResponse(
        @field:Schema(description = "Copy of used filterlist")
        val query: String?,
        val suggestionGroups: List<ApiSuggestionGroup>,
    )

    data class ApiSuggestionGroup(
        var id: String?,
        val name: String?,
        val trackingName: String,
        val maxSuggestions: Int,
        val suggestions: List<ApiSuggestion>,
    )

    @JsonInclude(JsonInclude.Include.NON_NULL)
    data class ApiSuggestion(
        var value: String? = null,
        var title: String? = null,
        var id: String? = null,
        @field:Schema(description = "Included on category Suggestions")
        var textPrefix: String? = null,
        var alias: String? = null,
        var subtitle: String? = null,
        var icon: String? = null,
        @field:Schema(
            description = "Included on StandRegistration, Category and EntityNews” and “Coupon” suggestions", oneOf =
            [ApiSuggestionCategoryAdditionalData::class, ApiSuggestionStandRegistrationAdditionalData::class, ApiSuggestionNewsAdditionalData::class, ApiSuggestionCouponAdditionalData::class]
        )
        var additionalData: ApiSuggestionAdditionalData? = null,
        var markSearchString: Boolean? = null,
    )


    @JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.PROPERTY,
        property = "type"
    )
    sealed class ApiSuggestionAdditionalData

    @JsonTypeName("category")
    data class ApiSuggestionCategoryAdditionalData(
        @field:JsonProperty("isProductType")
        var productType: Boolean,
    ) : ApiSuggestionAdditionalData()

    @JsonTypeName("standRegistration")
    data class ApiSuggestionStandRegistrationAdditionalData(
        var organizationAlias: String?,
        var organizationName: String?,
        var hallAlias: String?,
        var hallName: String?,
        var standAlias: String?,
        var standName: String?,
    ) : ApiSuggestionAdditionalData()

    @JsonTypeName("news")
    data class ApiSuggestionNewsAdditionalData(
        var externalUrl: String,
    ) : ApiSuggestionAdditionalData()

    @JsonTypeName("coupon")
    data class ApiSuggestionCouponAdditionalData(
        var url: String,
    ) : ApiSuggestionAdditionalData()

Custom filter

class CustomPublicOpenAPI31SpecFilter: AbstractSpecFilter() {

    override fun filterOperation(
        operation: Operation,
        api: ApiDescription,
        params: Map<String, List<String>?>?,
        cookies: Map<String, String>?,
        headers: Map<String, List<String>?>?
    ): Optional<Operation> {
        val security = operation.security

        // management
        if(security.find { it.contains("CustomerAccessKey") } != null
            || security.find { it.contains("Cognito Userpool") } != null ) {
            return Optional.empty()
        }

        // client
        if(security.find { it.contains("ConnectionToken_AppDev") } != null
            || security.find { it.contains("ConnectionToken_soTopic") } != null
            || security.find { it.contains("ConnectionToken_sotUser") } != null) {
            return Optional.empty()
        }

        // public
        // no security annotation
        return Optional.of(operation)
    }

    override fun isOpenAPI31Filter(): Boolean {
        return true
    }

    override fun isRemovingUnreferencedDefinitions(): Boolean {
        return true // <- setting it to true filters the oneOf references, although they are needed.
    }
}

Usage which links ApiSuggestionGroupsResponse from above and thus the oneOf attribute of ApiSuggestion.

@Singleton
@Path("/webservice/suggest")
@Tag(name = "SuggestWebservice")
class SuggestWebservice @Inject constructor(
    private val logicFactory: SuggestWebserviceLogicFactory,
) : BaseWebservice() {


    @Operation(
        summary = "🦾 gets suggestions for the requested suggestion groups",
        description = "Each group has a type and an max suggestion count (msc). For type entity the parameter entityType is needed." +
                "Suggestion groups are requested in parallel. No order is guaranteed.",
        requestBody = RequestBody(
            description = "HttpRequest", content = [Content(
                mediaType = MediaType.APPLICATION_FORM_URLENCODED,
                schema = Schema(
                    name = "payload",
                    implementation = SuggestWebserviceApiObjects.ApiSuggestRequest::class
                ),
                examples = [ExampleObject(…
                )]
            )]
        ),
        responses = [
            ApiResponse(
                responseCode = "200", description = "successful operation since api version 52",
                content = [Content(
                    mediaType = MediaType.APPLICATION_JSON,
                    schema = Schema(implementation = SuggestWebserviceApiObjects.ApiSuggestionGroupsResponse::class),
                )]
            ),
            ApiResponse(responseCode = "400", description = "Missing Parameter Exception")],
    )
    @POST
    @Throws(
        ServletException::class, IOException::class
    )
    public override fun doPost(req: HttpServletRequest, resp: HttpServletResponse) {
        doGet(req, resp)
    }
…
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant