Skip to content

Java Client Generation Issues with @ApiModel with declared subTypes and discriminator values. #1686

@mark1900

Description

@mark1900

I am trying to use Swagger to describe my JAX-RS Web Services and have decorated my classes with the relevant Swagger annotations (@apimodel @JsonSubTypes etc). Unfortunately, when I generate the swagger.json (http://localhost:8080/test-application/rest/swagger.json) and use this to create a client jar (Using the swagger editor - http://editor.swagger.io/#/), the generated code doesn't set the discriminator field "type" with the appropriate value. This is unexpected.

For inspiration I used the following:

Is there any good documentation on this feature that goes into more depth than the following?

Swagger Test Client

public class ApiIntegrationTest
{
    @Test
    public void testClient() throws ApiException {

        ApiClient apiclient = new ApiClient();
//        apiclient.setUsername("myUsername");
//        apiclient.setPassword("myPassword");
        EventsApi eventsApi = new EventsApi(apiclient);


        {
            NetworkEventDataDTO eventDataDTO  = new NetworkEventDataDTO ();

            NetworkDto network = new NetworkDto();
            eventDataDTO.setNetwork( network );

            // ISSUE:  This should be hard-coded in the pojo.
            // private final String type = "NetworkEventDataDTO";
            eventDataDTO.setType( "NetworkEventDataDTO" ); //$NON-NLS-1$

            eventsApi.processEvent( eventDataDTO );
        }


    }
}

swagger.json

JAX-RS Web Service

@Path( "/events" )
@Api(value = "/events")
@Stateless
public class EventsLoggerService
{
    private static final Logger LOGGER = LoggerFactory.getLogger( EventsLoggerService.class );


    @POST
    @Path( "/single" )
    @Consumes( MediaType.APPLICATION_JSON )
    @Produces(MediaType.APPLICATION_JSON)
    @ApiOperation(value = "Post a Notification Event", response = String.class)
    @ApiResponses(value = {
        @ApiResponse(code = 200, message = "OK"),
        @ApiResponse(code = 400, message = "Failed to consume Notification Event.")
    })
    public Response processEvent( @ApiParam(required = true, value = "Notification Event to post.") NotificationEventDTO event )
    {
        LOGGER.trace( "Processing NotificationEventDTO: {}", event ); //$NON-NLS-1$
        try
        {

//            System.out.println( event );
            return Response.ok().entity( "OK" ).build(); //$NON-NLS-1$
        }
        catch ( Exception e )
        {
            LOGGER.error( "Unexpected error processing NotificationEventDTO: {}", e.getMessage() ); //$NON-NLS-1$
            return Response.serverError().build();
        }
    }

}

Parent DTO

@JsonAutoDetect
@JsonTypeInfo( use = Id.NAME, include = As.PROPERTY, property = "type", visible = true )
@JsonSubTypes( { @Type( value = SubscriptionEventDataDTO.class, name = "SubscriptionEventDataDTO" ),
        @Type( value = ServiceEventDataDTO.class, name = "ServiceEventDataDTO" ),
        @Type( value = NetworkEventDataDTO.class, name = "NetworkEventDataDTO" ),
        @Type( value = NetworkIdEventDataDTO.class, name = "NetworkIdEventDataDTO" ) } )
@JsonPropertyOrder( { "version" } )
@ApiModel(value = "NotificationEventDTO",
    subTypes = { SubscriptionEventDataDTO.class, ServiceEventDataDTO.class, NetworkEventDataDTO.class, NetworkIdEventDataDTO.class},
    discriminator = "type")
public class NotificationEventDTO implements EventDataDTO
{
    @ApiModelProperty(required=true, value = "the discriminator field.")
    private String type;

    private long version = 1;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    @Override
    @JsonProperty( required = true, value = "version" )
    public long getVersion() {
        return version;
    }

    public void setVersion(long version) {
        this.version = version;
    }
}

Example Child DTO

@ApiModel(value = "NetworkEventDataDTO", parent = NotificationEventDTO.class)
public class NetworkEventDataDTO extends NotificationEventDTO
{
    private NetworkDto network;

    public NetworkEventDataDTO()
    {

    }

    public NetworkEventDataDTO( NetworkDto network )
    {
        this.network = network;

    }

    public NetworkDto getNetwork()
    {
        return network;
    }

    public void setNetwork( NetworkDto network )
    {
        this.network = network;
    }

}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions