V2.2.22 (15/05/2024) is the latest version of io.swagger.core.v3 libraries. I upgrade to this version to make sure I had the latest swagger implementation.
-----Original Message----- From: Andriy Redko <drr...@gmail.com> Sent: donderdag 4 juli 2024 4:44 To: Jean Pierre URKENS <jean-pierre.urk...@devoteam.com>; dev@cxf.apache.org Subject: Re: CXF JAX-RS: working with multipart form-data Hi Jean, Interesting, I was experimenting with different ways to express what you need, but no luck so far, I will try to spend a bit more time on that this week since OAS 3.x does support multipart [1] but we may indeed hit the limitation(s) of this particular Swagger Core version. Thank you. [1] https://swagger.io/docs/specification/describing-request-body/multipart-requests/ Best Regards, Andriy Redko > Hi Andriy, > > I already tried this but it didn't work. E.g. for following API interface > specification: > > /** > * Send a message, using a channel (email, paper mail, > ebox) and delivery method (registered or normal) of your choice. More than > 6 upfiles only supported for PAPER delivery. > * > */ > @POST > @Path("/messages") > @Consumes("multipart/form-data") > @Produces({ "application/json" }) > @Operation( > summary = > "Send a message, using a channel (email, paper mail, ebox) and > delivery method (registered or normal) of your choice. More than 6 > upfiles only supported for PAPER delivery.", > tags = > {"messages" }, > > operationId="createMessage", > > security=@SecurityRequirement(name="BearerAuthentication")) > @ApiResponses({ > > @ApiResponse( > > responseCode = "201", > > description = "Created", > > content = > @Content(mediaType=MediaType.APPLICATION_JSON,array=@ArraySchema(schem > a=@Schema(implementation=SendStatusMessage.class))), > > headers = {@Header( > > name="X-Magda-Exceptions", > > required=false, > > description="Only used in the context of EBOX delivery and if there > was a problem with the consent of the receiver's ebox.", > > schema=@Schema(implementation=MagdaExceptionList.class)) > > }), > > @ApiResponse( > > responseCode = "400", > > description = "Invalid data supplied", > > content = > @Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implement > ation=ErrorMessage.class))), > > @ApiResponse( > > responseCode = "401", > > description = "Invalid authorization", > > content = > @Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implement > ation=ErrorMessage.class))), > > @ApiResponse( > > responseCode = "500", > > description = "Unexpected Server Error", > > content = > @Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implement > ation=ErrorMessage.class))), > > @ApiResponse( > > responseCode = "502", > > description = "Bad Gateway", > > content = > @Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implement > ation=ErrorMessage.class))), > > @ApiResponse( > > responseCode = "503", > > description = "Service unavailable", > > content = > @Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implement > ation=ErrorMessage.class))), > > @ApiResponse( > > responseCode = "504", > > description = "Gateway Timeout", > > content = > @Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implement > ation=ErrorMessage.class))) > }) > public Response createMessage( > > @HeaderParam("x-correlation-id") @NotNull @Size(min = 10, max = 36) > @Parameter(description="ID of the transaction. Use this ID for log > tracing and incident handling.") String xCorrelationId, > > @HeaderParam("Idempotency-Key") @Size(min = 10, max = 36) > @Parameter(description="When retrying a failed call, the retry call > should have the same Idempotency Key.") String idempotencyKey, > > @Parameter(required=true,schema = > @Schema(implementation=MessageToSend.class)) @Multipart(value = > "messageToSend", type="application/json", required= true) > MessageToSend messageToSend, > > @Parameter(schema = @Schema(type = "string", format = "binary")) > @Multipart(value = "upfile1", type="application/octet-stream", > required = false) Attachment upfile1Detail, > > @Parameter(schema = @Schema(type = "string", format = "binary")) > @Multipart(value = "upfile2", type="application/octet-stream", > required = false) Attachment upfile2Detail, > > @Parameter(schema = @Schema(type = "string", format = "binary")) > @Multipart(value = "upfile3", type="application/octet-stream", > required = false) Attachment upfile3Detail, > > @Parameter(schema = @Schema(type = "string", format = "binary")) > @Multipart(value = "upfile4", type="application/octet-stream", > required = false) Attachment upfile4Detail, > > @Parameter(schema = @Schema(type = "string", format = "binary")) > @Multipart(value = "upfile5", type="application/octet-stream", > required = false) Attachment upfile5Detail, > > @Parameter(schema = @Schema(type = "string", format = "binary")) > @Multipart(value = "upfile6", type="application/octet-stream", > required = false) Attachment upfile6Detail, > > @Parameter(schema = @Schema(type = "string", format = "binary")) > @Multipart(value = "upfile7", type="application/octet-stream", > required = false) Attachment upfile7Detail, > > @Parameter(schema = @Schema(type = "string", format = "binary")) > @Multipart(value = "upfile8", type="application/octet-stream", > required = false) Attachment upfile8Detail, > > @Parameter(schema = @Schema(type = "string", format = "binary")) > @Multipart(value = "upfile9", type="application/octet-stream", > required = false) Attachment upfile9Detail, > > @Parameter(schema = @Schema(type = "string", format = "binary")) > @Multipart(value = "upfile10", type="application/octet-stream", > required = false) Attachment upfile10Detail, > > @Parameter(schema = @Schema(type = "string", format = "binary")) > @Multipart(value = "upfile11", type="application/octet-stream", > required = false) Attachment upfile11Detail, > > @Parameter(schema = @Schema(type = "string", format = "binary")) > @Multipart(value = "upfile12", type="application/octet-stream", > required = false) Attachment upfile12Detail, > > @Parameter(schema = @Schema(type = "string", format = "binary")) > @Multipart(value = "upfile13", type="application/octet-stream", > required = false) Attachment upfile13Detail, > > @Parameter(schema = @Schema(type = "string", format = "binary")) > @Multipart(value = "upfile14", type="application/octet-stream", > required = false) Attachment upfile14Detail, > > @Parameter(schema = @Schema(type = "string", format = "binary")) > @Multipart(value = "upfile15", type="application/octet-stream", > required = false) Attachment upfile15Detail, > > @Parameter(schema = @Schema(type = "string", format = "binary")) > @Multipart(value = "upfile16", type="application/octet-stream", > required = false) Attachment upfile16Detail, > > @Parameter(schema = @Schema(type = "string", format = "binary")) > @Multipart(value = "upfile17", type="application/octet-stream", > required = false) Attachment upfile17Detail, > > @Parameter(schema = @Schema(type = "string", format = "binary")) > @Multipart(value = "upfile18", type="application/octet-stream", > required = false) Attachment upfile18Detail, > > @Parameter(schema = @Schema(type = "string", format = "binary")) > @Multipart(value = "upfile19", type="application/octet-stream", > required = false) Attachment upfile19Detail, > > @Parameter(schema = @Schema(type = "string", format = "binary")) > @Multipart(value = "upfile20", type="application/octet-stream", > required = false) Attachment upfile20Detail, > > @Parameter(schema = @Schema(type = "string", format = "binary")) > @Multipart(value = "qrfile", type="application/octet-stream", required > = false) Attachment qrfileDetail); > > I’ve attached the generated openapi specification. It only contains the > ‘messageToSend’ as part of the multipart/form-data requestBody content, > all attachments are ignored. > > Below I’ve listed the libraries I’ve included in the project (cxf v3.5.8 > and swagger v2.2.2). Which of these libraries is acutal responsible for > generating the openapi.json specification from the interface description? > * cxf-rt-rs-service-description-common-openapi:3.5.8 > * cxf-rt-rs-service-description-openapi:3.5.8 > * cxf-rt-rs-service-description-swagger-ui:3.5.8 > * swagger-core:2.2.2 > * swagger-annotations:2.2.2 > * swagger-integration:2.2.2 > * swagger-jaxrs2: 2.2.2 > * swagger-model: 2.2.2 > > Note that I am still on JDK8, so I guess I can’t upgrade to a higher > version (currently our projects use cxf-v3.5.6 and swagger 2.1.13). > > Regards, > > J.P. Urkens > > > > -----Original Message----- > From: Andriy Redko <drr...@gmail.com> > Sent: woensdag 3 juli 2024 5:57 > To: Jean Pierre URKENS <jean-pierre.urk...@devoteam.com>; > dev@cxf.apache.org > Subject: Re: CXF JAX-RS: working with multipart form-data > > Hi Jean Pierre, > I suspect the @Multipart annotation is coming from CXF > (org.apache.cxf.jaxrs.ext.multipart.Multipart), right? If yes, this is not > a part of JAX-RS specification but CXF specific extension. You may need to > add Swagger API annotation to the parameters in question: > > @Parameter(schema = @Schema(type = "string", format = "binary")) > > Hope it helps. > Thank you. > > Best Regards, > Andriy Redko > > Monday, July 1, 2024, 12:09:17 PM, you wrote: > >> Hi all, >> I am having problems to correctly annotate service methods which consumes >> multipart/form-data that contains attachments next to other model >> objects. >> I’ve an openapi specification that contains following requestBody >> definition: >> /messages: >> post: >> tags: >> - "messages" >> summary: "Send a message, using a channel (email, paper mail, ebox) >> and delivery method (registered or normal) of your choice. More than 6 >> upfiles only supported for PAPER delivery." >> operationId: createMessage >> parameters: >> - $ref: '#/components/parameters/CorrelationId' >> - $ref: '#/components/parameters/Idempotency-Key' >> requestBody: >> content: >> multipart/form-data: >> schema: >> type: object >> required: >> - messageToSend >> properties: >> messageToSend: >> $ref: '#/components/schemas/MessageToSend' >> upfile1: >> type: string >> format: binary >> nullable: true >> upfile2: >> type: string >> format: binary >> nullable: true >> upfile3: >> type: string >> format: binary >> nullable: true >> upfile4: >> type: string >> format: binary >> nullable: true >> upfile5: >> type: string >> format: binary >> nullable: true >> upfile6: >> type: string >> format: binary >> nullable: true >> upfile7: >> type: string >> format: binary >> nullable: true >> upfile8: >> type: string >> format: binary >> nullable: true >> upfile9: >> type: string >> format: binary >> nullable: true >> upfile10: >> type: string >> format: binary >> nullable: true >> upfile11: >> type: string >> format: binary >> nullable: true >> upfile12: >> type: string >> format: binary >> nullable: true >> upfile13: >> type: string >> format: binary >> nullable: true >> upfile14: >> type: string >> format: binary >> nullable: true >> upfile15: >> type: string >> format: binary >> nullable: true >> upfile16: >> type: string >> format: binary >> nullable: true >> upfile17: >> type: string >> format: binary >> nullable: true >> upfile18: >> type: string >> format: binary >> nullable: true >> upfile19: >> type: string >> format: binary >> nullable: true >> upfile20: >> type: string >> format: binary >> nullable: true >> qrfile: >> type: string >> format: binary >> nullable: true >> required: true >> When using the openapi-generator-maven-plugin v7.6.0 it generates >> following method signature: >> @POST >> @Path("/messages") >> @Consumes("multipart/form-data") >> @Produces({ "application/json" }) >> @Operation( >> summary = "Send a message, using a channel >>(email, paper mail, ebox) and delivery method (registered or normal) >>of your choice. More than 6 upfiles only supported for PAPER >>delivery.", >> tags = {"messages" }, >> operationId="createMessage", >> >>security=@SecurityRequirement(name="BearerAuthentication"), >> responses= { >> @ApiResponse( >> responseCode >>= "201", >> description = >>"Created", >> content = >>@Content(mediaType=MediaType.APPLICATION_JSON,array=@ArraySchema(schem >>a=@Schema(implementation=SendStatusMessage.class))), >> headers = >>{@Header( >> >>name="X-Magda-Exceptions", >> >>required=false, >> >>description="Only used in the context of EBOX delivery and if there >>was a problem with the consent of the receiver's ebox.", >> >>schema=@Schema(implementation=MagdaExceptionList.class)) >> >>}), >> @ApiResponse( >> responseCode >>= "400", >> description = >>"Invalid data supplied", >> content = >>@Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implement >>ation=ErrorMessage.class))), >> @ApiResponse( >> responseCode >>= "401", >> description = >>"Invalid authorization", >> content = >>@Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implement >>ation=ErrorMessage.class))), >> @ApiResponse( >> responseCode >>= "500", >> description = >>"Unexpected Server Error", >> content = >>@Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implement >>ation=ErrorMessage.class))), >> @ApiResponse( >> responseCode >>= "502", >> description = >>"Bad Gateway", >> content = >>@Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implement >>ation=ErrorMessage.class))), >> @ApiResponse( >> responseCode >>= "503", >> description = >>"Service unavailable", >> content = >>@Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implement >>ation=ErrorMessage.class))), >> @ApiResponse( >> responseCode >>= "504", >> description = >>"Gateway Timeout", >> content = >>@Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implement >>ation=ErrorMessage.class))) >> }) >> public Response createMessage( >> @HeaderParam("x-correlation-id") @NotNull >>@Size(min = 10, max = 36) @Parameter(description="ID of the >>transaction. Use this ID for log tracing and incident handling.") >>String xCorrelationId, >> @HeaderParam("Idempotency-Key") @Size(min = >>10, max = 36) @Parameter(description="When retrying a failed call, the >>retry call should have the same Idempotency Key.") String >>idempotencyKey, >> @Multipart(value = "messageToSend”, required= >>true) MessageToSend messageToSend, >> @Multipart(value = "upfile1", required = >>false) Attachment upfile1Detail, >> @Multipart(value = "upfile2", required = >>false) Attachment upfile2Detail, >> @Multipart(value = "upfile3", required = >>false) Attachment upfile3Detail, >> @Multipart(value = "upfile4", required = >>false) Attachment upfile4Detail, >> @Multipart(value = "upfile5", required = >>false) Attachment upfile5Detail, >> @Multipart(value = "upfile6", required = >>false) Attachment upfile6Detail, >> @Multipart(value = "upfile7", required = >>false) Attachment upfile7Detail, >> @Multipart(value = "upfile8", required = >>false) Attachment upfile8Detail, >> @Multipart(value = "upfile9", required = >>false) Attachment upfile9Detail, >> @Multipart(value = "upfile10", required = >>false) Attachment upfile10Detail, >> @Multipart(value = "upfile11", required = >>false) Attachment upfile11Detail, >> @Multipart(value = "upfile12", required = >>false) Attachment upfile12Detail, >> @Multipart(value = "upfile13", required = >>false) Attachment upfile13Detail, >> @Multipart(value = "upfile14", required = >>false) Attachment upfile14Detail, >> @Multipart(value = "upfile15", required = >>false) Attachment upfile15Detail, >> @Multipart(value = "upfile16", required = >>false) Attachment upfile16Detail, >> @Multipart(value = "upfile17", required = >>false) Attachment upfile17Detail, >> @Multipart(value = "upfile18", required = >>false) Attachment upfile18Detail, >> @Multipart(value = "upfile19", required = >>false) Attachment upfile19Detail, >> @Multipart(value = "upfile20", required = >>false) Attachment upfile20Detail, >> @Multipart(value = "qrfile", required = >>false) Attachment qrfileDetail); If I now generate the swagger from this >>code (I modified the annotations in the generated code for using OAS v3 >>annotations through swagger-jaxrs2 v2.1.13 and I am using cxf-v3.5.6 >>having swagger-ui v4.18.2 generate the user interface) none of the upload >>files appears as request parameter, only the messageToSend is shown. >> Is the above signature for the method createMessage(...) incorrect? >> If I look at the generated openapi.json all the Attachment upFiles are >> missing from the specification? So is it a problem/short-coming(?) of the >> used software libraries, which then: >> · cxf-rt-rs-service-description-common-openapi v3.5.6 -> >>this library references swagger-jaxrs2 v2.1.13 · swagger-jaxrs2 >>v2.1.13 -> can I upgradethis to >>e.g. swagger-jaxrs2 v2.2.22 (latest) while retaining cxf v3.5.6? >> · ...another? > >> Regards, >> J.P. >