diff --git a/.DS_Store b/.DS_Store index 57608bd..bb5a37b 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component index c37070b..aa2982b 100644 --- a/.settings/org.eclipse.wst.common.component +++ b/.settings/org.eclipse.wst.common.component @@ -1,25 +1,70 @@ +<<<<<<< HEAD +======= + + + + + + +>>>>>>> refs/heads/EnunciateIntegration +<<<<<<< HEAD +======= + + + + + + +>>>>>>> refs/heads/EnunciateIntegration +<<<<<<< HEAD +======= + + + + + + +>>>>>>> refs/heads/EnunciateIntegration +<<<<<<< HEAD +======= + + + + + + +>>>>>>> refs/heads/EnunciateIntegration +<<<<<<< HEAD +======= + + + + + + +>>>>>>> refs/heads/EnunciateIntegration @@ -42,22 +87,58 @@ uses +<<<<<<< HEAD +======= + + + + + + +>>>>>>> refs/heads/EnunciateIntegration +<<<<<<< HEAD +======= + + + + + + +>>>>>>> refs/heads/EnunciateIntegration +<<<<<<< HEAD +======= + + + + + + +>>>>>>> refs/heads/EnunciateIntegration +<<<<<<< HEAD +======= + + + + + + +>>>>>>> refs/heads/EnunciateIntegration diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d37292..45ffb5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## [v2.5.0-SNAPSHOT] - 2022-04-06 + +- enunciate + ## [v2.4.0] - 2021-04-30 - Feature #21179 porting to storagehub messages diff --git a/enunciate.xml b/enunciate.xml new file mode 100644 index 0000000..75b414a --- /dev/null +++ b/enunciate.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index d510da3..310f1e7 100644 --- a/pom.xml +++ b/pom.xml @@ -12,23 +12,22 @@ org.gcube.portal social-networking-library-ws war - 2.4.0 + 2.5.0-SNAPSHOT social-networking-library-ws Rest interface for the social networking library. 1.8 - 1.5.13 - ${project.basedir}/distro + 2.14.0 ${project.build.directory}/${project.build.finalName} - distro + 2.14.0 UTF-8 UTF-8 - scm:git:https://code-repo.d4science.org/gCubeSystem/social-networking-library-ws.git - scm:git:https://code-repo.d4science.org/gCubeSystem/social-networking-library-ws.git - https://code-repo.d4science.org/gCubeSystem/social-networking-library-ws + scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git + scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git + https://code-repo.d4science.org/gCubeSystem/${project.artifactId} @@ -36,7 +35,7 @@ org.gcube.distribution gcube-smartgears-bom - 2.0.0 + 2.1.0 pom import @@ -44,6 +43,32 @@ + + + com.webcohesion.enunciate + enunciate-core-annotations + ${enunciate.version} + + + + com.webcohesion.enunciate + enunciate-rt-util + ${enunciate.version} + + + javax.servlet + javax.servlet-api + 3.1.0 + provided + + + + org.geotoolkit + geotk-xml-base + 3.20-geoapi-3.0 + provided + + net.sf.ehcache ehcache @@ -231,18 +256,6 @@ org.glassfish.jersey.ext jersey-bean-validation - - io.swagger - swagger-jersey2-jaxrs - ${version.swagger} - provided - - - jackson-dataformat-yaml - com.fasterxml.jackson.dataformat - - - javax.portlet portlet-api @@ -283,46 +296,64 @@ - ${name} + + + + + + + + + + + + + + + + + + + + - org.apache.maven.plugins - maven-war-plugin + com.webcohesion.enunciate + enunciate-maven-plugin + ${enunciate.version} + - compile + assemble - exploded + assemble - - ${webappDirectory} - + + org.apache.maven.plugins - maven-compiler-plugin - - ${java_version} - ${java_version} - - - - org.apache.maven.plugins - maven-javadoc-plugin - - -Xdoclint:none - -Xdoclint:none - - 3.1.0 + maven-resources-plugin + 2.5 - generate-doc - install + copy-enunciate-docs + process-resources - jar + copy-resources + + target + + + ${project.build.directory}/${project.artifactId}-${project.version}/docs + ${project.build.directory}/docs + true + + + diff --git a/src/main/java/org/gcube/portal/social/networking/swagger/config/Bootstrap.java b/src/main/java/org/gcube/portal/social/networking/swagger/config/Bootstrap.java deleted file mode 100644 index d33e196..0000000 --- a/src/main/java/org/gcube/portal/social/networking/swagger/config/Bootstrap.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.gcube.portal.social.networking.swagger.config; - -import io.swagger.jaxrs.config.BeanConfig; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; - -/** - * Configuration servlet for swagger. - * @author Costantino Perciante at ISTI-CNR - */ -@SuppressWarnings("serial") -public class Bootstrap extends HttpServlet{ - - public static final String GCUBE_TOKEN_IN_QUERY_DEF = "gcube-token-query"; - public static final String GCUBE_TOKEN_IN_HEADER_DEF = "gcube-token-header"; - - @Override - public void init(ServletConfig config) throws ServletException { - - super.init(config); - BeanConfig beanConfig = new BeanConfig(); - beanConfig.setResourcePackage("org.gcube.portal.social.networking.ws"); - beanConfig.setPrettyPrint(true); // print pretty json - beanConfig.setHost("socialnetworking1.d4science.org"); - beanConfig.setBasePath("social-networking-library-ws/rest"); - beanConfig.setScan(true); - - } -} \ No newline at end of file diff --git a/src/main/java/org/gcube/portal/social/networking/swagger/config/SwaggerConstants.java b/src/main/java/org/gcube/portal/social/networking/swagger/config/SwaggerConstants.java deleted file mode 100644 index 63fc6b6..0000000 --- a/src/main/java/org/gcube/portal/social/networking/swagger/config/SwaggerConstants.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.gcube.portal.social.networking.swagger.config; - -/** - * Swagger constants - * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) - */ -public class SwaggerConstants { - - public static final String SECURITY_SCHEMA = "gcube-token"; - public static final String HTTP_SCHEMA = "http"; - public static final String HTTPS_SCHEMA = "https"; - - // VALUES - public static final String USERS = "users"; - public static final String TOKENS = "tokens"; - public static final String POSTS = "posts"; - public static final String PEOPLE = "people"; - public static final String NOTIFICATIONS = "notifications"; - public static final String MESSAGES = "messages"; - public static final String HASHTAGS = "hashtags"; - public static final String FULLTEXT = "full-text-search"; - public static final String COMMENTS = "comments"; - public static final String VRES = "vres"; - -} \ No newline at end of file diff --git a/src/main/java/org/gcube/portal/social/networking/ws/SNLApiConfig.java b/src/main/java/org/gcube/portal/social/networking/ws/SNLApiConfig.java deleted file mode 100644 index 664c935..0000000 --- a/src/main/java/org/gcube/portal/social/networking/ws/SNLApiConfig.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.gcube.portal.social.networking.ws; - -import org.gcube.portal.social.networking.swagger.config.Bootstrap; - -import io.swagger.annotations.ApiKeyAuthDefinition; -import io.swagger.annotations.ApiKeyAuthDefinition.ApiKeyLocation; -import io.swagger.annotations.Contact; -import io.swagger.annotations.Extension; -import io.swagger.annotations.ExtensionProperty; -import io.swagger.annotations.ExternalDocs; -import io.swagger.annotations.Info; -import io.swagger.annotations.SecurityDefinition; -import io.swagger.annotations.SwaggerDefinition; - - -@SwaggerDefinition( - info = @Info( - description = "This is the official documentation of the second version (v. 2.0) of the Social-Networking RESTful interface.", - version = "V 2.0", - title = "Social Networking RESTful Service", - contact = @Contact( - name = "Costantino Perciante", - email ="costantino.perciante@isti.cnr.it" - ), - extensions = { - @Extension(name = "extra-contact", properties = { - @ExtensionProperty(name = "name", value = "Massimiliano Assante"), - @ExtensionProperty(name = "email", value = "massimiliano.assante@isti.cnr.it") - }), - @Extension(name = "development-host", properties = { - @ExtensionProperty(name = "url", value = "https://socialnetworking-d-d4s.d4science.org"), - }) - } - ), - externalDocs=@ExternalDocs(url="https://wiki.gcube-system.org/gcube/Social_Networking_Service", value="Wiki page at gCube"), - host="socialnetworking1.d4science.org", - basePath="social-networking-library-ws/rest", - securityDefinition=@SecurityDefinition( - apiKeyAuthDefinitions={ - @ApiKeyAuthDefinition(key=Bootstrap.GCUBE_TOKEN_IN_QUERY_DEF, description="A token bound to a user (or app identifier) and a context", in=ApiKeyLocation.HEADER, name="gcube-token"), - @ApiKeyAuthDefinition(key=Bootstrap.GCUBE_TOKEN_IN_HEADER_DEF, description="A token bound to a user (or app identifier) and a context", in=ApiKeyLocation.QUERY, name="gcube-token") - }), - schemes = {SwaggerDefinition.Scheme.HTTP, SwaggerDefinition.Scheme.HTTPS} - ) -public interface SNLApiConfig { - -} diff --git a/src/main/java/org/gcube/portal/social/networking/ws/docs/DocsGenerator.java b/src/main/java/org/gcube/portal/social/networking/ws/docs/DocsGenerator.java new file mode 100644 index 0000000..99e79bb --- /dev/null +++ b/src/main/java/org/gcube/portal/social/networking/ws/docs/DocsGenerator.java @@ -0,0 +1,45 @@ +package org.gcube.portal.social.networking.ws.docs; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Path("docs") +public class DocsGenerator { + + private static Logger logger = LoggerFactory.getLogger(DocsGenerator.class); + + @GET + @Path("/{any: .*}") + public InputStream toDoc(@Context HttpServletRequest req) throws WebApplicationException { + logger.info(DocsGenerator.class.getSimpleName() + " toDoc called"); + + String pathInfo = req.getPathInfo(); + logger.debug("pathInfo {}", pathInfo); + try { + + if (pathInfo.endsWith("/docs/")) { + pathInfo += "index.html"; + } + + logger.info("going to {}", pathInfo); + + String realPath = req.getServletContext().getRealPath(pathInfo); + return new FileInputStream(new File(realPath)); + + } catch (Exception e) { + e.printStackTrace(); + //MANAGE THE EXCEPTION + } + return null; + } +} \ No newline at end of file diff --git a/src/main/java/org/gcube/portal/social/networking/ws/inputs/ApplicationId.java b/src/main/java/org/gcube/portal/social/networking/ws/inputs/ApplicationId.java index 58495d9..3502379 100644 --- a/src/main/java/org/gcube/portal/social/networking/ws/inputs/ApplicationId.java +++ b/src/main/java/org/gcube/portal/social/networking/ws/inputs/ApplicationId.java @@ -1,8 +1,5 @@ package org.gcube.portal.social.networking.ws.inputs; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; - import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; @@ -13,18 +10,12 @@ import com.fasterxml.jackson.annotation.JsonProperty; * Application id object * @author Costantino Perciante at ISTI-CNR */ -@ApiModel(description="An object containing the app_id field", value="Application") +//@ApiModel(description="An object containing the app_id field", value="Application") public class ApplicationId { @JsonProperty("app_id") @NotNull(message="app_id cannot be null") @Size(message="app_id cannot be empty", min=1) - @ApiModelProperty( - example="appX", - name="app_id", - required=true, - value="The application identifier" - ) private String appId; public ApplicationId() { diff --git a/src/main/java/org/gcube/portal/social/networking/ws/inputs/JobNotificationBean.java b/src/main/java/org/gcube/portal/social/networking/ws/inputs/JobNotificationBean.java index 39a55ca..1f92736 100644 --- a/src/main/java/org/gcube/portal/social/networking/ws/inputs/JobNotificationBean.java +++ b/src/main/java/org/gcube/portal/social/networking/ws/inputs/JobNotificationBean.java @@ -1,8 +1,5 @@ package org.gcube.portal.social.networking.ws.inputs; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; - import javax.validation.constraints.NotNull; import org.gcube.portal.databook.shared.JobStatusType; @@ -12,65 +9,51 @@ import org.gcube.portal.social.networking.ws.providers.JobStatusTypeDeserializer import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.webcohesion.enunciate.metadata.DocumentationExample; /** * The job notification bean class. - * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it) */ @JsonIgnoreProperties(ignoreUnknown = true) // ignore in serialization/deserialization -@ApiModel(description="A job notification object", value="JobNotification") +/** + * @label A job notification object + */ public class JobNotificationBean { @JsonProperty("recipient") @NotNull(message="recipient cannot be missing") - @ApiModelProperty(value="The recipient of the notification", - required=true, - example="andrea.rossi", - name="recipient") + + /* + * @param "The recipient of the notification", + */ + @DocumentationExample("andrea.rossi") private String recipient; + + /* + * @param jobId The job's identifier, i.e. very likely a UUID + */ @JsonProperty("job_id") - @ApiModelProperty(value="The job's identifier, i.e. very likely a UUID", - required=true, - example="88055f18-558a-4246-942d-a43012528c92", - name="job_id") - @NotNull(message="job_id cannot be missing") private String jobId; @JsonProperty("job_name") - @ApiModelProperty(value="The job's name", - required=true, - example="SocialDataIndexer Plugin", - name="job_name") - @NotNull(message="job_name cannot be missing") private String jobName; @JsonProperty("service_name") - @ApiModelProperty(value="The name of the service running the job", - required=true, - example="SmartExecutor", - name="service_name") @NotNull(message="service_name cannot be missing") + /* + * @param serviceName The name of the service running the job + */ private String serviceName; @JsonProperty("status") - @ApiModelProperty(value="The status of the job", - required=true, - example="FAILED", - name="status", - allowableValues = "CANCELLED,CANCELLING,DELETED,DELETING,EXECUTING,FAILED,NEW,SUBMITTED,SUCCEEDED,TIMED_OUT,WAITING" - ) @JsonDeserialize(using=JobStatusTypeDeserializer.class) @NotNull(message="status cannot be missing") private JobStatusType status; @JsonProperty("status_message") - @ApiModelProperty(value="A message reporting the reason of the current status", - required=false, - example="An error occurred while ...", - name="status_message") - private String statusMessage; + private String statusMessage; public JobNotificationBean() { super(); diff --git a/src/main/java/org/gcube/portal/social/networking/ws/inputs/MessageInputBean.java b/src/main/java/org/gcube/portal/social/networking/ws/inputs/MessageInputBean.java index bf2792b..d1f89cb 100644 --- a/src/main/java/org/gcube/portal/social/networking/ws/inputs/MessageInputBean.java +++ b/src/main/java/org/gcube/portal/social/networking/ws/inputs/MessageInputBean.java @@ -1,8 +1,5 @@ package org.gcube.portal.social.networking.ws.inputs; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; - import java.io.Serializable; import java.util.ArrayList; @@ -15,47 +12,31 @@ import com.fasterxml.jackson.annotation.JsonProperty; /** * Generic input bean for methods that allow to write messages - * @author Costantino Perciante at ISTI-CNR */ @JsonIgnoreProperties(ignoreUnknown = true) // ignore in serialization/deserialization -@ApiModel(description="A message object", value="Message") + public class MessageInputBean implements Serializable { private static final long serialVersionUID = -1317811686036127456L; - /*@JsonProperty("sender") - @ApiModelProperty( - example="andrea.rossi", - required=false, - hidden=true, // do not show this information - value="The sender of the message. If not specified is the gcube-token's owner") - private String sender;*/ - @JsonProperty("body") @NotNull(message="body cannot be missing") @Size(min=1, message="body cannot be empty") - @ApiModelProperty( - example="This is the body of the mail ...", - required= true, - value="The body of the message") + private String body; @JsonProperty("subject") @NotNull(message="subject cannot be missing") @Size(min=1, message="subject cannot be empty") - @ApiModelProperty( - example="This is the subject of the mail ...", - required= true, - value="The subject of the message") + /** + * subject + */ private String subject; @JsonProperty("recipients") @NotNull(message="recipients cannot be missing") @Size(min=1, message="at least a recipient is needed") @Valid // validate recursively - @ApiModelProperty( - required= true, - value="The recipients of this message. At least one is needed") private ArrayList recipients; public MessageInputBean() { @@ -71,12 +52,6 @@ public class MessageInputBean implements Serializable { this.recipients = recipients; } - // public String getSender() { - // return sender; - // } - // public void setSender(String sender) { - // this.sender = sender; - // } public String getBody() { return body; } @@ -104,11 +79,6 @@ public class MessageInputBean implements Serializable { + (recipients != null ? "recipients=" + recipients : "") + "]"; } - // @Override - // public String toString() { - // return "MessageInputBean [sender=" + sender + ", body=" + body - // + ", subject=" + subject + ", recipients=" + recipients + "]"; - // } } diff --git a/src/main/java/org/gcube/portal/social/networking/ws/inputs/PostInputBean.java b/src/main/java/org/gcube/portal/social/networking/ws/inputs/PostInputBean.java index 4e9f76c..0cea77a 100644 --- a/src/main/java/org/gcube/portal/social/networking/ws/inputs/PostInputBean.java +++ b/src/main/java/org/gcube/portal/social/networking/ws/inputs/PostInputBean.java @@ -1,8 +1,5 @@ package org.gcube.portal.social.networking.ws.inputs; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; - import java.io.Serializable; import javax.validation.constraints.NotNull; @@ -10,12 +7,12 @@ import javax.validation.constraints.Size; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import com.webcohesion.enunciate.metadata.DocumentationExample; /** * Generic input bean for methods that allow to write posts * @author Costantino Perciante at ISTI-CNR */ @JsonIgnoreProperties(ignoreUnknown = true) // ignore in serialization/deserialization -@ApiModel(description="A post object", value="Post") public class PostInputBean implements Serializable{ private static final long serialVersionUID = 5274608088828232980L; @@ -23,58 +20,36 @@ public class PostInputBean implements Serializable{ @JsonProperty("text") @NotNull(message="text cannot be null") @Size(min=1, message="text cannot be empty") - @ApiModelProperty( - example="Dear vre members, ...", - required=true, - value="The text of the post") + @DocumentationExample("Dear vre members, ...") + /** + * text the text of the post + */ private String text; - @JsonProperty("preview_title") - @ApiModelProperty( - required=false, - value="A preview title for the preview", - name="preview_title") private String previewtitle; @JsonProperty("preview_description") - @ApiModelProperty( - required=false, - value="A preview description for the preview", - name="preview_description") private String previewdescription; @JsonProperty("preview_host") - @ApiModelProperty( - required=false, - value="A preview host for the preview", - name="preview_host") private String previewhost; @JsonProperty("preview_url") - @ApiModelProperty( - required=false, - value="A preview url for the preview", - name="preview_url") private String previewurl; + /** + * param httpimageurl An image url for the preview" + */ @JsonProperty("image_url") - @ApiModelProperty( - required=false, - value="An image url for the preview", - name="image_url") private String httpimageurl; + /** + * enablenotification If true send a notification to the other vre members about this post + */ @JsonProperty("enable_notification") - @ApiModelProperty( - required=false, - value="If true send a notification to the other vre members about this post", - name="enable_notification") private boolean enablenotification; @JsonProperty("params") - @ApiModelProperty( - required=false, - value="Other parameters for the application's posts") private String params; public PostInputBean() { diff --git a/src/main/java/org/gcube/portal/social/networking/ws/inputs/Recipient.java b/src/main/java/org/gcube/portal/social/networking/ws/inputs/Recipient.java index e375a7b..c3383fa 100644 --- a/src/main/java/org/gcube/portal/social/networking/ws/inputs/Recipient.java +++ b/src/main/java/org/gcube/portal/social/networking/ws/inputs/Recipient.java @@ -1,8 +1,5 @@ package org.gcube.portal.social.networking.ws.inputs; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; - import java.io.Serializable; import javax.validation.constraints.NotNull; @@ -10,6 +7,7 @@ import javax.validation.constraints.Size; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import com.webcohesion.enunciate.metadata.DocumentationExample; /** * Recipient message bean @@ -18,7 +16,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; * */ @JsonIgnoreProperties(ignoreUnknown = true) // ignore in serialization/deserialization -@ApiModel(description="A recipient object") public class Recipient implements Serializable{ private static final long serialVersionUID = 1071412144446514138L; @@ -26,10 +23,10 @@ public class Recipient implements Serializable{ @JsonProperty("id") @NotNull(message="recipient id must not be null") @Size(min=1, message="recipient id must not be empty") - @ApiModelProperty( - example="andrea.rossi", - required=true, - value="The id of the recipient") + /* + * @param "The recipient of the message", + */ + @DocumentationExample("john.smith") private String id; public Recipient() { diff --git a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Comments.java b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Comments.java index b21c06b..a2f0c7e 100644 --- a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Comments.java +++ b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Comments.java @@ -1,13 +1,6 @@ package org.gcube.portal.social.networking.ws.methods.v2; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import io.swagger.annotations.Authorization; - import java.util.List; import javax.validation.ValidationException; @@ -24,25 +17,25 @@ import org.gcube.common.authorization.library.provider.AuthorizationProvider; import org.gcube.common.authorization.library.utils.Caller; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.portal.databook.shared.Comment; -import org.gcube.portal.social.networking.swagger.config.Bootstrap; -import org.gcube.portal.social.networking.swagger.config.SwaggerConstants; import org.gcube.portal.social.networking.ws.outputs.ResponseBean; import org.gcube.portal.social.networking.ws.utils.CassandraConnection; import org.gcube.portal.social.networking.ws.utils.ErrorMessages; import org.gcube.portal.social.networking.ws.utils.Filters; import org.slf4j.LoggerFactory; +import com.webcohesion.enunciate.metadata.rs.RequestHeader; +import com.webcohesion.enunciate.metadata.rs.RequestHeaders; +import com.webcohesion.enunciate.metadata.rs.ResponseCode; +import com.webcohesion.enunciate.metadata.rs.StatusCodes; + /** * REST interface for the social networking library (comments). - * @author Costantino Perciante at ISTI-CNR */ @Path("2/comments") -@Api(value=SwaggerConstants.COMMENTS, authorizations={@Authorization(value = Bootstrap.GCUBE_TOKEN_IN_QUERY_DEF), @Authorization(value = Bootstrap.GCUBE_TOKEN_IN_HEADER_DEF)}) -/** - * Resource endpoint for Comment (version 2) - * @author Costantino Perciante at ISTI-CNR - * (costantino.perciante@isti.cnr.it) - */ +@RequestHeaders ({ + @RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"), + @RequestHeader( name = "Content-Type", description = "application/json") + }) public class Comments { // Logger @@ -51,10 +44,13 @@ public class Comments { @GET @Produces(MediaType.APPLICATION_JSON) @Path("get-comments-user") - @ApiOperation(value = "Retrieve user's comments", response=ResponseBean.class, nickname="get-comments-user", notes="Retrieve the list of comments belonging to the owner of the token in the related context.") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "The list of comments is put into the 'result' field", response = ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) + @StatusCodes ({ + @ResponseCode ( code = 200, condition = "The list of comments is put into the 'result' field"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) + /* + * Retrieve the list of comments belonging to the owner of the token in the related context. + */ public Response getCommentsUser() { ResponseBean responseBean = new ResponseBean(); @@ -83,19 +79,12 @@ public class Comments { @GET @Produces(MediaType.APPLICATION_JSON) @Path("get-comments-user-by-time") - @ApiOperation(value = "Retrieve user's comments and filter by date", notes="Retrieve comments of the gcube-token's owner in the context bound to the token itself and filter them by date", - response=ResponseBean.class, nickname="get-comments-user-by-time") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "The list of comments is put into the 'result' field", response = ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) + /* + * Retrieve comments of the gcube-token's owner in the context bound to the token itself and filter them by date + */ public Response getCommentsUserByTime( @QueryParam("time") @Min(value = 0, message="time cannot be negative") - @ApiParam( - allowableValues="range[0, infinity]", - required=true, - name="time", - value="the base time for filtering operation") long timeInMillis ) throws ValidationException{ diff --git a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/FullTextSearch.java b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/FullTextSearch.java index 23bb40f..d92835f 100644 --- a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/FullTextSearch.java +++ b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/FullTextSearch.java @@ -1,12 +1,5 @@ package org.gcube.portal.social.networking.ws.methods.v2; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import io.swagger.annotations.Authorization; - import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -35,8 +28,6 @@ import org.gcube.portal.databook.shared.EnhancedFeed; import org.gcube.portal.databook.shared.Feed; import org.gcube.portal.social.networking.liferay.ws.GroupManagerWSBuilder; import org.gcube.portal.social.networking.liferay.ws.UserManagerWSBuilder; -import org.gcube.portal.social.networking.swagger.config.Bootstrap; -import org.gcube.portal.social.networking.swagger.config.SwaggerConstants; import org.gcube.portal.social.networking.ws.outputs.ResponseBean; import org.gcube.portal.social.networking.ws.utils.CassandraConnection; import org.gcube.portal.social.networking.ws.utils.ElasticSearchConnection; @@ -49,40 +40,47 @@ import org.gcube.vomanagement.usermanagement.model.GCubeGroup; import org.gcube.vomanagement.usermanagement.model.GCubeUser; import org.slf4j.LoggerFactory; +import com.webcohesion.enunciate.metadata.rs.RequestHeader; +import com.webcohesion.enunciate.metadata.rs.RequestHeaders; +import com.webcohesion.enunciate.metadata.rs.ResponseCode; +import com.webcohesion.enunciate.metadata.rs.StatusCodes; + /** * REST interface for the social networking library (post and its comments). - * @author Costantino Perciante at ISTI-CNR */ @Path("2/full-text-search") -@Api(value=SwaggerConstants.FULLTEXT, authorizations={@Authorization(value = Bootstrap.GCUBE_TOKEN_IN_QUERY_DEF), @Authorization(value = Bootstrap.GCUBE_TOKEN_IN_HEADER_DEF)}) +@RequestHeaders ({ + @RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"), + @RequestHeader( name = "Content-Type", description = "application/json") + }) public class FullTextSearch { // Logger private static final org.slf4j.Logger logger = LoggerFactory.getLogger(FullTextSearch.class); + /** + * Retrieve posts/comments that match the given query + * @param httpServletRequest + * @param query A string to search for + * @param from the index of the base result to be returned, range[0, infinity], defaults from = 0 + * @param quantity defines how many results are most are to be returned, range[1, infinity], defaults from = 0, + * @return The posts/comments returned belong to the context bound to the AUTH Token + * @throws ValidationException + */ @GET @Path("search-by-query") @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve posts/comments that match the given query", - notes="The posts/comments returned belong to the context bound to the gcube-token", - response=ResponseBean.class, nickname="search-by-query") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Successful retrieval of posts/comments that match the query, reported in the 'result' field of the returned object", response = ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) + @StatusCodes ({ + @ResponseCode ( code = 200, condition = "Successful retrieval of posts/comments that match the query, reported in the 'result' field of the returned object"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) public Response searchByQuery( @Context HttpServletRequest httpServletRequest, @QueryParam("query") @NotNull(message="query cannot be null") @Size(min=1, message="query cannot be empty") - @ApiParam(required=true, defaultValue="none", name="query", value="A string to search for") String query, - @DefaultValue("0") @QueryParam("from") @Min(value=0, message="from cannot be negative") - @ApiParam(allowableValues="range[0, infinity]", - required=false, name="from", value="the index of the base result to be returned") - int from, - + int from, @DefaultValue("10") @QueryParam("quantity") @Min(value=0, message="quantity cannot be negative") - @ApiParam(allowableValues="range[1, infinity]", - required=false, name="quantity", value="defines how many results are most are to be returned") int quantity ) throws ValidationException{ diff --git a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/HashTags.java b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/HashTags.java index d8e21d4..2b85b5f 100644 --- a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/HashTags.java +++ b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/HashTags.java @@ -1,11 +1,5 @@ package org.gcube.portal.social.networking.ws.methods.v2; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import io.swagger.annotations.Authorization; - import java.util.Map; import javax.ws.rs.GET; @@ -20,19 +14,24 @@ import org.gcube.common.authorization.library.utils.Caller; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.portal.databook.server.DatabookStore; import org.gcube.portal.social.networking.liferay.ws.GroupManagerWSBuilder; -import org.gcube.portal.social.networking.swagger.config.Bootstrap; -import org.gcube.portal.social.networking.swagger.config.SwaggerConstants; import org.gcube.portal.social.networking.ws.outputs.ResponseBean; import org.gcube.portal.social.networking.ws.utils.CassandraConnection; import org.gcube.portal.social.networking.ws.utils.ErrorMessages; import org.slf4j.LoggerFactory; +import com.webcohesion.enunciate.metadata.rs.RequestHeader; +import com.webcohesion.enunciate.metadata.rs.RequestHeaders; +import com.webcohesion.enunciate.metadata.rs.ResponseCode; +import com.webcohesion.enunciate.metadata.rs.StatusCodes; + /** * REST interface for the social networking library (hash tags). - * @author Costantino Perciante at ISTI-CNR */ @Path("2/hashtags") -@Api(value=SwaggerConstants.HASHTAGS, authorizations={@Authorization(value = Bootstrap.GCUBE_TOKEN_IN_QUERY_DEF), @Authorization(value = Bootstrap.GCUBE_TOKEN_IN_HEADER_DEF)}) +@RequestHeaders ({ + @RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"), + @RequestHeader( name = "Content-Type", description = "application/json") + }) public class HashTags { // Logger @@ -41,11 +40,13 @@ public class HashTags { @GET @Path("get-hashtags-and-occurrences/") @Produces({MediaType.APPLICATION_JSON}) - @ApiOperation(value = "Retrieve hashtags", nickname="get-hashtags-and-occurrences", - notes="Retrieve hashtags in the context bound to the gcube-token", response=ResponseBean.class) - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Hashtags and occurrences retrieved, reported in the 'result' field of the returned object", response = ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) + @StatusCodes ({ + @ResponseCode ( code = 200, condition = "Hashtags and occurrences retrieved, reported in the 'result' field of the returned object"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) + /** + * @return hashtags in the context bound to the auth token + */ public Response getHashTagsAndOccurrences(){ Caller caller = AuthorizationProvider.instance.get(); diff --git a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Messages.java b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Messages.java index 70fc6f4..e462226 100644 --- a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Messages.java +++ b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Messages.java @@ -34,8 +34,6 @@ import org.gcube.portal.notifications.thread.MessageNotificationsThread; import org.gcube.portal.social.networking.caches.SocialNetworkingSiteFinder; import org.gcube.portal.social.networking.liferay.ws.LiferayJSONWsCredentials; import org.gcube.portal.social.networking.liferay.ws.UserManagerWSBuilder; -import org.gcube.portal.social.networking.swagger.config.Bootstrap; -import org.gcube.portal.social.networking.swagger.config.SwaggerConstants; import org.gcube.portal.social.networking.ws.inputs.MessageInputBean; import org.gcube.portal.social.networking.ws.inputs.Recipient; import org.gcube.portal.social.networking.ws.outputs.ResponseBean; @@ -46,12 +44,10 @@ import org.gcube.vomanagement.usermanagement.exception.UserRetrievalFault; import org.gcube.vomanagement.usermanagement.model.GCubeUser; import org.slf4j.LoggerFactory; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import io.swagger.annotations.Authorization; +import com.webcohesion.enunciate.metadata.rs.RequestHeader; +import com.webcohesion.enunciate.metadata.rs.RequestHeaders; +import com.webcohesion.enunciate.metadata.rs.ResponseCode; +import com.webcohesion.enunciate.metadata.rs.StatusCodes; /** * Messages services REST interface @@ -59,25 +55,36 @@ import io.swagger.annotations.Authorization; * (costantino.perciante@isti.cnr.it) */ @Path("2/messages") -@Api(value=SwaggerConstants.MESSAGES, authorizations={@Authorization(value = Bootstrap.GCUBE_TOKEN_IN_QUERY_DEF), @Authorization(value = Bootstrap.GCUBE_TOKEN_IN_HEADER_DEF)}) +@RequestHeaders ({ + @RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"), + @RequestHeader( name = "Content-Type", description = "application/json") + }) public class Messages { // Logger private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Messages.class); + /** + * Write a message to another user. The sender is the token's owner by default + * @responseExample application/json {"success": true, "message": null, "result": "556142e3-d6f5-4550-b2fa-abe5626625d3"} + * @param input The message to write" + * @param httpServletRequest + * @return see response example + * @throws ValidationException + * @throws UserManagementSystemException + * @throws UserRetrievalFault + */ @POST @Path("write-message/") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Write a message to another user", notes="Write a message to another user. The sender is the token's owner by default", - response=ResponseBean.class, nickname="write-message") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Successful write a message. Its id is reported in the 'result' field of the returned object", response = ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) + @StatusCodes ({ + @ResponseCode ( code = 200, condition = "Successful write a message. Its id is reported in the 'result' field of the returned object"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) public Response writeMessage( @NotNull(message="Message to send is missing") @Valid - @ApiParam(name="input", required=true, allowMultiple=false, value="The message to write") MessageInputBean input, @Context HttpServletRequest httpServletRequest) throws ValidationException, UserManagementSystemException, UserRetrievalFault{ @@ -165,11 +172,14 @@ public class Messages { @GET @Path("get-sent-messages") @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve the list of sent messages", notes="Retrieve the list of sent messages. The user is the token's owner by default", - response=ResponseBean.class, nickname="get-sent-messages") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Successful read of the sent messages, reported in the 'result' field of the returned object", response = ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) + @StatusCodes ({ + @ResponseCode ( code = 200, condition = "Successful read of the sent messages, reported in the 'result' field of the returned object"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) + /** + * + * @return the list of sent messages of the user (the token's owner) + */ public Response getSentMessages(){ Caller caller = AuthorizationProvider.instance.get(); @@ -198,11 +208,14 @@ public class Messages { @GET @Path("get-received-messages") @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve the list of received messages", notes="Retrieve the list of received messages. The user is the token's owner by default", - response=ResponseBean.class, nickname="get-received-messages") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Successful read of the received messages, reported in the 'result' field of the returned object", response = ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) + @StatusCodes ({ + @ResponseCode ( code = 200, condition = "Successful read of the received messages, reported in the 'result' field of the returned object"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) + /** + * + * @return the list of received messages of the user (the token's owner) + */ public Response getReceivedMessages(){ Caller caller = AuthorizationProvider.instance.get(); diff --git a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Notifications.java b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Notifications.java index 4881c12..a2d7e26 100644 --- a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Notifications.java +++ b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Notifications.java @@ -1,12 +1,5 @@ package org.gcube.portal.social.networking.ws.methods.v2; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import io.swagger.annotations.Authorization; - import java.util.Arrays; import java.util.List; @@ -38,8 +31,6 @@ import org.gcube.portal.notifications.thread.JobStatusNotificationThread; import org.gcube.portal.social.networking.caches.SocialNetworkingSiteFinder; import org.gcube.portal.social.networking.liferay.ws.LiferayJSONWsCredentials; import org.gcube.portal.social.networking.liferay.ws.UserManagerWSBuilder; -import org.gcube.portal.social.networking.swagger.config.Bootstrap; -import org.gcube.portal.social.networking.swagger.config.SwaggerConstants; import org.gcube.portal.social.networking.ws.inputs.JobNotificationBean; import org.gcube.portal.social.networking.ws.outputs.ResponseBean; import org.gcube.portal.social.networking.ws.utils.CassandraConnection; @@ -47,12 +38,19 @@ import org.gcube.portal.social.networking.ws.utils.ErrorMessages; import org.gcube.vomanagement.usermanagement.model.GCubeUser; import org.slf4j.LoggerFactory; +import com.webcohesion.enunciate.metadata.rs.RequestHeader; +import com.webcohesion.enunciate.metadata.rs.RequestHeaders; +import com.webcohesion.enunciate.metadata.rs.ResponseCode; +import com.webcohesion.enunciate.metadata.rs.StatusCodes; + /** * REST interface for the social networking library (notifications). - * @author Costantino Perciante at ISTI-CNR */ @Path("2/notifications") -@Api(value=SwaggerConstants.NOTIFICATIONS, authorizations={@Authorization(value = Bootstrap.GCUBE_TOKEN_IN_QUERY_DEF), @Authorization(value = Bootstrap.GCUBE_TOKEN_IN_HEADER_DEF)}) +@RequestHeaders ({ + @RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"), + @RequestHeader( name = "Content-Type", description = "application/json") + }) public class Notifications { // Logger @@ -61,20 +59,21 @@ public class Notifications { @GET @Path("get-range-notifications/") @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve user's notifications", notes="Retrieve notifications of the gcube-token's owner", - response=ResponseBean.class, nickname="get-range-notifications") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Notifications retrieved and reported in the 'result' field of the returned object", response = ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) + /** + * Retrieve notifications of the gcube-token's owner + * @param from must be greater or equal to 1, range[0, infinity] + * @param quantity quantity must be greater or equal to 0 + * @return notifications up to quantity + * @throws ValidationException + */ + @StatusCodes ({ + @ResponseCode ( code = 200, condition = "Notifications retrieved and reported in the 'result' field of the returned object"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) public Response getRangeNotifications( @DefaultValue("1") @QueryParam("from") @Min(value=1, message="from must be greater or equal to 1") - @ApiParam(allowableValues="range[0, infinity]", - required=false, allowMultiple=false, value="The base index notification") int from, - @DefaultValue("10") @QueryParam("quantity") @Min(value=0, message="quantity must be greater or equal to 0") - @ApiParam(allowableValues="range[1, infinity]", - required=false, allowMultiple=false, value="Retrieve notifications up to this quantity") int quantity ) throws ValidationException{ @@ -102,19 +101,24 @@ public class Notifications { return Response.status(status).entity(responseBean).build(); } + /** + * Send a JOB notification to a given recipient + * @param job The job bean + * @return + * @throws ValidationException + */ @POST @Path("notify-job-status/") - @ApiOperation(value = "Send a JOB Notification", notes="Send a JOB notification to a given recipient", - response=ResponseBean.class, nickname="notify-job-status") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Notification is sent correctly", response = ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) + @StatusCodes ({ + @ResponseCode ( code = 200, condition = "Notification is sent correctly"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) public Response notifyJobStatus( @NotNull(message="input is missing") - @ApiParam(name="job", required=true, allowMultiple=false, value="The job bean") - @Valid JobNotificationBean job) throws ValidationException{ + @Valid + JobNotificationBean job) throws ValidationException{ Caller caller = AuthorizationProvider.instance.get(); String context = ScopeProvider.instance.get(); diff --git a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/People.java b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/People.java index bc08843..be9024a 100644 --- a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/People.java +++ b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/People.java @@ -1,11 +1,5 @@ package org.gcube.portal.social.networking.ws.methods.v2; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import io.swagger.annotations.Authorization; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -13,8 +7,6 @@ import java.util.Map; import javax.ws.rs.GET; import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; @@ -24,8 +16,6 @@ import org.gcube.common.scope.api.ScopeProvider; import org.gcube.portal.social.networking.liferay.ws.GroupManagerWSBuilder; import org.gcube.portal.social.networking.liferay.ws.RoleManagerWSBuilder; import org.gcube.portal.social.networking.liferay.ws.UserManagerWSBuilder; -import org.gcube.portal.social.networking.swagger.config.Bootstrap; -import org.gcube.portal.social.networking.swagger.config.SwaggerConstants; import org.gcube.portal.social.networking.ws.outputs.ResponseBean; import org.gcube.portal.social.networking.ws.utils.ErrorMessages; import org.gcube.portal.social.networking.ws.utils.TokensUtils; @@ -36,25 +26,34 @@ import org.gcube.vomanagement.usermanagement.model.GCubeRole; import org.gcube.vomanagement.usermanagement.model.GCubeUser; import org.slf4j.LoggerFactory; +import com.webcohesion.enunciate.metadata.rs.RequestHeader; +import com.webcohesion.enunciate.metadata.rs.RequestHeaders; +import com.webcohesion.enunciate.metadata.rs.ResponseCode; +import com.webcohesion.enunciate.metadata.rs.StatusCodes; + /** - * REST interface for the social networking library (people). Used by OAUTH 2.0 apps/users. - * @author Costantino Perciante at ISTI-CNR + * REST interface for the social service (people). Used by OAUTH 2.0 apps/users. */ +@RequestHeaders ({ + @RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"), + @RequestHeader( name = "Content-Type", description = "application/json") + }) @Path("2/people") -@Api(value=SwaggerConstants.PEOPLE, authorizations={@Authorization(value = Bootstrap.GCUBE_TOKEN_IN_QUERY_DEF), @Authorization(value = Bootstrap.GCUBE_TOKEN_IN_HEADER_DEF)}) public class People { private static final org.slf4j.Logger logger = LoggerFactory.getLogger(People.class); @GET @Path("profile") - @ApiOperation(value = "Retrieve user's profile", notes="Retrieve the user's profile. The user in this case is the one bound to the token which can be of any kind (qualified, default)", - response=ResponseBean.class, nickname="profile") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Successful retrieval of user's profile, reported in the 'result' field of the returned object", response = ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) - @Produces(MediaType.APPLICATION_JSON) + @StatusCodes ({ + @ResponseCode ( code = 200, condition = "Successful retrieval of user's profile, reported in the 'result' field of the returned object"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) + /** + * @responseExample application/json { "success" : true, "message" : null, "result" : { "roles" : [ ], "context" : "***", "avatar" : "https://*****3D", "fullname" : "John Smith", "username" : "john.smith" } } + * @return the user's profile. The user in this case is the one bound to the token + */ public Response getProfile(){ Caller caller = AuthorizationProvider.instance.get(); diff --git a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Posts.java b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Posts.java index 257fa1b..6c09d79 100644 --- a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Posts.java +++ b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Posts.java @@ -1,13 +1,6 @@ package org.gcube.portal.social.networking.ws.methods.v2; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import io.swagger.annotations.Authorization; - import java.util.ArrayList; import java.util.List; @@ -32,8 +25,6 @@ import org.gcube.common.scope.api.ScopeProvider; import org.gcube.portal.databook.server.DatabookStore; import org.gcube.portal.databook.shared.ApplicationProfile; import org.gcube.portal.databook.shared.Feed; -import org.gcube.portal.social.networking.swagger.config.Bootstrap; -import org.gcube.portal.social.networking.swagger.config.SwaggerConstants; import org.gcube.portal.social.networking.ws.inputs.PostInputBean; import org.gcube.portal.social.networking.ws.outputs.ResponseBean; import org.gcube.portal.social.networking.ws.utils.CassandraConnection; @@ -42,12 +33,19 @@ import org.gcube.portal.social.networking.ws.utils.Filters; import org.gcube.portal.social.networking.ws.utils.SocialUtils; import org.slf4j.LoggerFactory; +import com.webcohesion.enunciate.metadata.rs.RequestHeader; +import com.webcohesion.enunciate.metadata.rs.RequestHeaders; +import com.webcohesion.enunciate.metadata.rs.ResponseCode; +import com.webcohesion.enunciate.metadata.rs.StatusCodes; + /** - * REST interface for the social networking library (feeds). - * @author Costantino Perciante at ISTI-CNR + * REST interface for the social networking library (posts). */ @Path("2/posts") -@Api(value=SwaggerConstants.POSTS, authorizations={@Authorization(value = Bootstrap.GCUBE_TOKEN_IN_QUERY_DEF), @Authorization(value = Bootstrap.GCUBE_TOKEN_IN_HEADER_DEF)}) +@RequestHeaders ({ + @RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"), + @RequestHeader( name = "Content-Type", description = "application/json") + }) public class Posts { // Logger @@ -56,15 +54,18 @@ public class Posts { @GET @Path("get-posts-user-since/") @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve user's posts", notes="Retrieve posts of the gcube-token's owner, and allow to filter them by time", - response=ResponseBean.class, nickname="get-posts-user-since") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Successful retrieval of posts, reported in the 'result' field of the returned object", response = ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) + @StatusCodes ({ + @ResponseCode ( code = 200, condition = "Successful retrieval of posts, reported in the 'result' field of the returned object"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) + /** + * Retrieve posts of the auth token's owner, and allow to filter them by time" + * @param timeInMillis The reference time since when retrieving posts + * @return the posts + * @throws ValidationException + */ public Response getRecentPostsByUserAndDate( @QueryParam("time") @Min(value = 0, message="time cannot be negative") - @ApiParam(allowableValues="range[0, infinity]", name="time", - required=true, allowMultiple=false, value="The reference time since when retrieving posts") long timeInMillis ) throws ValidationException{ @@ -97,11 +98,14 @@ public class Posts { @GET @Path("get-posts-user/") @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve all user's posts", notes="Retrieve all posts of the gcube-token's owner", - response=ResponseBean.class, nickname="get-posts-user") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Successful retrieval of posts, reported in the 'result' field of the returned object", response = ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) + @StatusCodes ({ + @ResponseCode ( code = 200, condition = "Successful retrieval of posts, reported in the 'result' field of the returned object"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) + /** + * Retrieve all user's posts + * @return all posts of the auth token's owner in the context identified by the token + */ public Response getAllPostsByUser() { Caller caller = AuthorizationProvider.instance.get(); @@ -131,17 +135,20 @@ public class Posts { @GET @Path("get-posts-user-quantity/") @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve a given quantity of latest user's posts", notes="Retrieve a given quantity of latest posts of the gcube-token's owner", - response=ResponseBean.class, nickname="get-posts-user-quantity") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Successful retrieval of posts, reported in the 'result' field of the returned object", response = ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) + @StatusCodes ({ + @ResponseCode ( code = 200, condition = "Successful retrieval of posts, reported in the 'result' field of the returned object"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) + /** + * Retrieve a given quantity of latest user's posts + * @param quantity the number of latest post to get + * @return all posts of the auth token's owner in the context identified by the token, in reverse chronological order up to quantity (at most) + * @throws ValidationException + */ public Response getQuantityPostsByUser( @DefaultValue("10") @QueryParam("quantity") @Min(value=0, message="quantity cannot be negative") - @ApiParam(allowableValues="range[0, infinity]", name="quantity", - required=false, allowMultiple=false, value="How many posts needs to be retrieved at most") int quantity) throws ValidationException{ Caller caller = AuthorizationProvider.instance.get(); @@ -178,16 +185,19 @@ public class Posts { @Path("write-post-user") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Create a new user post", notes="Create a new user post having as owner the gcube-token's owner", - response=ResponseBean.class, nickname="write-post-user") - @ApiResponses(value = { - @ApiResponse(code = 201, message = "Successfull created, the new post is reported in the 'result' field of the returned object", response = ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) + @StatusCodes ({ + @ResponseCode ( code = 201, condition = "Successfull created, the new post is reported in the 'result' field of the returned object"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) + /** + * Create a new user post having as owner the auth token's owner + * @param post The post to be written + * @return + * @throws ValidationException + */ public Response writePostUser( @NotNull(message="Post to write is missing") @Valid - @ApiParam(name="post", - required=true, allowMultiple=false, value="The post to be written") PostInputBean post) throws ValidationException{ logger.debug("Request of writing a feed coming from user " + post); @@ -246,12 +256,15 @@ public class Posts { @GET @Path("get-posts-app/") @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve the application's posts", notes="Retrieve the application's posts belonging to the gcube-token's owner (i.e., an application)", - response=ResponseBean.class, nickname="get-posts-app") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Successfull retrieved posts, they are reported in the 'result' field of the returned object", response = ResponseBean.class), - @ApiResponse(code = 403, message = "There is no application profile with such token", response=ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) + @StatusCodes ({ + @ResponseCode ( code = 200, condition = "Successfull created, the new post is reported in the 'result' field of the returned object"), + @ResponseCode ( code = 403, condition = "\"There is no application profile with such token"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) + /** + * Retrieve the application's posts + * @return the application's posts belonging to the token's owner (i.e., an application)" + */ public Response getAllPostsByApp() { Caller caller = AuthorizationProvider.instance.get(); @@ -295,17 +308,19 @@ public class Posts { @Path("write-post-app") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Create a new application post", notes="Create a new application post having as owner-application the gcube-token's owner", - response=ResponseBean.class, nickname="write-post-app") - @ApiResponses(value = { - @ApiResponse(code = 201, message = "Successfull created, the new post is reported in the 'result' field of the returned object", response = ResponseBean.class), - @ApiResponse(code = 403, message = "There is no application profile with such token", response=ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) + @StatusCodes ({ + @ResponseCode ( code = 200, condition = "Successfull created, the new post is reported in the 'result' field of the returned object"), + @ResponseCode ( code = 403, condition = "\"There is no application profile with such token"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) + /** + * Create a new application post having as owner-application the token's owner (the IAM Client) + * @param post The post to be written + * @return + */ public Response writePostApp( @NotNull(message="Post to write is null") @Valid - @ApiParam(name="post", - required=true, allowMultiple=false, value="The post to be written") PostInputBean post){ Caller caller = AuthorizationProvider.instance.get(); @@ -369,11 +384,14 @@ public class Posts { @GET @Path("get-posts-vre/") @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve vre's posts", notes="Retrieve all the posts in the context bound to the gcube-token", - response=ResponseBean.class, nickname="get-posts-vre") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Successfull retrieved posts, they are reported in the 'result' field of the returned object", response = ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) + @StatusCodes ({ + @ResponseCode ( code = 201, condition = "Sccessfull retrieved posts, they are reported in the 'result' field of the returned object"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) + /** + * + * @return all the posts in the context bound to the auth token + */ public Response getAllPostsByVRE() { String scope = ScopeProvider.instance.get(); @@ -399,16 +417,19 @@ public class Posts { @GET @Path("get-posts-by-hashtag/") @Produces({MediaType.APPLICATION_JSON}) - @ApiOperation(value = "Retrieve posts containing the hashtag", notes="Retrieve posts containing the hashtag in the context bound to the gcube-token", - response=ResponseBean.class, nickname="get-posts-by-hashtag") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Successfull retrieved posts, they are reported in the 'result' field of the returned object", response = ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) + @StatusCodes ({ + @ResponseCode ( code = 201, condition = "Sccessfull retrieved posts, they are reported in the 'result' field of the returned object"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) + /** + * Retrieve posts containing the hashtag in the context bound to the auth token + * @param hashtag he hashtag to be contained within the posts + * @return the posts in the context bound to the auth token matching the hashtag + * @throws ValidationException + */ public Response getPostsByHashTags( @QueryParam("hashtag") @NotNull(message="hashtag cannot be missing") - @ApiParam(name="hashtag", - required=true, allowMultiple=false, value="The hashtag to be contained within the posts") String hashtag) throws ValidationException { Caller caller = AuthorizationProvider.instance.get(); @@ -434,11 +455,14 @@ public class Posts { @GET @Path("get-id-liked-posts/") @Produces({MediaType.APPLICATION_JSON}) - @ApiOperation(value = "Retrieve ids (UUID) of the liked by the user", notes="Retrieve ids (UUID) of the liked by the user in the context bound to the gcube-token", - response=ResponseBean.class, nickname="get-id-liked-posts") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Successfull retrieved ids, they are reported in the 'result' field of the returned object", response = ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) + @StatusCodes ({ + @ResponseCode ( code = 201, condition = "Sccessfull retrieved ids, they are reported in the 'result' field of the returned object"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) + /** + * Retrieve ids (UUID) of the liked by the user + * @return ids (UUID) of the liked by the user in the context bound to the auth token + */ public Response getAllLikedPostIdsByUser() { Caller caller = AuthorizationProvider.instance.get(); @@ -470,17 +494,20 @@ public class Posts { @GET @Path("get-liked-posts/") @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Retrieve posts liked by the user", notes="Retrieve posts liked by the user (up to a given quantity) in the context bound to the gcube-token", - response=ResponseBean.class, nickname="get-liked-posts") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Successfull retrieved posts. They are reported in the 'result' field of the returned object", response = ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) + @StatusCodes ({ + @ResponseCode ( code = 200, condition = "Successfull retrieved posts, they are reported in the 'result' field of the returned object"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) + /** + * Retrieve posts liked by the user + * @param limit The maximum number of posts to be retrieved + * @return posts liked by the user (up to a given quantity) in the context bound to the auth token + * @throws ValidationException + */ public Response getAllLikedPostsByUser( @DefaultValue("10") @QueryParam("limit") @Min(message="limit cannot be negative", value = 0) - @ApiParam(name="limit", - required=false, allowMultiple=false, value="The maximum number of posts to be retrieved") int limit) throws ValidationException{ Caller caller = AuthorizationProvider.instance.get(); diff --git a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Tokens.java b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Tokens.java index ed721c6..1c934b7 100644 --- a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Tokens.java +++ b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Tokens.java @@ -1,12 +1,6 @@ package org.gcube.portal.social.networking.ws.methods.v2; import static org.gcube.common.authorization.client.Constants.authorizationService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import io.swagger.annotations.Authorization; import javax.validation.Valid; import javax.validation.ValidationException; @@ -21,21 +15,21 @@ import javax.ws.rs.core.Response.Status; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.portal.databook.shared.ApplicationProfile; -import org.gcube.portal.social.networking.swagger.config.Bootstrap; -import org.gcube.portal.social.networking.swagger.config.SwaggerConstants; import org.gcube.portal.social.networking.ws.inputs.ApplicationId; import org.gcube.portal.social.networking.ws.outputs.ResponseBean; import org.gcube.portal.social.networking.ws.utils.ErrorMessages; import org.gcube.portal.social.networking.ws.utils.SocialUtils; import org.slf4j.LoggerFactory; +import com.webcohesion.enunciate.metadata.rs.ResponseCode; +import com.webcohesion.enunciate.metadata.rs.StatusCodes; + /** * REST interface for the social networking library (tokens). - * @author Costantino Perciante at ISTI-CNR */ @Path("2/tokens") -@Api(value=SwaggerConstants.TOKENS, authorizations={@Authorization(value = Bootstrap.GCUBE_TOKEN_IN_QUERY_DEF), @Authorization(value = Bootstrap.GCUBE_TOKEN_IN_HEADER_DEF)}) +@Deprecated public class Tokens { // Logger @@ -45,16 +39,20 @@ public class Tokens { @Path("generate-application-token/") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Generate an application token", notes="Generate an application token for the application with id app_id", - response=ResponseBean.class, nickname="generate-application-token") - @ApiResponses(value = { - @ApiResponse(code = 201, message = "Successful creation of the token, reported in the 'result' field of the returned object", response = ResponseBean.class), - @ApiResponse(code = 403, message = "There is no application profile with such id", response=ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) + @StatusCodes ({ + @ResponseCode ( code = 201, condition = "Successful creation of the token, reported in the 'result' field of the returned object"), + @ResponseCode ( code = 403, condition = "There is no application profile with such id"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) + /** + * Generate a legacy application auth token for the application with id app_id + * @param input The bean containing the app_id field + * @return the legacy application token + * @throws ValidationException + */ public Response generateApplicationToken( @NotNull(message="Missing input parameter") @Valid - @ApiParam(name="input", required=true, allowMultiple=false, value="The bean containing the app_id field") ApplicationId input) throws ValidationException{ logger.debug("Incoming request for app token generation."); diff --git a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Users.java b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Users.java index 7d705a7..3a8f28a 100644 --- a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Users.java +++ b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Users.java @@ -26,8 +26,6 @@ import org.gcube.portal.social.networking.caches.UsersCache; import org.gcube.portal.social.networking.liferay.ws.GroupManagerWSBuilder; import org.gcube.portal.social.networking.liferay.ws.RoleManagerWSBuilder; import org.gcube.portal.social.networking.liferay.ws.UserManagerWSBuilder; -import org.gcube.portal.social.networking.swagger.config.Bootstrap; -import org.gcube.portal.social.networking.swagger.config.SwaggerConstants; import org.gcube.portal.social.networking.ws.outputs.ResponseBean; import org.gcube.portal.social.networking.ws.utils.ErrorMessages; import org.gcube.portal.social.networking.ws.utils.TokensUtils; @@ -39,19 +37,19 @@ import org.gcube.vomanagement.usermanagement.model.GCubeRole; import org.gcube.vomanagement.usermanagement.model.GCubeUser; import org.slf4j.LoggerFactory; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; -import io.swagger.annotations.Authorization; +import com.webcohesion.enunciate.metadata.rs.RequestHeader; +import com.webcohesion.enunciate.metadata.rs.RequestHeaders; +import com.webcohesion.enunciate.metadata.rs.ResponseCode; +import com.webcohesion.enunciate.metadata.rs.StatusCodes; /** * REST interface for the social networking library (users). - * @author Costantino Perciante at ISTI-CNR */ @Path("2/users") -@Api(value=SwaggerConstants.USERS, authorizations={@Authorization(value = Bootstrap.GCUBE_TOKEN_IN_QUERY_DEF), @Authorization(value = Bootstrap.GCUBE_TOKEN_IN_HEADER_DEF)}) +@RequestHeaders ({ + @RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"), + @RequestHeader( name = "Content-Type", description = "application/json") + }) public class Users { // Logger @@ -62,16 +60,20 @@ public class Users { @GET @Path("get-custom-attribute/") @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Read a user's custom attribute", notes="Read a user's custom attribute. The user is the one owning the token", - response=ResponseBean.class, nickname="get-custom-attribute") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "Successful read of the attribute, reported in the 'result' field of the returned object", response = ResponseBean.class), - @ApiResponse(code = 404, message = "Such an attribute doesn't exist", response = ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) + @StatusCodes ({ + @ResponseCode ( code = 200, condition = "Successful read of the attribute, reported in the 'result' field of the returned object"), + @ResponseCode ( code = 404, condition = "Such an attribute doesn't exist"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) + /** + * Read a user's custom attribute. The user is the one owning the token + * @param attributeKey The key of the attribute to be read + * @return the user's custom attribute + * @throws ValidationException + */ public Response readCustomAttr( @QueryParam("attribute") @NotNull(message="attribute name is missing") - @ApiParam(name="attribute", required=true, allowMultiple=false, value="The key of the attribute to be read") String attributeKey ) throws ValidationException { @@ -104,69 +106,18 @@ public class Users { return Response.status(status).entity(responseBean).build(); } - // @PUT - // @Path("update-custom-attribute") - // @Consumes(MediaType.APPLICATION_JSON) - // @Produces(MediaType.APPLICATION_JSON) - // @ApiOperation(value = "Update a user's custom attribute", notes="Update a user's custom attribute. The user is the one owning the token", - // response=ResponseBean.class, nickname="update-custom-attribute") - // @ApiResponses(value = { - // @ApiResponse(code = 200, message = "Successful update of the attribute, the new value is reported in the 'result' field of the returned object", response = ResponseBean.class), - // @ApiResponse(code = 400, message = "Key or value for the new attribute missing", response=ResponseBean.class), - // @ApiResponse(code = 500, message = ErrorMessages.errorMessageApiResult, response=ResponseBean.class), - // @ApiResponse(code = 304, message = "Attribute not modified", response=ResponseBean.class)}) - // public Response updateCustomAttr( - // @NotNull(message="input is missing") - // @ApiParam(name="input", required=true, allowMultiple=false, value="The object having an attribute key and a value key for the new value") - // String inputJsonObj - // ) throws ValidationException{ - // - // Caller caller = AuthorizationProvider.instance.get(); - // String username = caller.getClient().getId(); - // ResponseBean responseBean = new ResponseBean(); - // Status status = Status.OK; - // - // try{ - // - // // Jackson parser - // ObjectMapper mapper = new ObjectMapper(); - // JsonNode actualObj = mapper.readTree(inputJsonObj); - // String attributeKey = actualObj.get("attribute").asText(); - // String newValue = actualObj.get("value").asText(); - // - // if(attributeKey == null || attributeKey.isEmpty() || newValue == null){ - // - // logger.error("Missing/wrong request parameters"); - // status = Status.BAD_REQUEST; - // responseBean.setMessage(ErrorMessages.missingParameters); - // return Response.status(status).entity(responseBean).build(); - // - // } - // - // GCubeUser user = userManager.getUserByUsername(username); - // userManager.saveCustomAttr(user.getUserId(), attributeKey, newValue); - // responseBean.setSuccess(true); - // responseBean.setResult(newValue); - // - // }catch(Exception e){ - // - // logger.error("Unable to set attribute for user.", e); - // status = Status.NOT_MODIFIED; - // responseBean.setMessage(e.toString()); - // - // } - // - // return Response.status(status).entity(responseBean).build(); - // } @GET @Path("get-fullname") @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Read the user's fullname", notes="Read the user's fullname. The user is the one owning the token", - response=ResponseBean.class, nickname="get-fullname") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "The user's fullname is reported in the 'result' field of the returned object", response = ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) + @StatusCodes ({ + @ResponseCode ( code = 200, condition = "The user's fullname is reported in the 'result' field of the returned object"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) + /** + * Read the user's fullname. The user is the one owning the token + * @return the user's fullname + */ public Response getUserFullname(){ Caller caller = AuthorizationProvider.instance.get(); @@ -202,11 +153,14 @@ public class Users { @GET @Path("get-email") @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Read the user's email address", notes="Read the user's email address. The user is the one owning the token", - response=ResponseBean.class, nickname="get-email") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "The user's email value is reported in the 'result' field of the returned object", response = ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) + @StatusCodes ({ + @ResponseCode ( code = 200, condition = "The user's email is reported in the 'result' field of the returned object"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) + /** + * Read the user's email address. The user is the one owning the token + * @return rhe user's email address + */ public Response getUserEmail(){ Caller caller = AuthorizationProvider.instance.get(); @@ -237,14 +191,18 @@ public class Users { return Response.status(status).entity(responseBean).build(); } + /** + * Get the profile associated to the token + * @responseExample application/json { "success" : true, "message" : null, "result" : { "user_id" : 23769487, "username" : "john.smith", "email" : "********", "first_name" : "John", "middle_name" : "", "last_name" : "Smith", "fullname" : "John Smith", "registration_date" : 1475151491415, "user_avatar_url" : "https://******D", "male" : true, "job_title" : "", "location_industry" : "no", "custom_attrs_map" : null, "email_addresses" : [ ], "screen_name" : "john.smith", "user_avatar_id" : "https://****sY%3D" } } + * @return the user's profile. The user is the one owning the token + */ @GET @Path("get-profile") @Produces(MediaType.APPLICATION_JSON) - @ApiOperation(value = "Read the user's profile", notes="Read the user's profile. The user is the one owning the token", - response=ResponseBean.class, nickname="get-profile") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "The user's profile is reported in the 'result' field of the returned object", response = ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) + @StatusCodes ({ + @ResponseCode ( code = 200, condition = "The user's profile is reported in the 'result' field of the returned object"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) public Response getUserProfile(){ Caller caller = AuthorizationProvider.instance.get(); @@ -294,6 +252,23 @@ public class Users { } }; + /** + * @responseExample application/json { + "id": "john.smith", + "roles": [], + "picture": "https://***gAJ4uVWTA74xwQ6%2FCA72RRinysY%3D", + "name": "John Smith", + "middle_name": "", + "male": true, + "location_industry": "no", + "given_name": "John", + "email": "******", + "job_title": "", + "family_name": "Smith", + "verified_email": true +} + * @return the user's profile compliant with oauth + */ @GET @Path("get-oauth-profile") @Produces(MediaType.APPLICATION_JSON) @@ -335,15 +310,25 @@ public class Users { return Response.status(status).entity(userWithEmailVerified).build(); } - + /** + * @responseExample application/json { + "success": true, + "message": null, + "result": [ + "john.smith", + "marco.polo" + ] +} + * Get the list of usernames belonging to a given context + * @return the list of usernames for the user belonging to the context linked to the provided auth token + */ @GET @Path("get-all-usernames") - @ApiOperation(value = "Get the list of usernames belonging to a given context", notes="Retrieve the list of usernames for the user belonging to the context linked to the provided token.", - response=ResponseBean.class, nickname="get-all-usernames") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "The list of usernames is put into the 'result' field of the returned object", response = ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) @Produces(MediaType.APPLICATION_JSON) + @StatusCodes ({ + @ResponseCode ( code = 200, condition = "The list of usernames is put into the 'result' field of the returned object"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) public Response getAllUserNames(){ ResponseBean responseBean = new ResponseBean(); @@ -383,14 +368,17 @@ public class Users { return Response.status(status).entity(responseBean).build(); } - + + /** + * Get the map of couples username/fullname of the users belonging to a given context + * @return the map of couples username/fullname of the users belonging to the context linked to the provided token. + */ @GET @Path("get-all-fullnames-and-usernames") - @ApiOperation(value = "Get the map of couples username/fullname of the users belonging to a given context", notes="Get the map of couples username/fullname of the users belonging to the context linked to the provided token.", - response=ResponseBean.class, nickname="get-all-fullnames-and-usernames") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "The map is put into the 'result' field of the returned object", response = ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) + @StatusCodes ({ + @ResponseCode ( code = 200, condition = "The map is put into the 'result' field of the returned object"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) @Produces(MediaType.APPLICATION_JSON) public Response getFullnamesAndUsernames(){ @@ -432,16 +420,19 @@ public class Users { return Response.status(status).entity(responseBean).build(); } + /** + * Get the list of users having a given global-role, e.g. 'Administrator'. (Legacy) + * @param roleName the name of the role to be checked (e.g. Administrator) + * @return the list of users having a given global-role + */ @GET @Path("get-usernames-by-global-role") - @ApiOperation(value = "Get the list of users having a given global-role", notes="Get the list of users having a given global-role, e.g. 'Administrator'.", - response=ResponseBean.class, nickname="get-usernames-by-global-role") - @ApiResponses(value = { - @ApiResponse(code = 200, message = "The list is put into the 'result' field of the returned object", response = ResponseBean.class), - @ApiResponse(code = 500, message = ErrorMessages.ERROR_IN_API_RESULT, response=ResponseBean.class)}) @Produces(MediaType.APPLICATION_JSON) + @StatusCodes ({ + @ResponseCode ( code = 200, condition = "The list is put into the 'result' field of the returned object"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) public Response getUsernamesByGlobalRole( - @ApiParam(value = "role-name: the name of the role to be checked (e.g. Administrator)", required = true) @QueryParam("role-name") String roleName){ ResponseBean responseBean = new ResponseBean(); @@ -482,12 +473,24 @@ public class Users { return Response.status(status).entity(responseBean).build(); } + /** + * @pathExample /get-usernames-by-role?role-name=VRE-Manager + * @param roleName the role name + * @return the usernames having the role in the VRE + * @responseExample application/json { + "success": true, + "message": null, + "result": [ + "john.smith", + "marco.polo" + ] +} + */ @GET @Path("get-usernames-by-role") @Produces(MediaType.APPLICATION_JSON) public Response getUsernamesByRole( @QueryParam("role-name") String roleName){ - ResponseBean responseBean = new ResponseBean(); Status status = Status.OK; String context = ScopeProvider.instance.get(); @@ -539,6 +542,7 @@ public class Users { @GET @Path("user-exists") @Produces(MediaType.APPLICATION_JSON) + @Deprecated public Response existUser(@QueryParam("username") String username){ ResponseBean responseBean = new ResponseBean(); diff --git a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/VREs.java b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/VREs.java index 6efa424..3a374c6 100644 --- a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/VREs.java +++ b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/VREs.java @@ -1,8 +1,5 @@ package org.gcube.portal.social.networking.ws.methods.v2; -import io.swagger.annotations.Api; -import io.swagger.annotations.Authorization; - import java.util.List; import javax.validation.ValidationException; @@ -20,8 +17,6 @@ import org.gcube.common.authorization.library.utils.Caller; import org.gcube.portal.social.networking.liferay.ws.GroupManagerWSBuilder; import org.gcube.portal.social.networking.liferay.ws.RoleManagerWSBuilder; import org.gcube.portal.social.networking.liferay.ws.UserManagerWSBuilder; -import org.gcube.portal.social.networking.swagger.config.Bootstrap; -import org.gcube.portal.social.networking.swagger.config.SwaggerConstants; import org.gcube.portal.social.networking.ws.outputs.ResponseBean; import org.gcube.portal.social.networking.ws.utils.TokensUtils; import org.gcube.vomanagement.usermanagement.GroupManager; @@ -34,18 +29,42 @@ import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.slf4j.LoggerFactory; +import com.webcohesion.enunciate.metadata.rs.RequestHeader; +import com.webcohesion.enunciate.metadata.rs.RequestHeaders; + /** * REST interface for the social networking library (vres). - * @author Costantino Perciante at ISTI-CNR */ @Path("2/vres") -@Api(value=SwaggerConstants.VRES, authorizations={@Authorization(value = Bootstrap.GCUBE_TOKEN_IN_QUERY_DEF), @Authorization(value = Bootstrap.GCUBE_TOKEN_IN_HEADER_DEF)}) +@RequestHeaders ({ + @RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"), + @RequestHeader( name = "Content-Type", description = "application/json") + }) public class VREs { // Logger private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Users.class); + /** + * @responseExample application/json { + "success" : true, + "message" : null, + "result" : [ { + "name" : "NextNext", + "context" : "/gcube/devNext/NextNext", + "description" : "NextNext description AAA" + }, { + "name" : "devVRE", + "context" : "/gcube/devsec/devVRE", + "description" : "devVRE description BBB" + } ] +} + * @pathExample /get-my-vres?getManagers=false + * @param getManagers set true if you also want to know the VRE-Managers + * @return the list of vres along with some metadata + * @throws ValidationException + */ @SuppressWarnings("unchecked") @GET @Path("get-my-vres/") diff --git a/src/main/java/org/gcube/portal/social/networking/ws/outputs/ResponseBean.java b/src/main/java/org/gcube/portal/social/networking/ws/outputs/ResponseBean.java index 7a89c25..ff52f26 100644 --- a/src/main/java/org/gcube/portal/social/networking/ws/outputs/ResponseBean.java +++ b/src/main/java/org/gcube/portal/social/networking/ws/outputs/ResponseBean.java @@ -1,27 +1,26 @@ package org.gcube.portal.social.networking.ws.outputs; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; - import java.io.Serializable; /** * Response bean - * @author Costantino Perciante at ISTI-CNR - * (costantino.perciante@isti.cnr.it) * */ -@ApiModel(description="A response object", value="Response") public class ResponseBean implements Serializable { private static final long serialVersionUID = -2725238162673879658L; - @ApiModelProperty(value="The result of the request: true if it succeeded, false otherwise") + /** + * The result of the request: true if it succeeded, false otherwise + */ private boolean success; - @ApiModelProperty(value="An error message if something wrong happened, null/empty otherwise") + /** + * An error message if something wrong happened, null/empty otherwise + */ private String message; - - @ApiModelProperty(value="The result object of the request") + /** + * The result object of the request + */ private Object result; public ResponseBean() { diff --git a/src/main/resources/META-INF/enunciate/d4science_docs.fmt b/src/main/resources/META-INF/enunciate/d4science_docs.fmt new file mode 100644 index 0000000..a5ee6ab --- /dev/null +++ b/src/main/resources/META-INF/enunciate/d4science_docs.fmt @@ -0,0 +1,1183 @@ +[#ftl] +[#-- + + Copyright © 2006-2016 Web Cohesion (info@webcohesion.com) + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--] +[#-- @ftlvariable name="resourceApis" type="java.util.List" --] +[#-- @ftlvariable name="serviceApis" type="java.util.List" --] +[#-- @ftlvariable name="data" type="java.util.List" --] +[#-- @ftlvariable name="downloads" type="java.util.List" --] +[#-- @ftlvariable name="title" type="java.lang.String" --] +[#-- @ftlvariable name="indexPageName" type="java.lang.String" --] +[#-- @ftlvariable name="disableMountpoint" type="java.lang.Boolean" --] +[#-- @ftlvariable name="disableResourceLinks" type="java.lang.Boolean" --] +[#-- @ftlvariable name="apiRelativePath" type="java.lang.String" --] +[#-- @ftlvariable name="cssFile" type="java.lang.String" --] +[#-- @ftlvariable name="additionalCssFiles" type="java.util.List" --] +[#-- @ftlvariable name="copyright" type="java.lang.String" --] +[#-- @ftlvariable name="apiDoc" type="java.lang.String" --] +[#-- @ftlvariable name="swaggerUI" type="com.webcohesion.enunciate.api.InterfaceDescriptionFile" --] +[#-- @ftlvariable name="favicon" type="java.lang.String" --] +[#-- @ftlvariable name="includeApplicationPath" type="java.lang.Boolean" --] +[#-- @ftlvariable name="includeDataTypesHomeIndex" type="java.lang.Boolean" --] +[#--set up the subnavigation menus--] +[#assign nav_sections = { } /] +[#if resourceApis?size > 0] + [#assign nav_sections = nav_sections + { "Resources" : "resources.html" }/] +[/#if] +[#if serviceApis?size > 0] + [#assign nav_sections = nav_sections + { "Services" : "services.html" }/] +[/#if] +[#if data?size > 0] + [#list data as syntax] + [#assign nav_sections = { syntax.label : syntax.slug + ".html" } /] + [/#list] +[/#if] +[#if downloads?size > 0] + [#assign nav_sections = nav_sections + { "Files and Libraries" : "downloads.html"} /] +[/#if] +[#--Basic boilerplate macro.--] +[#macro boilerplate title=title breadcrumbs=[{"title" : "Home", "href" : indexPageName}] pagenav=[] codeblocks=true] + + + + + + + + + ${title} + + + + + + + + [#if cssFile??] + + + [/#if] + [#list additionalCssFiles as additionalCssFile] + + [/#list] + [#if favicon??] + + + [/#if] + + + + + + +
+ D4Science + D4Science + + Don't have a D4Science account? + + Create one + + Could not find what you are looking for? + + Contact us. +
+ + + +
+
+ + +
+ + + [#nested/] + +
+
+

[#if copyright??]Copyright © ${copyright}. [/#if]Generated by Enunciate.

+
+
+ +
+
+
+ + + + + + + + + + + + + + +[/#macro] +[#--Macro that wraps its text in a deprecated tag if the element is deprecated.--] +[#macro deprecation element] + [#assign deprecated=(element?? && element.deprecated??)/] + [#if deprecated][/#if][#nested/][#if deprecated][/#if] +[/#macro] +[@file name=indexPageName] + [#assign pagenav=[]/] + [#if resourceApis?size > 0] + [#assign pagenav=pagenav + [{ "href" : "#resources", "title" : "Resources" }]/] + [/#if] + [#if serviceApis?size > 0] + [#assign pagenav=pagenav + [{ "href" : "#services", "title" : "Services" }]/] + [/#if] + [#list data as syntax] + [#assign pagenav=pagenav + [{ "href" : "#" + syntax.slug, "title" : syntax.label }]/] + [/#list] + [@boilerplate pagenav=pagenav] + [#if apiDoc??] + + [/#if] + [#if resourceApis?size > 0] + +

Resources

+ [#list resourceApis as resourceApi] + [#if downloads?size > 0] + +

+ The resources use a data model that is supported by a set of client-side libraries that are made available on the + files and libraries page. +

+ [/#if] + [#if resourceApi.wadlFile??] + +

+ There is a WADL document available that describes the resources API. +

+ [/#if] + [#if swaggerUI??] + +

+ You may also enjoy the interactive interface provided for this API by Swagger. +

+

+ Try it out! +

+ [/#if] + + + + + [#if resourceApi.includeResourceGroupName!false] + + [/#if] + + + + + + + [#list resourceApi.resourceGroups as resourceGroup] + [@processResourceGroup resourceGroup=resourceGroup/] + + [#if resourceApi.includeResourceGroupName!false] + + [/#if] + + + + + [/#list] + +
namepathmethodsdescription
[@deprecation element=resourceGroup]${resourceGroup.label}[/@deprecation]
    [#list resourceGroup.paths as path]
  • [@deprecation element=resourceGroup][#if ((includeApplicationPath!false) && (resourceGroup.relativeContextPath?has_content))]/${resourceGroup.relativeContextPath}[/#if]${path.path}[/@deprecation]
  • [/#list]
    [#list resourceGroup.paths as path]
  • [@deprecation element=resourceGroup][#list path.methods as method]${method} [/#list][/@deprecation]
  • [/#list]
[@deprecation element=resourceGroup]${resourceGroup.description!" "}[/@deprecation]
+ [/#list] + [/#if] + [#if serviceApis?size > 0] + +

Services

+ [#list serviceApis as serviceApi] + [#list serviceApi.serviceGroups as serviceGroup] + + + + + + + + + + + [#list serviceGroup.services as service] + [@processService service=service/] + + + + + [/#list] + +
Namespace ${serviceGroup.namespace!"(Default)"}[#if serviceGroup.wsdlFile??] (wsdl)[/#if]
namedescription
[@deprecation element=service]${service.label}[/@deprecation][@deprecation element=service]${service.description!" "}[/@deprecation]
+ [/#list] + [/#list] + [#if downloads?size > 0] + +

The services API is also accessible by a set of client-side libraries that can be downloaded from the files and libraries page.

+ [/#if] + [/#if] + [#if data?size > 0 && includeDataTypesHomeIndex] + +

Data Types

+ [#list data as syntax] + [@processDataSyntax syntax=syntax/] + +

${syntax.label}

+ [#list syntax.namespaces as ns] + [#if ns.types?size > 0] + + + [#if ns.uri??] + [#if ns.uri?length > 0] + + [#else] + + [/#if] + [/#if] + + + + + + + + [#list ns.types as type] + + + + + [/#list] + +
Namespace ${ns.uri}[#if ns.schemaFile??] (schema)[/#if]Default Namespace [#if ns.schemaFile??] (schema)[/#if]
typedescription
[@deprecation element=type]${type.label}[/@deprecation][@deprecation element=type]${type.description}[/@deprecation]
+ [/#if] + [/#list] + [/#list] + [#elseif data?size > 0] + [#list data as syntax] + [@processDataSyntax syntax=syntax/] + [/#list] + [/#if] + [/@boilerplate] +[/@file] +[@file name="data.html"] + [#assign pagenav=[]/] + [#list data as syntax] + [#assign pagenav=pagenav + [{ "href" : "#" + syntax.slug, "title" : syntax.label }]/] + [/#list] + [@boilerplate title=title + ": Data Types" breadcrumbs=[{"title" : "Home", "href" : indexPageName}, {"title" : "Data Types" , "href" : "data.html"}] pagenav=pagenav] +

Data Types

+ [#list data as syntax] + +

${syntax.label}

+ [#list syntax.namespaces as ns] + [#if ns.types?size > 0] + + + [#if ns.uri??] + [#if ns.uri?length > 0] + + [#else] + + [/#if] + [/#if] + + + + + + + + [#list ns.types as type] + + + + + [/#list] + +
Namespace ${ns.uri}[#if ns.schemaFile??] (schema)[/#if]Default Namespace [#if ns.schemaFile??] (schema)[/#if]
typedescription
[@deprecation element=type]${type.label}[/@deprecation][@deprecation element=type]${type.description}[/@deprecation]
+ [/#if] + [/#list] + [/#list] + [/@boilerplate] +[/@file] +[#if downloads?size > 0] + [@file name="downloads.html"] + [#assign pagenav=[]/] + [#list downloads as download] + [#assign pagenav=pagenav + [{ "href" : "#" + download.slug, "title" : download.name }]/] + [/#list] + [@boilerplate title=title + ": Files and Libraries" breadcrumbs=[{"title" : "Home", "href" : indexPageName}, { "title" : "Files and Libraries" , "href" : "downloads.html"}] codeblocks=true pagenav=pagenav] +

Files and Libraries

+ + [#list downloads as download] +

${download.name}

+ [#if download.created??] +

Created ${download.created?date?string.long}

+ [/#if] + [#if download.artifactId??] +
+ [#if download.groupId??] +
groupId
+
${download.groupId}
+ [/#if] + [#if download.artifactId??] +
artifactId
+
${download.artifactId}
+ [/#if] + [#if download.version??] +
version
+
${download.version}
+
+ [/#if] + [/#if] + [#if download.description??] +

${download.description}

+ [/#if] + + + + + + + + + + + [#list download.files as file] + + + + + + [/#list] + +
Files
namesizedescription
${file.name}${file.size}${file.description!download.description!" "}
+ [/#list] + [/@boilerplate] + [/@file] +[/#if] +[#if resourceApis?size > 0] + [@file name="resources.html"] + [@boilerplate title=title + ": Resources" breadcrumbs=[{"title" : "Home", "href" : indexPageName}, {"title" : "Resources" , "href" : "resources.html"}]] +

Resources

+ + [#list resourceApis as resourceApi] + [#if downloads?size > 0] +

+ The resources use a data model that is supported by a set of client-side libraries that are made available on the + files and libraries page. +

+ [/#if] + [#if resourceApi.wadlFile??] +

+ There is a WADL document available that describes the resources API. +

+ [/#if] + [#if swaggerUI??] +

+ You may also enjoy the interactive interface provided for this API by Swagger. +

+

+ Try it out! +

+ [/#if] + + + + [#if resourceApi.includeResourceGroupName!false] + + [/#if] + + + + + + + [#list resourceApi.resourceGroups as resourceGroup] + + [#if resourceApi.includeResourceGroupName!false] + + [/#if] + + + + + [/#list] + +
namepathmethodsdescription
[@deprecation element=resourceGroup]${resourceGroup.label}[/@deprecation]
    [#list resourceGroup.paths as path]
  • [@deprecation element=resourceGroup][#if ((includeApplicationPath!false) && (resourceGroup.relativeContextPath?has_content))]/${resourceGroup.relativeContextPath}[/#if]${path.path}[/@deprecation]
  • [/#list]
    [#list resourceGroup.paths as path]
  • [@deprecation element=resourceGroup][#list path.methods as method]${method} [/#list][/@deprecation]
  • [/#list]
[@deprecation element=resourceGroup]${resourceGroup.description!" "}[/@deprecation]
+ [/#list] + [/@boilerplate] + [/@file] +[/#if] +[#if serviceApis?size > 0] + [@file name="services.html"] + [@boilerplate title=title + ": Services" breadcrumbs=[{"title" : "Home", "href" : indexPageName}, {"title" : "Services" , "href" : "services.html"}]] +

Services

+ [#list serviceApis as serviceApi] + [#list serviceApi.serviceGroups as serviceGroup] + + + + + + + + + + + [#list serviceGroup.services as service] + + + + + [/#list] + +
Namespace ${serviceGroup.namespace}[#if serviceGroup.wsdlFile??] (wsdl)[/#if]
namedescription
[@deprecation element=service]${service.label}[/@deprecation][@deprecation element=service]${service.description!" "}[/@deprecation]
+ [/#list] + [/#list] + [#if downloads?size > 0] + +

The services API is also accessible by a set of client-side libraries that can be downloaded from the files and libraries page.

+ [/#if] + [/@boilerplate] + [/@file] +[/#if] +[#macro processResourceGroup resourceGroup] + [#assign pagenav=[]/] + [#list resourceGroup.resources as resource] + [#list resource.methods as method] + [#assign path=resource.path/] + [#if ((includeApplicationPath!false) && (resourceGroup.relativeContextPath?has_content))] + [#assign path="/" + resourceGroup.relativeContextPath + resource.path/] + [/#if] + [#assign pagenav=pagenav + [{ "href" : "#" + method.slug, "title" : method.label + " " + path }]/] + [/#list] + [/#list] + [#-- @ftlvariable name="resourceGroup" type="com.webcohesion.enunciate.api.resources.ResourceGroup" --] + [@file name=resourceGroup.slug + ".html"] + [@boilerplate title=title + ": " + resourceGroup.label breadcrumbs=[{"title" : "Home", "href" : indexPageName}, {"title" : "Resources" , "href" : "resources.html"}, {"title" : resourceGroup.label , "href" : resourceGroup.slug + ".html"}] pagenav=pagenav] +

${resourceGroup.label} Resource

+ [#if resourceGroup.description??] + +

${resourceGroup.description}

+ [/#if] + [#list resourceGroup.resources as resource] + [#if resource.since?? || resource.version?? || resource.seeAlso??] + +
+ [#if resource.since??] +
Available Since
+
${resource.since}
+ [/#if] + [#if resource.version??] +
Version
+
${resource.version}
+ [/#if] + [#if resource.seeAlso??] + [#list resource.seeAlso as seeAlso] +
See Also
+
${seeAlso}
+ [/#list] + [/#if] +
+ [/#if] + [#list resource.methods as method] + +
+

${method.label} [#if ((includeApplicationPath!false) && (resourceGroup.relativeContextPath?has_content))]/${resourceGroup.relativeContextPath}[/#if]${resource.path}[#if !disableResourceLinks!false] [/#if]

+ [#if resourceGroup.deprecated?? || method.deprecated??] + +
This method has been deprecated. [#if method.deprecated??] ${method.deprecated!""}[#else] ${resource.deprecated!""}[/#if]
+ [/#if] + [#if method.description??] + +

${method.description}

+ [/#if] + [#-- would be nice to enable a "Try it out" link to Swagger. See https://github.com/swagger-api/swagger-spec/issues/239 + [#if swaggerUI??] + +

Try it out!

+ [/#if] + --] + [#assign securityRoles=method.securityRoles![]/] + [#if (method.since?? || method.version?? || method.seeAlso?? || securityRoles?size > 0)] + +
+ [#if method.since??] +
Available Since
+
${method.since}
+ [/#if] + [#if method.version??] +
Version
+
${method.version}
+ [/#if] + [#if securityRoles?size > 0] +
Security Roles Allowed
+
[#list securityRoles as role]${role}[#if role_has_next], [/#if][/#list]
+ [/#if] + [#if method.seeAlso??] + [#list method.seeAlso as seeAlso] +
See Also
+
${seeAlso}
+ [/#list] + [/#if] +
+ [/#if] + [#if method.parameters?size > 0] + + + + + + + + + [#assign includeDefault=method.includeDefaultParameterValues/] + [#if includeDefault] + + [/#if] + [#assign includeConstraints=method.hasParameterConstraints/] + [#if includeConstraints] + + [/#if] + [#assign includeMultiplicity=method.hasParameterMultiplicity/] + [#if includeMultiplicity] + + [/#if] + + + + [#list method.parameters as parameter] + + + + + [#if includeDefault] + + [/#if] + [#if includeConstraints] + + [/#if] + [#if includeMultiplicity] + + [/#if] + + [/#list] + +
Request Parameters
nametypedescriptiondefaultconstraintsmultivalued
${parameter.name}${parameter.typeLabel}${parameter.description!" "}${parameter.defaultValue!" "}${parameter.constraints!" "}${parameter.multivalued?string("yes", "no")}
+ [/#if] + [#if method.requestEntity??] + + + + + + + + [#if method.requestEntity.description??] + + [/#if] + + + + [#list method.requestEntity.mediaTypes as io] + + + + [#if io_index = 0 && method.requestEntity.description??] + 1] rowspan="${method.requestEntity.mediaTypes?size}" class="multi-row-description"[/#if]>${method.requestEntity.description} + [/#if] + + [/#list] + +
Request Body
media typedata typedescription
${io.mediaType}[@referenceDataType referenceType=io.dataType!{"label" : "(custom)"}/][#if io.syntax??] (${io.syntax})[/#if]
+ [/#if] + [#if method.responseCodes?size > 0] + + + + + + + + [#assign hasExpectedTypes=false/] + [#list method.responseCodes as responseCode] + [#if responseCode.mediaTypes?size > 0] + [#assign hasExpectedTypes=true/] + [/#if] + [/#list] + [#if hasExpectedTypes] + + [/#if] + + + + [#list method.responseCodes as responseCode] + + + + [#if hasExpectedTypes] + + [/#if] + + [/#list] + +
Response Codes
codeconditiontype
${responseCode.code}${responseCode.condition!""}
    [#list responseCode.mediaTypes as io]
  • [@referenceDataType referenceType=io.dataType!{"label" : "(custom)"}/][#if io.syntax??] (${io.syntax})[/#if]
  • [/#list]
+ [/#if] + [#if method.responseEntity??] + + + + + + + + [#if method.responseEntity.description??] + + [/#if] + + + + [#list method.responseEntity.mediaTypes as io] + + + + [#if io_index = 0 && method.responseEntity.description??] + 1] rowspan="${method.responseEntity.mediaTypes?size}" class="multi-row-description"[/#if]>${method.responseEntity.description} + [/#if] + + [/#list] + +
Response Body
media typedata typedescription
${io.mediaType}[@referenceDataType referenceType=io.dataType!{"label" : "(custom)"}/][#if io.syntax??] (${io.syntax})[/#if]
+ [/#if] + [#if method.warnings?size > 0] + + + + + + + + + + + [#list method.warnings as responseCode] + + + + + [/#list] + +
Response Warnings
codecondition
${responseCode.code}${responseCode.condition!""}
+ [/#if] + [#if method.responseHeaders?size > 0] + + + + + + + + + + + [#list method.responseHeaders as header] + + + + + [/#list] + +
Response Headers
namedescription
${header.name}${header.description!" "}
+ + [/#if] + [#if method.example??] +

Example

+ +
+
+
+
Request
+
+${method.example.requestHeaders?xhtml}
+            [#if method.example.requestLang??]
+                
+${method.example.requestBody?xhtml}
+                
+            [/#if]
+              
+
+
+
Response
+
+${method.example.responseHeaders?xhtml}
+            [#if method.example.responseLang??]
+                
+${method.example.responseBody?xhtml}
+                
+            [/#if]
+              
+
+
+
+ [/#if] +
+ [/#list] + [/#list] + [/@boilerplate] + [/@file] +[/#macro] +[#macro processService service] + [#assign pagenav=[]/] + [#list service.operations as operation] + [#assign pagenav=pagenav + [{ "href" : "#" + operation.slug, "title" : operation.name }]/] + [/#list] + [#-- @ftlvariable name="service" type="com.webcohesion.enunciate.api.services.Service" --] + [@file name=service.slug + ".html"] + [@boilerplate title=title + ": " + service.label breadcrumbs=[{"title" : "Home", "href" : indexPageName}, {"title" : service.label , "href" : service.slug + ".html"}] pagenav=pagenav] +

${service.label} Service

+ [#if service.deprecated??] + +
This service has been deprecated. ${service.deprecated}
+ [/#if] + [#if service.description??] + +

${service.description}

+ [/#if] + +
+ [#if service.namespace?? && service.namespace?length > 0] +
Namespace
+
${service.namespace}
+ [/#if] + [#if service.group.wsdlFile??] +
WSDL
+
${service.group.wsdlFile.href}
+ [/#if] + [#if service.path??] +
Path
+
${service.path}
+ [/#if] + [#if service.since??] +
Available Since
+
${service.since}
+ [/#if] + [#if service.version??] +
Version
+
${service.version}
+ [/#if] + [#if service.seeAlso??] + [#list service.seeAlso as seeAlso] +
See Also
+
${seeAlso}
+ [/#list] + [/#if] +
+ [#list service.operations as operation] + +

${operation.name} Operation

+ [#if operation.deprecated??] + +
This method has been deprecated. ${operation.deprecated}
+ [/#if] + [#if operation.description??] + +

${operation.description}

+ [/#if] + [#if (operation.since?? || operation.version?? || operation.seeAlso??)] + +
+ [#if operation.since??] +
Available Since
+
${operation.since}
+ [/#if] + [#if operation.version??] +
Version
+
${operation.version}
+ [/#if] + [#if operation.seeAlso??] + [#list operation.seeAlso as seeAlso] +
See Also
+
${seeAlso}
+ [/#list] + [/#if] +
+ [/#if] + [#if operation.inputParameters?size > 0] + + + + + + + + + + + + [#list operation.inputParameters as parameter] + + + + + + [/#list] + +
Input Parameters
nametypedescription
${parameter.name}[@referenceDataType referenceType=parameter.dataType/]${parameter.description!" "}
+ [/#if] + [#if operation.httpRequestHeaders?size > 0] + + + + + + + + + + + + [#list operation.httpRequestHeaders as parameter] + + + + + + [/#list] + +
HTTP Request Headers
nametypedescription
${parameter.name}[@referenceDataType referenceType=parameter.dataType/]${parameter.description!" "}
+ [/#if] + [#if operation.outputParameters?size > 0] + + + + + + + + + + + + [#list operation.outputParameters as parameter] + + + + + + [/#list] + +
Output Parameters
nametypedescription
${parameter.name}[@referenceDataType referenceType=parameter.dataType/]${parameter.description!" "}
+ [/#if] + [#if operation.returnType??] + + + + + + + + + + + + + + + +
Return Value
typedescription
[@referenceDataType referenceType=operation.returnType/]${operation.returnDescription!" "}
+ [/#if] + [#if operation.faults?size > 0] + + + + + + + + + + + + [#list operation.faults as fault] + + + + + + [/#list] + +
Faults
nametypeconditions
${fault.name}[@referenceDataType referenceType=fault.dataType/]${fault.conditions!" "}
+ [/#if] + [/#list] + [/@boilerplate] + [/@file] +[/#macro] +[#macro processDataSyntax syntax] + [#-- @ftlvariable name="syntax" type="com.webcohesion.enunciate.api.datatype.Syntax" --] + [@file name=syntax.slug + ".html"] + [@boilerplate title=title + ": " + syntax.label breadcrumbs=[{"title" : "Home", "href" : indexPageName}, {"title" : syntax.label , "href" : syntax.slug + ".html"} ]] +

${syntax.label}

+ [#list syntax.namespaces as ns] + [#if ns.types?size > 0] + + + [#if ns.uri??] + [#if ns.uri?length > 0] + + [#else] + + [/#if] + [/#if] + + + + + + + + [#list ns.types as type] + [@processDataType type=type/] + + + + + [/#list] + +
Namespace ${ns.uri}[#if ns.schemaFile??] (schema)[/#if]Default Namespace [#if ns.schemaFile??] (schema)[/#if]
typedescription
[@deprecation element=type]${type.label}[/@deprecation][@deprecation element=type]${type.description}[/@deprecation]
+ [/#if] + [/#list] + [/@boilerplate] + [/@file] +[/#macro] +[#macro processDataType type] + [#-- @ftlvariable name="type" type="com.webcohesion.enunciate.api.datatype.DataType" --] + [#assign pagenav=[]/] + [#if type.values??] + [#list type.values as value] + [#assign pagenav=pagenav + [{ "href" : "#" + value.value, "title" : value.value }]/] + [/#list] + [/#if] + [@file name=type.slug + ".html"] + [@boilerplate title=title + ": " + type.label breadcrumbs=[{"title" : "Home", "href" : indexPageName}, {"title" : type.syntax.label , "href" : type.syntax.slug + ".html"}, {"title" : type.label , "href" : type.slug + ".html"} ] pagenav=pagenav codeblocks=true] +

${type.label} Data Type

+ [#if type.deprecated??] + +
This data type has been deprecated. ${type.deprecated}
+ [/#if] + [#if type.description??] + +

${type.description}

+ [/#if] + +
+ [#if type.namespace.uri??] +
Namespace
+ [#if type.namespace.uri?length > 0] +
${type.namespace.uri}
+ [#else] +
(Default)
+ [/#if] + [/#if] + [#if type.namespace.schemaFile??] +
Schema
+
${type.namespace.schemaFile.href}
+ [/#if] + [#if type.since??] +
Available Since
+
${type.since}
+ [/#if] + [#if type.version??] +
Version
+
${type.version}
+ [/#if] + [#if type.abstract] +
Abstract Type
+
+ [/#if] + [#if type.subtypes??] +
Subtypes
+
[#list type.subtypes as subtype][#if subtype.slug??]${subtype.label}[#else]${subtype.label}[/#if][#if subtype_has_next], [/#if][/#list]
+ [/#if] + [#if type.interfaces??] +
Implemented Interfaces
+
[#list type.interfaces as iface]${iface.label}[#if iface_has_next], [/#if][/#list]
+ [/#if] + [#if type.seeAlso??] + [#list type.seeAlso as seeAlso] +
See Also
+
${seeAlso}
+ [/#list] + [/#if] +
+ [#if type.values??] + + + + + + + + + + + [#list type.values as value] + + + + + [/#list] + +
Values
valuedescription
${value.value}[#if value.since??]since ${value.since} [/#if]${value.description!" "}
+ [/#if] + [#if type.properties??] + + + + + + + + [#list type.propertyMetadata?keys as meta] + + [/#list] + + + + + [#list type.properties as property] + + + + [#list type.propertyMetadata?keys as meta] + + [/#list] + + + [/#list] + + [#if type.supertypes??] + [#list type.supertypes as supertype] + [#if supertype.value?? && supertype.value.properties?? && supertype.value.properties?size > 0] + + + + + [#list supertype.value.properties as superProperty] + + + + [#list type.propertyMetadata?keys as meta] + + [/#list] + + + [/#list] + + [/#if] + [/#list] + [/#if] +
Properties
namedata type${type.propertyMetadata[meta]}description
[@deprecation element=property]${property.name}[/@deprecation][@deprecation element=property][@referenceDataType referenceType=property.dataType/][/@deprecation][@deprecation element=property][@printPropertyMetadata property=property meta=meta/][/@deprecation][@deprecation element=property][#if property.since??]since ${property.since} [/#if]${property.description!" "}[/@deprecation]
Properties inherited from ${supertype.label}
${superProperty.name}[@referenceDataType referenceType=superProperty.dataType/][@printPropertyMetadata property=superProperty meta=meta/][#if superProperty.since??]since ${superProperty.since} [/#if]${superProperty.description!" "}
+ [/#if] + [#if type.example??] + +

Example

+ [#if type.abstract && type.subtypes?? ] + +
This data type is abstract. The example below may be incomplete. More accurate examples can be found in subtypes pages.
+ [/#if] + +
${type.example.body?xhtml}
+ [/#if] + [/@boilerplate] + [/@file] +[/#macro] +[#macro referenceDataType referenceType] +[#-- @ftlvariable name="type" type="com.webcohesion.enunciate.api.datatype.DataTypeReference" --] +[#if referenceType.containers??][#list referenceType.containers as container]${container?string} of [/#list][/#if][#if referenceType.slug??][/#if]${referenceType.label!"(custom)"}[#if referenceType.slug??][/#if] +[/#macro] +[#macro printPropertyMetadata property meta] + [#assign metaValue=property[meta]!({ "structure" : true })/] + [#if metaValue?is_hash && metaValue.structure!false] +[#if metaValue.href??][/#if][#if metaValue.title??][/#if]${metaValue.value!" "}[#if metaValue.title??][/#if][#if metaValue.href??][/#if] + [#else] +${metaValue} + [/#if] +[/#macro] \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/gcube-app.xml b/src/main/webapp/WEB-INF/gcube-app.xml index 27ca951..4579edf 100644 --- a/src/main/webapp/WEB-INF/gcube-app.xml +++ b/src/main/webapp/WEB-INF/gcube-app.xml @@ -1,11 +1,8 @@ SocialNetworking Portal - 2.1.0-SNAPSHOT + 2.5.0-SNAPSHOT SocialNetworking Service - /rest/ - /rest/swagger.yaml - /rest/swagger.json - /rest/application.wadl + /docs/* \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index 9a8bd29..122f396 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -15,19 +15,12 @@ jersey.config.server.provider.packages - io.swagger.jaxrs.listing, org.gcube.portal.social.networking 1 - - SwaggerBootstrap - org.gcube.portal.social.networking.swagger.config.Bootstrap - 2 - - jersey-servlet /rest/* diff --git a/src/main/webapp/docs/css/d4science_enunciate_custom.css b/src/main/webapp/docs/css/d4science_enunciate_custom.css new file mode 100644 index 0000000..9dae183 --- /dev/null +++ b/src/main/webapp/docs/css/d4science_enunciate_custom.css @@ -0,0 +1,25 @@ +.d4science_intro { + top: 0; + z-index: 2000; + position: fixed; + display: block ruby; + padding: 10px; + background: white; + width: 100%; +} + +.navbar-fixed-top { + top: 100px !important; +} + +.sidebar { + top: 160px !important; +} + +.navbar { + margin-bottom: 40px !important; +} + +.main { + top: 90px; +} \ No newline at end of file