Closed hcrocker closed 11 years ago
OK that's not right. If you can, set com.wordnik=DEBUG in your logger and post what you see? What does com.servicemesh.model.Employee
look like? Maybe that class is failing to introspect?
I don't believe the reader is smart enough to link the response (void) to the produces
field. I'm guessing something else is going on.
Tony,
I enabled debugging in the swagger-maven plugin (1.1.0) as well as the maven compiler. I did not see any interesting output. Is that how you want debugging enabled? I also added a logger (log4j) to my annotated resource class but no output was generated.
I have attached my schema, the generated class, the annotated resource, and the JSON output for your review. If I use 1.2.5 and ApiProperty (vs ApiModelProperty) this works.
We are looking to use the product but since the annotations are changing in the next release we are trying to use 1.3 to avoid rework later.
Thanks.
Henry.
On Fri, Jul 12, 2013 at 12:07 AM, Tony Tam notifications@github.com wrote:
OK that's not right. If you can, set com.wordnik=DEBUG in your logger and post what you see? What does com.servicemesh.model.Employee look like? Maybe that class is failing to introspect?
I don't believe the reader is smart enough to link the response (void) to the produces field. I'm guessing something else is going on.
— Reply to this email directly or view it on GitHubhttps://github.com/wordnik/swagger-core/issues/252#issuecomment-20858712 .
Hi Henry, when running inside maven, you should be able to turn on debugging in src/main/resources/logback.xml. The files you mentioned above didn't come through in the ticket.
Sorry...new to Git.
I do not see a way to attach files so I will include them inline. My apologies if this is wrong.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.servicemesh.com/model" elementFormDefault="qualified"
xmlns:tns="http://www.servicemesh.com/model"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.1"
xmlns:annox="http://annox.dev.java.net" jaxb:extensionBindingPrefixes="annox"
xmlns:sw="http://annox.dev.java.net/com.wordnik.swagger.annotations"
xmlns:jl="http://annox.dev.java.net/java.lang"
xmlns:jxml="http://annox.dev.java.net/javax.xml.bind.annotation"
xmlns:sm="http://annox.dev.java.net/com.servicemesh.poc.annotation">
<xs:complexType name="employee">
<xs:annotation>
<xs:appinfo>
<annox:annotate target="class">
<jxml:XmlRootElement>
<jxml:name>Employee</jxml:name>
</jxml:XmlRootElement>
<sw:ApiModel value="Employee class."
description="More on the Employee class."
discriminator="employee" />
</annox:annotate>
</xs:appinfo>
</xs:annotation>
<xs:complexContent>
<xs:extension base="tns:person" >
<xs:sequence>
<xs:element name="companyId" type="xs:string" >
<xs:annotation>
<xs:appinfo>
<annox:annotate target="field">
<sw:ApiModelProperty value="Company issued identification number."
notes="This value is found on the front of the employee badge."
dataType="string"
required="true"
access="POST: required; PUT: ignored;" />
</annox:annotate>
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="managerId" type="xs:string" minOccurs="0">
<xs:annotation>
<xs:appinfo>
<annox:annotate target="field">
<sw:ApiModelProperty value="Identification number of employee manager."
notes="This value is found on the front of the manager badge."
dataType="string"
required="false"
access="POST: optional; PUT: optional;" />
</annox:annotate>
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="age" type="tns:ageRange">
<xs:annotation>
<xs:appinfo>
<annox:annotate target="field">
<sw:ApiModelProperty value="Age of employee."
notes="This value is found on the front of the employee badge."
dataType="string"
allowableValues="[25-68]"
required="true"
access="POST: optional; PUT: optional;" />
</annox:annotate>
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="classification" type="tns:employeeClassification" default="Regular">
<xs:annotation>
<xs:appinfo>
<annox:annotate target="field">
<sw:ApiModelProperty value="Employee classification type."
notes="Employment type."
dataType="string"
allowableValues="[25-68]"
required="true"
access="POST: optional; PUT: optional;" />
</annox:annotate>
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="person">
<xs:annotation>
<xs:appinfo>
<annox:annotate target="class">
<jxml:XmlRootElement>
<jxml:name>Person</jxml:name>
</jxml:XmlRootElement>
<sw:ApiModel value="Person class."
description="More on the Person class."
discriminator="person" />
</annox:annotate>
</xs:appinfo>
</xs:annotation>
<xs:sequence>
<xs:element name="firstName" type="xs:string" >
<xs:annotation>
<xs:appinfo>
<annox:annotate target="field">
<sw:ApiModelProperty value="First name of person."
required="true"
allowableValues="[a-zA-Z]"
notes="The first name would represent the actual first name and not what they are called by."
dataType="string"
access="POST: required; PUT: required;" />
</annox:annotate>
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="lastName" type="xs:string">
<xs:annotation>
<xs:appinfo>
<annox:annotate target="field">
<sw:ApiModelProperty value="Last name of person."
required="true"
allowableValues="[a-zA-Z]"
notes="The is also know as the sir name."
dataType="string"
access="POST: required; PUT: required;" />
</annox:annotate>
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="email" type="xs:string">
<xs:annotation>
<xs:appinfo>
<annox:annotate target="field">
<sw:ApiModelProperty value="Primary email address."
required="true"
allowableValues="[a-zA-Z@_-]"
notes="This should be the company email address."
dataType="string"
access="POST: required; PUT: required;" />
</annox:annotate>
</xs:appinfo>
</xs:annotation>
</xs:element>
<xs:element name="phone" type="xs:string" minOccurs="0">
<xs:annotation>
<xs:appinfo>
<annox:annotate target="field">
<sw:ApiModelProperty value="Company phone number."
required="false"
allowableValues="[0-9()-]"
notes=""
dataType="string"
access="POST: optiona; PUT: optional;" />
</annox:annotate>
</xs:appinfo>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="employeeClassification">
<xs:restriction base="xs:string">
<xs:enumeration value="Regular" />
<xs:enumeration value="Contractor" />
<xs:enumeration value="Temporary" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="ageRange">
<xs:restriction base="xs:integer">
<xs:minInclusive value="25"/>
<xs:maxInclusive value="68"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.6
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2013.07.12 at 07:01:29 AM CDT
//
package com.servicemesh.model;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import com.wordnik.swagger.annotations.ApiModel;
import com.wordnik.swagger.annotations.ApiModelProperty;
import org.jvnet.jaxb2_commons.lang.Equals;
import org.jvnet.jaxb2_commons.lang.EqualsStrategy;
import org.jvnet.jaxb2_commons.lang.HashCode;
import org.jvnet.jaxb2_commons.lang.HashCodeStrategy;
import org.jvnet.jaxb2_commons.lang.JAXBEqualsStrategy;
import org.jvnet.jaxb2_commons.lang.JAXBHashCodeStrategy;
import org.jvnet.jaxb2_commons.lang.JAXBToStringStrategy;
import org.jvnet.jaxb2_commons.lang.ToString;
import org.jvnet.jaxb2_commons.lang.ToStringStrategy;
import org.jvnet.jaxb2_commons.locator.ObjectLocator;
import org.jvnet.jaxb2_commons.locator.util.LocatorUtils;
/**
* <p>Java class for employee complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType name="employee">
* <complexContent>
* <extension base="{http://www.servicemesh.com/model}person">
* <sequence>
* <element name="companyId" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="managerId" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="age" type="{http://www.servicemesh.com/model}ageRange"/>
* <element name="classification" type="{http://www.servicemesh.com/model}employeeClassification"/>
* </sequence>
* </extension>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "employee", propOrder = {
"companyId",
"managerId",
"age",
"classification"
})
@XmlRootElement(name = "Employee")
@ApiModel(description = "More on the Employee class.", discriminator = "employee", value = "Employee class.")
public class Employee
extends Person
implements Equals, HashCode, ToString
{
@XmlElement(required = true)
@ApiModelProperty(dataType = "string", value = "Company issued identification number.", notes = "This value is found on the front of the employee badge.", required = true, access = "POST: required; PUT: ignored;")
protected String companyId;
@ApiModelProperty(dataType = "string", value = "Identification number of employee manager.", notes = "This value is found on the front of the manager badge.", required = false, access = "POST: optional; PUT: optional;")
protected String managerId;
@ApiModelProperty(dataType = "string", allowableValues = "[25-68]", value = "Age of employee.", notes = "This value is found on the front of the employee badge.", required = true, access = "POST: optional; PUT: optional;")
protected int age;
@XmlElement(required = true, defaultValue = "Regular")
@ApiModelProperty(dataType = "string", allowableValues = "[25-68]", value = "Employee classification type.", notes = "Employment type.", required = true, access = "POST: optional; PUT: optional;")
protected EmployeeClassification classification;
/**
* Gets the value of the companyId property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getCompanyId() {
return companyId;
}
/**
* Sets the value of the companyId property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setCompanyId(String value) {
this.companyId = value;
}
/**
* Gets the value of the managerId property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getManagerId() {
return managerId;
}
/**
* Sets the value of the managerId property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setManagerId(String value) {
this.managerId = value;
}
/**
* Gets the value of the age property.
*
*/
public int getAge() {
return age;
}
/**
* Sets the value of the age property.
*
*/
public void setAge(int value) {
this.age = value;
}
/**
* Gets the value of the classification property.
*
* @return
* possible object is
* {@link EmployeeClassification }
*
*/
public EmployeeClassification getClassification() {
return classification;
}
/**
* Sets the value of the classification property.
*
* @param value
* allowed object is
* {@link EmployeeClassification }
*
*/
public void setClassification(EmployeeClassification value) {
this.classification = value;
}
public String toString() {
final ToStringStrategy strategy = JAXBToStringStrategy.INSTANCE;
final StringBuilder buffer = new StringBuilder();
append(null, buffer, strategy);
return buffer.toString();
}
public StringBuilder append(ObjectLocator locator, StringBuilder buffer, ToStringStrategy strategy) {
strategy.appendStart(locator, this, buffer);
appendFields(locator, buffer, strategy);
strategy.appendEnd(locator, this, buffer);
return buffer;
}
public StringBuilder appendFields(ObjectLocator locator, StringBuilder buffer, ToStringStrategy strategy) {
super.appendFields(locator, buffer, strategy);
{
String theCompanyId;
theCompanyId = this.getCompanyId();
strategy.appendField(locator, this, "companyId", buffer, theCompanyId);
}
{
String theManagerId;
theManagerId = this.getManagerId();
strategy.appendField(locator, this, "managerId", buffer, theManagerId);
}
{
int theAge;
theAge = (true?this.getAge(): 0);
strategy.appendField(locator, this, "age", buffer, theAge);
}
{
EmployeeClassification theClassification;
theClassification = this.getClassification();
strategy.appendField(locator, this, "classification", buffer, theClassification);
}
return buffer;
}
public boolean equals(ObjectLocator thisLocator, ObjectLocator thatLocator, Object object, EqualsStrategy strategy) {
if (!(object instanceof Employee)) {
return false;
}
if (this == object) {
return true;
}
if (!super.equals(thisLocator, thatLocator, object, strategy)) {
return false;
}
final Employee that = ((Employee) object);
{
String lhsCompanyId;
lhsCompanyId = this.getCompanyId();
String rhsCompanyId;
rhsCompanyId = that.getCompanyId();
if (!strategy.equals(LocatorUtils.property(thisLocator, "companyId", lhsCompanyId), LocatorUtils.property(thatLocator, "companyId", rhsCompanyId), lhsCompanyId, rhsCompanyId)) {
return false;
}
}
{
String lhsManagerId;
lhsManagerId = this.getManagerId();
String rhsManagerId;
rhsManagerId = that.getManagerId();
if (!strategy.equals(LocatorUtils.property(thisLocator, "managerId", lhsManagerId), LocatorUtils.property(thatLocator, "managerId", rhsManagerId), lhsManagerId, rhsManagerId)) {
return false;
}
}
{
int lhsAge;
lhsAge = (true?this.getAge(): 0);
int rhsAge;
rhsAge = (true?that.getAge(): 0);
if (!strategy.equals(LocatorUtils.property(thisLocator, "age", lhsAge), LocatorUtils.property(thatLocator, "age", rhsAge), lhsAge, rhsAge)) {
return false;
}
}
{
EmployeeClassification lhsClassification;
lhsClassification = this.getClassification();
EmployeeClassification rhsClassification;
rhsClassification = that.getClassification();
if (!strategy.equals(LocatorUtils.property(thisLocator, "classification", lhsClassification), LocatorUtils.property(thatLocator, "classification", rhsClassification), lhsClassification, rhsClassification)) {
return false;
}
}
return true;
}
public boolean equals(Object object) {
final EqualsStrategy strategy = JAXBEqualsStrategy.INSTANCE;
return equals(null, null, object, strategy);
}
public int hashCode(ObjectLocator locator, HashCodeStrategy strategy) {
int currentHashCode = super.hashCode(locator, strategy);
{
String theCompanyId;
theCompanyId = this.getCompanyId();
currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "companyId", theCompanyId), currentHashCode, theCompanyId);
}
{
String theManagerId;
theManagerId = this.getManagerId();
currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "managerId", theManagerId), currentHashCode, theManagerId);
}
{
int theAge;
theAge = (true?this.getAge(): 0);
currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "age", theAge), currentHashCode, theAge);
}
{
EmployeeClassification theClassification;
theClassification = this.getClassification();
currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "classification", theClassification), currentHashCode, theClassification);
}
return currentHashCode;
}
public int hashCode() {
final HashCodeStrategy strategy = JAXBHashCodeStrategy.INSTANCE;
return this.hashCode(null, strategy);
}
}
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.6
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2013.07.12 at 07:01:29 AM CDT
//
package com.servicemesh.model;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlType;
import com.wordnik.swagger.annotations.ApiModel;
import com.wordnik.swagger.annotations.ApiModelProperty;
import org.jvnet.jaxb2_commons.lang.Equals;
import org.jvnet.jaxb2_commons.lang.EqualsStrategy;
import org.jvnet.jaxb2_commons.lang.HashCode;
import org.jvnet.jaxb2_commons.lang.HashCodeStrategy;
import org.jvnet.jaxb2_commons.lang.JAXBEqualsStrategy;
import org.jvnet.jaxb2_commons.lang.JAXBHashCodeStrategy;
import org.jvnet.jaxb2_commons.lang.JAXBToStringStrategy;
import org.jvnet.jaxb2_commons.lang.ToString;
import org.jvnet.jaxb2_commons.lang.ToStringStrategy;
import org.jvnet.jaxb2_commons.locator.ObjectLocator;
import org.jvnet.jaxb2_commons.locator.util.LocatorUtils;
/**
* <p>Java class for person complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType name="person">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="firstName" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="lastName" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="email" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="phone" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "person", propOrder = {
"firstName",
"lastName",
"email",
"phone"
})
@XmlSeeAlso({
Employee.class
})
@XmlRootElement(name = "Person")
@ApiModel(description = "More on the Person class.", discriminator = "person", value = "Person class.")
public class Person
implements Equals, HashCode, ToString
{
@XmlElement(required = true)
@ApiModelProperty(dataType = "string", allowableValues = "[a-zA-Z]", value = "First name of person.", notes = "The first name would represent the actual first name and not what they are called by.", required = true, access = "POST: required; PUT: required;")
protected String firstName;
@XmlElement(required = true)
@ApiModelProperty(dataType = "string", allowableValues = "[a-zA-Z]", value = "Last name of person.", notes = "The is also know as the sir name.", required = true, access = "POST: required; PUT: required;")
protected String lastName;
@XmlElement(required = true)
@ApiModelProperty(dataType = "string", allowableValues = "[a-zA-Z@_-]", value = "Primary email address.", notes = "This should be the company email address.", required = true, access = "POST: required; PUT: required;")
protected String email;
@ApiModelProperty(dataType = "string", allowableValues = "[0-9()-]", value = "Company phone number.", required = false, access = "POST: optiona; PUT: optional;")
protected String phone;
/**
* Gets the value of the firstName property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getFirstName() {
return firstName;
}
/**
* Sets the value of the firstName property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setFirstName(String value) {
this.firstName = value;
}
/**
* Gets the value of the lastName property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getLastName() {
return lastName;
}
/**
* Sets the value of the lastName property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setLastName(String value) {
this.lastName = value;
}
/**
* Gets the value of the email property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getEmail() {
return email;
}
/**
* Sets the value of the email property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setEmail(String value) {
this.email = value;
}
/**
* Gets the value of the phone property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getPhone() {
return phone;
}
/**
* Sets the value of the phone property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setPhone(String value) {
this.phone = value;
}
public String toString() {
final ToStringStrategy strategy = JAXBToStringStrategy.INSTANCE;
final StringBuilder buffer = new StringBuilder();
append(null, buffer, strategy);
return buffer.toString();
}
public StringBuilder append(ObjectLocator locator, StringBuilder buffer, ToStringStrategy strategy) {
strategy.appendStart(locator, this, buffer);
appendFields(locator, buffer, strategy);
strategy.appendEnd(locator, this, buffer);
return buffer;
}
public StringBuilder appendFields(ObjectLocator locator, StringBuilder buffer, ToStringStrategy strategy) {
{
String theFirstName;
theFirstName = this.getFirstName();
strategy.appendField(locator, this, "firstName", buffer, theFirstName);
}
{
String theLastName;
theLastName = this.getLastName();
strategy.appendField(locator, this, "lastName", buffer, theLastName);
}
{
String theEmail;
theEmail = this.getEmail();
strategy.appendField(locator, this, "email", buffer, theEmail);
}
{
String thePhone;
thePhone = this.getPhone();
strategy.appendField(locator, this, "phone", buffer, thePhone);
}
return buffer;
}
public boolean equals(ObjectLocator thisLocator, ObjectLocator thatLocator, Object object, EqualsStrategy strategy) {
if (!(object instanceof Person)) {
return false;
}
if (this == object) {
return true;
}
final Person that = ((Person) object);
{
String lhsFirstName;
lhsFirstName = this.getFirstName();
String rhsFirstName;
rhsFirstName = that.getFirstName();
if (!strategy.equals(LocatorUtils.property(thisLocator, "firstName", lhsFirstName), LocatorUtils.property(thatLocator, "firstName", rhsFirstName), lhsFirstName, rhsFirstName)) {
return false;
}
}
{
String lhsLastName;
lhsLastName = this.getLastName();
String rhsLastName;
rhsLastName = that.getLastName();
if (!strategy.equals(LocatorUtils.property(thisLocator, "lastName", lhsLastName), LocatorUtils.property(thatLocator, "lastName", rhsLastName), lhsLastName, rhsLastName)) {
return false;
}
}
{
String lhsEmail;
lhsEmail = this.getEmail();
String rhsEmail;
rhsEmail = that.getEmail();
if (!strategy.equals(LocatorUtils.property(thisLocator, "email", lhsEmail), LocatorUtils.property(thatLocator, "email", rhsEmail), lhsEmail, rhsEmail)) {
return false;
}
}
{
String lhsPhone;
lhsPhone = this.getPhone();
String rhsPhone;
rhsPhone = that.getPhone();
if (!strategy.equals(LocatorUtils.property(thisLocator, "phone", lhsPhone), LocatorUtils.property(thatLocator, "phone", rhsPhone), lhsPhone, rhsPhone)) {
return false;
}
}
return true;
}
public boolean equals(Object object) {
final EqualsStrategy strategy = JAXBEqualsStrategy.INSTANCE;
return equals(null, null, object, strategy);
}
public int hashCode(ObjectLocator locator, HashCodeStrategy strategy) {
int currentHashCode = 1;
{
String theFirstName;
theFirstName = this.getFirstName();
currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "firstName", theFirstName), currentHashCode, theFirstName);
}
{
String theLastName;
theLastName = this.getLastName();
currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "lastName", theLastName), currentHashCode, theLastName);
}
{
String theEmail;
theEmail = this.getEmail();
currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "email", theEmail), currentHashCode, theEmail);
}
{
String thePhone;
thePhone = this.getPhone();
currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "phone", thePhone), currentHashCode, thePhone);
}
return currentHashCode;
}
public int hashCode() {
final HashCodeStrategy strategy = JAXBHashCodeStrategy.INSTANCE;
return this.hashCode(null, strategy);
}
}
package com.servicemesh.poc.resources;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import org.apache.log4j.Logger;
import com.servicemesh.model.Employee;
import com.servicemesh.storage.EmployeeTable;
import com.servicemesh.storage.RecordDoesNotExistException;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;
import com.wordnik.swagger.annotations.ApiResponse;
import com.wordnik.swagger.annotations.ApiResponses;
@Path("/staff/")
@Produces({MediaType.APPLICATION_XML})
@Consumes({MediaType.APPLICATION_XML})
@Api(value = "/staff", description = "Sample Swagger annotated API")
public class Staff {
private static Logger logger = Logger.getLogger(Staff.class);
@Context UriInfo uriInfo;
@Context Request request;
@Path("/size")
@GET
@Produces(MediaType.TEXT_HTML)
@ApiOperation(httpMethod = "GET",
produces = "text/html",
value = "Show current records in database",
notes = "The database starts with four records",
response = java.lang.String.class)
public Response getRowCount() {
return (Response.ok("<p>There are " + EmployeeTable.rowCount() + " employees currently defined in the database.<p>").build());
}
@Path("/{id}")
@GET
@ApiOperation(httpMethod = "GET",
produces = MediaType.APPLICATION_XML,
value = "Get employee using company ID value",
notes = "The ID value is on the badge",
response = com.servicemesh.model.Employee.class)
@ApiResponses(value = {@ApiResponse(code = 404,
message = "Employee was not found in the database.",
response = java.lang.String.class),
@ApiResponse(code = 200,
message = "Employee record found.",
response = com.servicemesh.model.Employee.class)})
public Response getEmployee(@ApiParam(value = "Company ID of the employee.",
allowableValues = "Character String",
required = true) @PathParam("id") String id) {
Response resp = null;
try {
Employee e = EmployeeTable.get(id);
if (e != null) {
resp = Response.ok(e).build();
}
else {
resp = Response.ok(new Employee()).build();
}
}
catch (RecordDoesNotExistException e) {
resp = Response.ok(new Employee()).build();
}
catch (Throwable t) {
resp = Response.noContent().build();
resp = Response.status(500).build();
}
return resp;
}
@GET
@ApiOperation(httpMethod = "GET",
produces = MediaType.APPLICATION_XML,
value = "Get a list of employees given a name",
notes = "The first and last names are searched for a match. The complete name must match.",
response = com.servicemesh.model.Employee.class)
public Employee[] getEmployeeByName(@ApiParam(value = "First or last name of employee.",
allowableValues = "Character String",
required = true) @QueryParam("name") String name) {
return (EmployeeTable.findByName(name));
}
@Path("/{id}")
@POST
@ApiOperation(httpMethod = "POST",
consumes = MediaType.APPLICATION_XML,
value = "Add a new employee to the database",
notes = "The ID is provided so the proper URL can be returned.")
@ApiResponses(value = {@ApiResponse(code = 404,
message = "Failure because the employee already exists.",
response = java.lang.String.class),
@ApiResponse(code = 201,
message = "Employee successfully added.",
response = java.lang.String.class)})
public Response addEmployee(Employee e) {
Response resp;
try {
if (EmployeeTable.add(e)) {
resp = Response.created(uriInfo.getAbsolutePath()).build();
resp = Response.status(201).build();
}
else {
resp = Response.noContent().build();
resp = Response.status(404).build();
}
}
catch (Throwable t) {
resp = Response.status(404).build();
}
return resp;
}
@Path("/{id}")
@DELETE
@ApiOperation(httpMethod = "DELETE",
consumes = MediaType.APPLICATION_XML,
value = "Remove an employee from the database.",
notes = "If the employee does not exist it will not cause a problem. The deleted employee record is returned.",
response = com.servicemesh.model.Employee.class)
@ApiResponses(value = {@ApiResponse(code = 404,
message = "The employee failed to be removed from the database.",
response = java.lang.String.class),
@ApiResponse(code = 200,
message = "The employee was successfully removed.",
response = com.servicemesh.model.Employee.class)})
public Response deleteEmployee(@ApiParam(value = "Company ID of the employee.",
allowableValues = "Character String",
required = true) @PathParam("id") String id) {
Response resp;
try {
Employee deletedEmp = EmployeeTable.delete(id);
if (deletedEmp != null) {
resp = Response.ok(deletedEmp, MediaType.APPLICATION_XML).build();
resp = Response.status(200).build();
}
else {
resp = Response.noContent().build();
resp = Response.status(404).build();
}
}
catch (Throwable t) {
resp = Response.status(404).build();
}
return resp;
}
}
{
"apiVersion" : "v1",
"swaggerVersion" : "1.1",
"basePath" : "http://localhost:8080/smapidocs",
"apis" : [ {
"path" : "/staff",
"description" : ""
} ]
}
{
"apiVersion" : "v1",
"swaggerVersion" : "1.1",
"basePath" : "http://localhost:8080/smapidocs",
"resourcePath" : "/staff",
"apis" : [ {
"path" : "/staff/size",
"description" : "Sample Swagger annotated API",
"operations" : [ {
"httpMethod" : "GET",
"summary" : "Show current records in database",
"notes" : "The database starts with four records",
"responseClass" : "void",
"nickname" : "getRowCount"
} ]
}, {
"path" : "/staff/{id}",
"description" : "Sample Swagger annotated API",
"operations" : [ {
"httpMethod" : "GET",
"summary" : "Get employee using company ID value",
"notes" : "The ID value is on the badge",
"responseClass" : "void",
"nickname" : "getEmployee",
"parameters" : [ {
"name" : "id",
"description" : "Company ID of the employee.",
"paramType" : "path",
"allowableValues" : {
"valueType" : "LIST",
"values" : [ "Character String" ],
"valueType" : "LIST"
},
"required" : true,
"allowMultiple" : false,
"dataType" : "string"
} ]
}, {
"httpMethod" : "POST",
"summary" : "Add a new employee to the database",
"notes" : "The ID is provided so the proper URL can be returned.",
"responseClass" : "void",
"nickname" : "addEmployee"
}, {
"httpMethod" : "DELETE",
"summary" : "Remove an employee from the database.",
"notes" : "If the employee does not exist it will not cause a problem. The deleted employee record is returned.",
"responseClass" : "void",
"nickname" : "deleteEmployee",
"parameters" : [ {
"name" : "id",
"description" : "Company ID of the employee.",
"paramType" : "path",
"allowableValues" : {
"valueType" : "LIST",
"values" : [ "Character String" ],
"valueType" : "LIST"
},
"required" : true,
"allowMultiple" : false,
"dataType" : "string"
} ]
} ]
}, {
"path" : "/staff",
"description" : "Sample Swagger annotated API",
"operations" : [ {
"httpMethod" : "GET",
"summary" : "Get a list of employees given a name",
"notes" : "The first and last names are searched for a match. The complete name must match.",
"responseClass" : "void",
"nickname" : "getEmployeeByName",
"parameters" : [ {
"name" : "name",
"description" : "First or last name of employee.",
"paramType" : "query",
"allowableValues" : {
"valueType" : "LIST",
"values" : [ "Character String" ],
"valueType" : "LIST"
},
"required" : true,
"allowMultiple" : false,
"dataType" : "string"
} ]
} ]
} ]
}
Clue:
I switched back to 1.2.5 and added the ApiParamImplicit annotation and the build completed. The JSON file was created but the responseClass was "void" and there was no models section. I removed the annotation and it worked fine. This implies that some annotation I am using in 1.3.0 is causing a problem but not throwing an exception.
Does the api version need to be changed in the web.xml file? It is set to 1.0.0.
I'll get to this in the next day or so. You shouldn't have to set the api version to anything specific for swagger to work.
OK well, there is good news. I didn't have all the dependencies (EmployeeClassification, etc) and didn't pull in all the auto-generated JAXB stuff (Equals, ToString, HashCode). Removing that stuff and adding the /staff
resource into our standard java-jaxrs sample works exactly as expected.
That said, there could be one of two things happening.
1) The injection of the auto-generated bean properties is causing a problem with the swagger model introspector 2) You have some other environmental issue in your project.
I will look at (1), as that should not cause a problem for you. For (2) I propose you look at the sample app and see what is different in your setup. If you send an email address, I can send you the modified project that I just verified.
Hi, checking in, are we clear on this issue?
Hello Tony,
We backed off of 1.3.0 and went back to 1.2.5 for our PoC project.
Thanks.
Henry.
On Thu, Jul 18, 2013 at 10:31 PM, Tony Tam notifications@github.com wrote:
Hi, checking in, are we clear on this issue?
— Reply to this email directly or view it on GitHubhttps://github.com/wordnik/swagger-core/issues/252#issuecomment-21229684 .
OK, if you have a chance to help figure out why that issue came up, it'd be appreciated so I can make sure whatever config/code bug there is can be addressed.
I set the produces and response attribute for the ApiOperation annotation but the values are not translated into the JSON file. The response shows as "responseClass" : "void" and the "produces" item/value does not show up.
The model is annotated with the new @ApiModelProperty as well as the @ApiModel property.
No model section appears in the JSON file. I assume that is because all my responseClass values are "void".
@ApiOperation(httpMethod = "GET", produces = MediaType.APPLICATION_XML, value = "Get employee using company ID value", notes = "The ID value is on the badge", response = com.servicemesh.model.Employee.class)