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(schema=@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(implementation=ErrorMessage.class))),
>                                                             @ApiResponse(
>                                                                               
>                       responseCode = "401",
>                                                                               
>                       description = "Invalid authorization",
>                                                                               
>                       content = 
> @Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implementation=ErrorMessage.class))),
>                                                             @ApiResponse(
>                                                                               
>                       responseCode = "500",
>                                                                               
>                       description = "Unexpected Server Error",
>                                                                               
>                       content = 
> @Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implementation=ErrorMessage.class))),
>                                                             @ApiResponse(
>                                                                               
>                       responseCode = "502",
>                                                                               
>                       description = "Bad Gateway",
>                                                                               
>                       content = 
> @Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implementation=ErrorMessage.class))),
>                                                             @ApiResponse(
>                                                                               
>                       responseCode = "503",
>                                                                               
>                       description = "Service unavailable",
>                                                                               
>                       content = 
> @Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implementation=ErrorMessage.class))),
>                                                             @ApiResponse(
>                                                                               
>                       responseCode = "504",
>                                                                               
>                       description = "Gateway Timeout",
>                                                                               
>                       content = 
> @Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implementation=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(schema=@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(implementation=ErrorMessage.class))),
>>                                         @ApiResponse(
>>                                                         responseCode = "401",
>>                                                         description = 
>>"Invalid authorization",
>>                                                         content = 
>>@Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implementation=ErrorMessage.class))),
>>                                         @ApiResponse(
>>                                                         responseCode = "500",
>>                                                         description = 
>>"Unexpected Server Error",
>>                                                         content = 
>>@Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implementation=ErrorMessage.class))),
>>                                         @ApiResponse(
>>                                                         responseCode = "502",
>>                                                         description = "Bad 
>>Gateway",
>>                                                         content = 
>>@Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implementation=ErrorMessage.class))),
>>                                         @ApiResponse(
>>                                                         responseCode = "503",
>>                                                         description = 
>>"Service unavailable",
>>                                                         content = 
>>@Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implementation=ErrorMessage.class))),
>>                                         @ApiResponse(
>>                                                         responseCode = "504",
>>                                                         description = 
>>"Gateway Timeout",
>>                                                         content = 
>>@Content(mediaType=MediaType.APPLICATION_JSON,schema=@Schema(implementation=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.
>  


Reply via email to