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

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

Open
mark1900 opened this issue Dec 8, 2015 · 2 comments

Comments

@mark1900
Copy link

mark1900 commented Dec 8, 2015

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;
    }

}
@who
Copy link
Contributor

who commented Apr 27, 2016

I am hitting this same issue.

Using @JsonTypeInfo and @JsonSubTypes in a parent+child @ApiModel, there's no good way to set the discriminator field in a swagger-codegen'd client.

@wing328 wing328 modified the milestones: Future, v2.3.0 Jul 7, 2016
@wing328 wing328 modified the milestones: v2.2.1, v2.2.2 Aug 8, 2016
peder280370 added a commit to maritime-web/Enav-Services that referenced this issue Oct 20, 2016

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
…d classes for fetching NW-NM messages.

Currently Swagger does not properly support polymorphism, see: swagger-api/swagger-codegen#1686
@wing328 wing328 modified the milestones: v2.2.3, v2.2.2 Feb 15, 2017
@wing328 wing328 modified the milestones: v2.2.3, v2.3.0 Jul 16, 2017
@wing328 wing328 modified the milestones: v2.3.0, v2.4.0 Dec 15, 2017
@delenius
Copy link
Contributor

delenius commented May 3, 2018

I think you're supposed to leave out the discriminator property, i.e. this part:

@ApiModelProperty(required=true, value = "the discriminator field.")
    private String type;

It will be autogenerated. At least, that seems to work for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants