diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/CertificateManagementAdminService.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/CertificateManagementAdminService.java index e32571150d..6fed010f65 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/CertificateManagementAdminService.java +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/CertificateManagementAdminService.java @@ -344,46 +344,6 @@ public interface CertificateManagementAdminService { defaultValue = "12438035315552875930") @PathParam("serialNumber") String serialNumber); - @DELETE - @Path("/{serialNumber}/v2") - @ApiOperation( - consumes = MediaType.APPLICATION_JSON, - produces = MediaType.APPLICATION_JSON, - httpMethod = "DELETE", - value = "Deleting an SSL Certificate", - notes = "Delete an SSL certificate that's on the client end.", - tags = "Certificate Management", - extensions = { - @Extension(properties = { - @ExtensionProperty(name = SCOPE, value = "perm:admin:certificates:delete") - }) - } - ) - @ApiResponses(value = { - @ApiResponse( - code = 200, - message = "OK. \n Successfully removed the certificate."), - @ApiResponse( - code = 400, - message = "Bad Request. \n Invalid request or validation error.", - response = ErrorResponse.class), - @ApiResponse( - code = 404, - message = "Not Found. \n The specified resource does not exist."), - @ApiResponse( - code = 500, - message = "Internal Server Error. \n " + - "Server error occurred while removing the certificate.", - response = ErrorResponse.class)}) - Response removeCertificateDep( - @ApiParam( - name = "serialNumber", - value = "The serial number of the certificate.\n" + - "NOTE: Make sure that a certificate with the serial number you provide exists in the server. If not, first add a certificate.", - required = true, - defaultValue = "12438035315552875930") - @PathParam("serialNumber") String serialNumber); - /** * Verify Certificate for the API security filter * diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/impl/CertificateManagementAdminServiceImpl.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/impl/CertificateManagementAdminServiceImpl.java index ac7aacfa06..5957b1b8cf 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/impl/CertificateManagementAdminServiceImpl.java +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/impl/CertificateManagementAdminServiceImpl.java @@ -166,26 +166,6 @@ public class CertificateManagementAdminServiceImpl implements CertificateManagem } } - @DELETE - @Deprecated - @Path("/{serialNumber}/v2") - public Response removeCertificateDep(@PathParam("serialNumber") String serialNumber) { - RequestValidationUtil.validateSerialNumber(serialNumber); - - CertificateManagementService certificateService = CertificateMgtAPIUtils.getCertificateManagementService(); - try { - certificateService.removeCertificate(serialNumber); - return Response.status(Response.Status.OK).entity( - "Certificate that carries the serial number '" + - serialNumber + "' has been removed").build(); - } catch (CertificateManagementException e) { - String msg = "Error occurred while converting PEM file to X509Certificate"; - log.error(msg, e); - return Response.serverError().entity( - new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); - } - } - // @POST // @Path("/verify/ios") // public Response verifyIOSCertificate(@ApiParam(name = "certificate", value = "Mdm-Signature of the " + diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/pom.xml b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/pom.xml new file mode 100644 index 0000000000..f9c1d75ef5 --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/pom.xml @@ -0,0 +1,221 @@ + + + + + + + certificate-mgt + org.wso2.carbon.devicemgt + 3.0.185-SNAPSHOT + ../pom.xml + + + 4.0.0 + org.wso2.carbon.certificate.mgt.cert.admin.v09.api + war + WSO2 Carbon - Admin Certificate Management v09 API + WSO2 Carbon - Admin Certificate Management v09 API + http://wso2.org + + + + + maven-compiler-plugin + + 1.8 + 1.8 + + + + maven-war-plugin + + WEB-INF/lib/*cxf*.jar + api#certificate-mgt#v0.9 + + + + org.jacoco + jacoco-maven-plugin + + ${basedir}/target/coverage-reports/jacoco-unit.exec + + + + jacoco-initialize + + prepare-agent + + + + jacoco-site + test + + report + + + ${basedir}/target/coverage-reports/jacoco-unit.exec + ${basedir}/target/coverage-reports/site + + + + + + + + + + deploy + + compile + + + org.apache.maven.plugins + maven-antrun-plugin + 1.7 + + + compile + + run + + + + + + + + + + + + + + + + + + client + + test + + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + + test + + java + + + + + + + + + + + + org.apache.cxf + cxf-rt-frontend-jaxws + + + commons-codec.wso2 + commons-codec + + + commons-codec + commons-codec + + + + + org.apache.cxf + cxf-rt-frontend-jaxrs + + + org.apache.cxf + cxf-rt-transports-http + + + junit + junit + test + + + javax.ws.rs + jsr311-api + provided + + + org.wso2.carbon + org.wso2.carbon.logging + provided + + + org.wso2.carbon.devicemgt + org.wso2.carbon.certificate.mgt.core + provided + + + org.wso2.carbon.devicemgt + org.wso2.carbon.identity.jwt.client.extension + provided + + + io.swagger + swagger-annotations + + + io.swagger + swagger-core + + + org.slf4j + slf4j-api + + + + + io.swagger + swagger-jaxrs + + + org.slf4j + slf4j-api + + + + + javax.servlet + servlet-api + provided + + + org.wso2.carbon.devicemgt + org.wso2.carbon.apimgt.annotations + provided + + + + diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/CertificateManagementAdminService.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/CertificateManagementAdminService.java new file mode 100644 index 0000000000..f6cb69b0ec --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/CertificateManagementAdminService.java @@ -0,0 +1,417 @@ +/* + * + * Copyright (c) ${date}, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * / + */ + +package org.wso2.carbon.certificate.mgt.cert.jaxrs.api; + +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Info; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.Extension; +import io.swagger.annotations.Tag; +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.ResponseHeader; +import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans.CertificateList; +import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans.EnrollmentCertificate; +import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans.ErrorResponse; +import org.wso2.carbon.certificate.mgt.core.dto.CertificateResponse; + +import javax.validation.constraints.Size; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +@SwaggerDefinition( + info = @Info( + version = "0.9.0", + title = "", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "Certificate Management"), + @ExtensionProperty(name = "context", value = "/api/certificate-mgt/v0.9/admin/certificates"), + }) + } + ), + tags = { + @Tag(name = "device_management", description = "") + } +) +@Api(value = "Certificate Management", description = "This API includes all the certificate management related operations") +@Path("/admin/certificates") +@Scopes(scopes = { + @Scope( + name = "Adding a new SSL certificate", + description = "Adding a new SSL certificate", + key = "perm:admin:certificates:add", + permissions = {"/device-mgt/admin/certificates/add"} + ), + @Scope( + name = "Getting Details of an SSL Certificate", + description = "Getting Details of an SSL Certificate", + key = "perm:admin:certificates:details", + permissions = {"/device-mgt/admin/certificates/details"} + ), + @Scope( + name = "Getting Details of Certificates", + description = "Getting Details of Certificates", + key = "perm:admin:certificates:view", + permissions = {"/device-mgt/admin/certificates/view"} + ), + @Scope( + name = "Deleting an SSL Certificate", + description = "Deleting an SSL Certificate", + key = "perm:admin:certificates:delete", + permissions = {"/device-mgt/admin/certificates/delete"} + ), + @Scope( + name = "Verify SSL certificate", + description = "Verify SSL certificate", + key = "perm:admin:certificates:verify", + permissions = {"/device-mgt/admin/certificates/verify"} + ) +} +) +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public interface CertificateManagementAdminService { + + String SCOPE = "scope"; + + /** + * Save a list of certificates and relevant information in the database. + * + * @param enrollmentCertificates List of all the certificates which includes the tenant id, certificate as + * a pem and a serial number. + * @return Status of the data persist operation. + */ + @POST + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Adding a new SSL certificate", + notes = "Add a new SSL certificate to the client end database.\n", + tags = "Certificate Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:admin:certificates:add") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 201, + message = "Created. \n Successfully added the certificate.", + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "The URL of the added certificates."), + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests.")}), + @ApiResponse( + code = 303, + message = "See Other. \n The source can be retrieved from the URL specified in the location header.", + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "The Source URL of the document.")}), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 415, + message = "Unsupported Media Type. \n The format of the requested entity was not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while adding certificates.", + response = ErrorResponse.class) + }) + Response addCertificate( + @ApiParam( + name = "enrollmentCertificates", + value = "The properties to add a new certificate. It includes the following: \n" + + "serial: The unique ID of the certificate. \n" + + "pem: Convert the OpenSSL certificate to the .pem format and base 64 encode the file. \n" + + "INFO: Upload the .pem file and base 64 encode it using a tool, such as the base64encode.in tool.", + required = true) EnrollmentCertificate[] enrollmentCertificates); + + /** + * Get a certificate when the serial number is given. + * + * @param serialNumber serial of the certificate needed. + * @return certificate response. + */ + @GET + @Path("/{serialNumber}") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting Details of an SSL Certificate", + notes = "Get the client side SSL certificate details.", + tags = "Certificate Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:admin:certificates:details") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the certificate details.", + response = CertificateResponse.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n " + + "Empty body because the client already has the latest version of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified certificate does not exist."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving the requested certificate information.", + response = ErrorResponse.class) + }) + Response getCertificate( + @ApiParam(name = "serialNumber", + value = "The serial number of the certificate.", + required = true, + defaultValue = "124380353155528759302") + @PathParam("serialNumber") String serialNumber, + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time.\n" + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") String ifModifiedSince + ); + + /** + * Get all certificates in a paginated manner. + * + * @return paginated result of certificate. + */ + @GET + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting Details of Certificates", + notes = "Get all the details of the certificates you have used for mutual SSL. In a situation where you wish to " + + "view all the certificate details, it is not feasible to show all the details on one " + + "page. Therefore, the details are paginated.", + tags = "Certificate Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:admin:certificates:view") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the list of certificates.", + response = CertificateList.class, + responseContainer = "List", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests.")}), + @ApiResponse( + code = 303, + message = "See Other. \n " + + "The source can be retrieved from the URL specified in the location header.\n", + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "The Source URL of the document.")}), + @ApiResponse( + code = 304, + message = "Not Modified. \n " + + "Empty body because the client already has the latest version of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable. \n The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving the certificate details.", + response = ErrorResponse.class) + }) + Response getAllCertificates( + @ApiParam( + name = "offset", + value = "The starting pagination index for the complete list of qualified items.", + required = false, + defaultValue = "0") + @QueryParam("offset") int offset, + @ApiParam( + name = "limit", + value = "Provide how many certificate details you require from the starting pagination index/offset.", + required = false, + defaultValue = "5") + @QueryParam("limit") int limit, + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time. \n" + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") String ifModifiedSince); + + @DELETE + @Path("/{serialNumber}") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "DELETE", + value = "Deleting an SSL Certificate", + notes = "Delete an SSL certificate that's on the client end.", + tags = "Certificate Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:admin:certificates:delete") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully removed the certificate."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified resource does not exist."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while removing the certificate.", + response = ErrorResponse.class)}) + Response removeCertificate( + @ApiParam( + name = "serialNumber", + value = "The serial number of the certificate.\n" + + "NOTE: Make sure that a certificate with the serial number you provide exists in the server. If not, first add a certificate.", + required = true, + defaultValue = "12438035315552875930") + @PathParam("serialNumber") String serialNumber); + + /** + * Verify Certificate for the API security filter + * + * @param certificate to be verified as a String + * @return Status of the certificate verification. + */ + @POST + @Path("/verify/{type}") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Verify SSL certificate", + notes = "Verify Certificate for the API security filter.\n", + tags = "Certificate Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:admin:certificates:verify") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "Return the status of the certificate verification.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body")}), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class) + }) + Response verifyCertificate( + @ApiParam( + name = "type", + value = "The device type, such as ios, android or windows.", + required = true, + allowableValues = "android, ios, windows") + @PathParam("type") + @Size(max = 45) + String type, + @ApiParam( + name = "certificate", + value = "The properties to verify certificate. It includes the following: \n" + + "serial: The unique ID of the certificate. (optional) \n" + + "pem: pem String of the certificate", + required = true) EnrollmentCertificate certificate); +} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/InputValidationException.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/InputValidationException.java new file mode 100644 index 0000000000..0804806967 --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/InputValidationException.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.certificate.mgt.cert.jaxrs.api; + +import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans.ErrorResponse; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; +import java.io.Serializable; + +public class InputValidationException extends WebApplicationException implements Serializable { + + private static final long serialVersionUID = 147843589458906890L; + + public InputValidationException(ErrorResponse error) { + super(Response.status(Response.Status.BAD_REQUEST).entity(error).build()); + } + +} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/UnexpectedServerErrorException.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/UnexpectedServerErrorException.java new file mode 100644 index 0000000000..28eaed09bc --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/UnexpectedServerErrorException.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.certificate.mgt.cert.jaxrs.api; + +import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans.ErrorResponse; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; + +public class UnexpectedServerErrorException extends WebApplicationException { + + private static final long serialVersionUID = 147943679458906890L; + + public UnexpectedServerErrorException(ErrorResponse error) { + super(Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build()); + } + +} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/beans/BasePaginatedResult.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/beans/BasePaginatedResult.java new file mode 100644 index 0000000000..b1fe40a9ec --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/beans/BasePaginatedResult.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; + +public class BasePaginatedResult { + + private int count; + private String next; + private String previous; + + /** + * Number of Devices returned. + */ + @ApiModelProperty(value = "Number of resources returned.") + @JsonProperty("count") + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + + /** + * Link to the next subset of resources qualified. \nEmpty if no more resources are to be returned. + */ + @ApiModelProperty(value = "Link to the next subset of resources qualified. \n " + + "Empty if no more resources are to be returned.") + @JsonProperty("next") + public String getNext() { + return next; + } + + public void setNext(String next) { + this.next = next; + } + + /** + * Link to the previous subset of resources qualified. \nEmpty if current subset is the first subset returned. + */ + @ApiModelProperty(value = "Link to the previous subset of resources qualified. \n" + + "Empty if current subset is the first subset returned.") + @JsonProperty("previous") + public String getPrevious() { + return previous; + } + + public void setPrevious(String previous) { + this.previous = previous; + } + +} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/beans/CertificateList.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/beans/CertificateList.java new file mode 100644 index 0000000000..2c61a4b23a --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/beans/CertificateList.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.certificate.mgt.core.dto.CertificateResponse; + +import java.util.ArrayList; +import java.util.List; + +public class CertificateList extends BasePaginatedResult { + + private List certificates = new ArrayList<>(); + + @ApiModelProperty(value = "List of certificates returned") + @JsonProperty("certificates") + public List getList() { + return certificates; + } + + public void setList(List certificates) { + this.certificates = certificates; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("{\n"); + + sb.append(" count: ").append(getCount()).append(",\n"); + sb.append(" next: ").append(getNext()).append(",\n"); + sb.append(" previous: ").append(getPrevious()).append(",\n"); + sb.append(" certificates: [").append(certificates).append("\n"); + sb.append("]}\n"); + return sb.toString(); + } + +} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/beans/EnrollmentCertificate.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/beans/EnrollmentCertificate.java new file mode 100644 index 0000000000..e119746c91 --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/beans/EnrollmentCertificate.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans; + +public class EnrollmentCertificate { + String serial; + String pem; + int tenantId; + + public int getTenantId() { + return tenantId; + } + + public void setTenantId(int tenantId) { + this.tenantId = tenantId; + } + + public String getSerial() { + return serial; + } + + public void setSerial(String serial) { + this.serial = serial; + } + + public String getPem() { + return pem; + } + + public void setPem(String pem) { + this.pem = pem; + } +} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/beans/ErrorListItem.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/beans/ErrorListItem.java new file mode 100644 index 0000000000..dc3a94efb1 --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/beans/ErrorListItem.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.NotNull; + +@ApiModel(description = "Error List Item") +public class ErrorListItem { + + @NotNull + private String code = null; + @NotNull + private String message = null; + + @ApiModelProperty(required = true, value = "") + @JsonProperty("code") + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public ErrorListItem() { + } + + public ErrorListItem(String code, String msg) { + this.code = code; + this.message = msg; + } + + + /** + * Description about individual errors occurred + */ + @ApiModelProperty(required = true, value = "Description about individual errors occurred") + @JsonProperty("message") + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("errorItem {\n"); + + sb.append(" code: ").append(code).append("\n"); + sb.append(" message: ").append(message).append("\n"); + sb.append("}\n"); + return sb.toString(); + } + +} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/beans/ErrorResponse.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/beans/ErrorResponse.java new file mode 100644 index 0000000000..f8101d796f --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/beans/ErrorResponse.java @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.ArrayList; +import java.util.List; + +@ApiModel(description = "Error Response") +public class ErrorResponse { + + private Long code = null; + private String message = null; + private String description = null; + private String moreInfo = null; + private List errorItems = new ArrayList<>(); + + private ErrorResponse() { + } + + @JsonProperty(value = "code") + @ApiModelProperty(required = true, value = "") + public Long getCode() { + return code; + } + + public void setCode(Long code) { + this.code = code; + } + + @JsonProperty(value = "message") + @ApiModelProperty(required = true, value = "ErrorResponse message.") + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + @JsonProperty(value = "description") + @ApiModelProperty(value = "A detail description about the error message.") + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @JsonProperty(value = "moreInfo") + @ApiModelProperty(value = "Preferably an url with more details about the error.") + public String getMoreInfo() { + return moreInfo; + } + + public void setMoreInfo(String moreInfo) { + this.moreInfo = moreInfo; + } + + public void addErrorListItem(ErrorListItem item) { + this.errorItems.add(item); + } + + /** + * If there are more than one error list them out. \nFor example, list out validation errors by each field. + */ + @JsonProperty(value = "errorItems") + @ApiModelProperty(value = "If there are more than one error list them out. \n" + + "For example, list out validation errors by each field.") + public List getErrorItems() { + return errorItems; + } + + public void setErrorItems(List error) { + this.errorItems = error; + } + + @Override + public String toString() { +// StringBuilder sb = new StringBuilder(); +// sb.append("{"); +// boolean cont = false; +// if (code != null) { +// cont = true; +// sb.append(" \"code\": ").append(code); +// } +// if (message != null) { +// if (cont) { +// sb.append(","); +// } +// cont = true; +// sb.append(" \"message\": \"").append(message).append("\""); +// } +// if (description != null) { +// if (cont) { +// sb.append(","); +// } +// cont = true; +// sb.append(" \"description\": ").append(description).append("\""); +// } +// if (moreInfo != null) { +// if (cont) { +// sb.append(","); +// } +// cont = true; +// sb.append(" \"moreInfo\": \"").append(moreInfo).append("\""); +// } +// if (error != null && error.size() > 0) { +// if (cont) { +// sb.append(","); +// } +// sb.append(" \"errorItems\": ").append(error); +// } +// sb.append("}"); +// return sb.toString(); + return null; + } + + public static class ErrorResponseBuilder { + + private Long code = null; + private String message = null; + private String description = null; + private String moreInfo = null; + private List error; + + + public ErrorResponseBuilder() { + this.error = new ArrayList<>(); + } + + public ErrorResponseBuilder setCode(long code) { + this.code = code; + return this; + } + + public ErrorResponseBuilder setMessage(String message) { + this.message = message; + return this; + } + + public ErrorResponseBuilder setDescription(String description) { + this.description = description; + return this; + } + + public ErrorResponseBuilder setMoreInfo(String moreInfo) { + this.moreInfo = moreInfo; + return this; + } + + public ErrorResponseBuilder addErrorItem(String code, String msg) { + ErrorListItem item = new ErrorListItem(); + item.setCode(code); + item.setMessage(msg); + this.error.add(item); + return this; + } + + public ErrorResponse build() { + ErrorResponse errorResponse = new ErrorResponse(); + errorResponse.setCode(code); + errorResponse.setMessage(message); + errorResponse.setErrorItems(error); + errorResponse.setDescription(description); + errorResponse.setMoreInfo(moreInfo); + return errorResponse; + } + } + +} + + diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/beans/ValidationResponse.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/beans/ValidationResponse.java new file mode 100644 index 0000000000..8774fc438d --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/beans/ValidationResponse.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + + +package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans; + +public class ValidationResponse { + + private String JWTToken; // X-JWT-Assertion + private String deviceId; + private String deviceType; + private int tenantId; + + public String getJWTToken() { + return JWTToken; + } + + public void setJWTToken(String JWTToken) { + this.JWTToken = JWTToken; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public int getTenantId() { + return tenantId; + } + + public void setTenantId(int tenantId) { + this.tenantId = tenantId; + } +} + diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/common/ErrorHandler.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/common/ErrorHandler.java new file mode 100644 index 0000000000..25d9e4ad79 --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/common/ErrorHandler.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.common; + +import javax.ws.rs.Produces; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.ExceptionMapper; + +@Produces({ "application/json", "application/xml" }) +public class ErrorHandler implements ExceptionMapper { + + public Response toResponse(MDMAPIException exception) { + ErrorMessage errorMessage = new ErrorMessage(); + errorMessage.setErrorMessage(exception.getErrorMessage()); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build(); + } +} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/common/ErrorMessage.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/common/ErrorMessage.java new file mode 100644 index 0000000000..3bbb36969d --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/common/ErrorMessage.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.common; + + +public class ErrorMessage { + + private String errorMessage; + private String errorCode; + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + public String getErrorCode() { + return errorCode; + } + + public void setErrorCode(String errorCode) { + this.errorCode = errorCode; + } +} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/common/GsonMessageBodyHandler.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/common/GsonMessageBodyHandler.java new file mode 100644 index 0000000000..7ca13eb59f --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/common/GsonMessageBodyHandler.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.common; + + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import javax.ws.rs.Consumes; +import javax.ws.rs.Produces; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.ext.MessageBodyReader; +import javax.ws.rs.ext.MessageBodyWriter; +import javax.ws.rs.ext.Provider; +import java.io.*; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +import static javax.ws.rs.core.MediaType.APPLICATION_JSON; + +@Provider +@Produces(APPLICATION_JSON) +@Consumes(APPLICATION_JSON) +public class GsonMessageBodyHandler implements MessageBodyWriter, MessageBodyReader { + + private Gson gson; + private static final String UTF_8 = "UTF-8"; + + public boolean isReadable(Class aClass, Type type, Annotation[] annotations, MediaType mediaType) { + return true; + } + + private Gson getGson() { + if (gson == null) { + final GsonBuilder gsonBuilder = new GsonBuilder(); + gson = gsonBuilder.create(); + } + return gson; + } + + public Object readFrom(Class objectClass, Type type, Annotation[] annotations, MediaType mediaType, + MultivaluedMap stringStringMultivaluedMap, InputStream entityStream) + throws IOException, WebApplicationException { + + InputStreamReader reader = new InputStreamReader(entityStream, "UTF-8"); + + try { + return getGson().fromJson(reader, type); + } finally { + reader.close(); + } + } + + public boolean isWriteable(Class aClass, Type type, Annotation[] annotations, MediaType mediaType) { + return true; + } + + public long getSize(Object o, Class aClass, Type type, Annotation[] annotations, MediaType mediaType) { + return -1; + } + + public void writeTo(Object object, Class aClass, Type type, Annotation[] annotations, MediaType mediaType, + MultivaluedMap stringObjectMultivaluedMap, OutputStream entityStream) + throws IOException, WebApplicationException { + + OutputStreamWriter writer = new OutputStreamWriter(entityStream, UTF_8); + try { + getGson().toJson(object, type, writer); + } finally { + writer.close(); + } + } +} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/common/MDMAPIException.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/common/MDMAPIException.java new file mode 100644 index 0000000000..6a27e76fcb --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/common/MDMAPIException.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.common; + +/** + * Custom exception class for handling CDM API related exceptions. + */ +public class MDMAPIException extends Exception { + + private static final long serialVersionUID = 7950151650447893900L; + private String errorMessage; + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + public MDMAPIException(String msg, Exception e) { + super(msg, e); + setErrorMessage(msg); + } + + public MDMAPIException(String msg, Throwable cause) { + super(msg, cause); + setErrorMessage(msg); + } + + public MDMAPIException(String msg) { + super(msg); + setErrorMessage(msg); + } + + public MDMAPIException() { + super(); + } + + public MDMAPIException(Throwable cause) { + super(cause); + } +} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/exception/BadRequestException.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/exception/BadRequestException.java new file mode 100644 index 0000000000..6c358cba36 --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/exception/BadRequestException.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.exception; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +public class BadRequestException extends WebApplicationException { + + public BadRequestException(Message message, MediaType mediaType) { + super(Response.status(Response.Status.BAD_REQUEST).entity(message).type(mediaType).build()); + } + +} \ No newline at end of file diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/exception/Message.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/exception/Message.java new file mode 100644 index 0000000000..081a99377b --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/exception/Message.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.exception; + +public class Message { + + private String errorMessage; + private String discription; + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + public String getDiscription() { + return discription; + } + + public void setDiscription(String discription) { + this.discription = discription; + } +} \ No newline at end of file diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/impl/CertificateManagementAdminServiceImpl.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/impl/CertificateManagementAdminServiceImpl.java new file mode 100644 index 0000000000..6ce9bdd842 --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/impl/CertificateManagementAdminServiceImpl.java @@ -0,0 +1,318 @@ +/* + * Copyright (c) 2016-2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.CertificateManagementAdminService; +import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans.CertificateList; +import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans.EnrollmentCertificate; +import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans.ErrorResponse; +import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans.ValidationResponse; +import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.util.CertificateMgtAPIUtils; +import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.util.RequestValidationUtil; +import org.wso2.carbon.certificate.mgt.core.dto.CertificateResponse; +import org.wso2.carbon.certificate.mgt.core.exception.CertificateManagementException; +import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException; +import org.wso2.carbon.certificate.mgt.core.scep.SCEPException; +import org.wso2.carbon.certificate.mgt.core.scep.SCEPManager; +import org.wso2.carbon.certificate.mgt.core.scep.TenantedDeviceWrapper; +import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService; +import org.wso2.carbon.certificate.mgt.core.service.PaginationResult; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceManagementConstants; +import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; +import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; + +import javax.ws.rs.*; +import javax.ws.rs.core.Response; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Path("/admin/certificates") +public class CertificateManagementAdminServiceImpl implements CertificateManagementAdminService { + + private static Log log = LogFactory.getLog(CertificateManagementAdminServiceImpl.class); + private static final String PROXY_AUTH_MUTUAL_HEADER = "proxy-mutual-auth-header"; + + /** + * Save a list of certificates and relevant information in the database. + * + * @param enrollmentCertificates List of all the certificates which includes the tenant id, certificate as + * a pem and a serial number. + * @return Status of the data persist operation. + */ + @POST + public Response addCertificate(EnrollmentCertificate[] enrollmentCertificates) { + CertificateManagementService certificateService; + List certificates = new ArrayList<>(); + org.wso2.carbon.certificate.mgt.core.bean.Certificate certificate; + certificateService = CertificateMgtAPIUtils.getCertificateManagementService(); + try { + for (EnrollmentCertificate enrollmentCertificate : enrollmentCertificates) { + certificate = new org.wso2.carbon.certificate.mgt.core.bean.Certificate(); + certificate.setTenantId(PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId()); + certificate.setSerial(enrollmentCertificate.getSerial()); + certificate.setCertificate(certificateService.pemToX509Certificate(enrollmentCertificate.getPem())); + certificates.add(certificate); + } + certificateService.saveCertificate(certificates); + return Response.status(Response.Status.CREATED).entity("Added successfully.").build(); + } catch (KeystoreException e) { + String msg = "Error occurred while converting PEM file to X509Certificate."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()).build(); + } + } + + /** + * Get a certificate when the serial number is given. + * + * @param serialNumber serial of the certificate needed. + * @return certificate response. + */ + @GET + @Path("/{serialNumber}") + public Response getCertificate( + @PathParam("serialNumber") String serialNumber, + @HeaderParam("If-Modified-Since") String ifModifiedSince) { + RequestValidationUtil.validateSerialNumber(serialNumber); + + CertificateManagementService certificateService = CertificateMgtAPIUtils.getCertificateManagementService(); + List certificateResponse; + try { + certificateResponse = certificateService.searchCertificates(serialNumber); + return Response.status(Response.Status.OK).entity(certificateResponse).build(); + } catch (CertificateManagementException e) { + String msg = "Error occurred while converting PEM file to X509Certificate"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()).build(); + } + } + + /** + * Get all certificates in a paginated manner. + * + * @param offset index of the first record to be fetched + * @param limit number of records to be fetched starting from the start index. + * @return paginated result of certificate. + */ + @GET + public Response getAllCertificates( + @QueryParam("offset") int offset, + @QueryParam("limit") int limit, + @HeaderParam("If-Modified-Since") String ifModifiedSince) { + RequestValidationUtil.validatePaginationInfo(offset, limit); + CertificateManagementService certificateService = CertificateMgtAPIUtils.getCertificateManagementService(); + try { + PaginationResult result = certificateService.getAllCertificates(offset, limit); + CertificateList certificates = new CertificateList(); + certificates.setCount(result.getRecordsTotal()); + certificates.setList((List) result.getData()); + return Response.status(Response.Status.OK).entity(certificates).build(); + } catch (CertificateManagementException e) { + String msg = "Error occurred while fetching all certificates."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + @DELETE + @Deprecated + @Path("/{serialNumber}") + public Response removeCertificate(@PathParam("serialNumber") String serialNumber) { + RequestValidationUtil.validateSerialNumber(serialNumber); + + CertificateManagementService certificateService = CertificateMgtAPIUtils.getCertificateManagementService(); + try { + certificateService.removeCertificate(serialNumber); + return Response.status(Response.Status.OK).entity( + "Certificate that carries the serial number '" + + serialNumber + "' has been removed").build(); + } catch (CertificateManagementException e) { + String msg = "Error occurred while converting PEM file to X509Certificate"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + +// @POST +// @Path("/verify/ios") +// public Response verifyIOSCertificate(@ApiParam(name = "certificate", value = "Mdm-Signature of the " + +// "certificate that needs to be verified", required = true) EnrollmentCertificate certificate) { +// try { +// CertificateManagementService certMgtService = CertificateMgtAPIUtils.getCertificateManagementService(); +// X509Certificate cert = certMgtService.extractCertificateFromSignature(certificate.getPem()); +// String challengeToken = certMgtService.extractChallengeToken(cert); +// +// if (challengeToken != null) { +// challengeToken = challengeToken.substring(challengeToken.indexOf("(") + 1).trim(); +// +// SCEPManager scepManager = CertificateMgtAPIUtils.getSCEPManagerService(); +// DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); +// deviceIdentifier.setId(challengeToken); +// deviceIdentifier.setType(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS); +// TenantedDeviceWrapper tenantedDeviceWrapper = scepManager.getValidatedDevice(deviceIdentifier); +// +// if (tenantedDeviceWrapper != null) { +// return Response.status(Response.Status.OK).entity("valid").build(); +// } +// } +// } catch (SCEPException e) { +// String msg = "Error occurred while extracting information from certificate."; +// log.error(msg, e); +// return Response.serverError().entity( +// new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()).build(); +// } catch (KeystoreException e) { +// String msg = "Error occurred while converting PEM file to X509Certificate."; +// log.error(msg, e); +// return Response.serverError().entity( +// new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()).build(); +// } +// return Response.status(Response.Status.OK).entity("invalid").build(); +// } +// +// @POST +// @Path("/verify/android") +// public Response verifyAndroidCertificate(@ApiParam(name = "certificate", value = "Base64 encoded .pem file of the " + +// "certificate that needs to be verified", required = true) EnrollmentCertificate certificate) { +// CertificateResponse certificateResponse = null; +// try { +// CertificateManagementService certMgtService = CertificateMgtAPIUtils.getCertificateManagementService(); +// if (certificate.getSerial().toLowerCase().contains(PROXY_AUTH_MUTUAL_HEADER)) { +// certificateResponse = certMgtService.verifySubjectDN(certificate.getPem()); +// } else { +// X509Certificate clientCertificate = certMgtService.pemToX509Certificate(certificate.getPem()); +// if (clientCertificate != null) { +// certificateResponse = certMgtService.verifyPEMSignature(clientCertificate); +// } +// } +// +// if (certificateResponse != null && certificateResponse.getCommonName() != null && !certificateResponse +// .getCommonName().isEmpty()) { +// return Response.status(Response.Status.OK).entity("valid").build(); +// } +// } catch (KeystoreException e) { +// String msg = "Error occurred while converting PEM file to X509Certificate."; +// log.error(msg, e); +// return Response.serverError().entity( +// new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()).build(); +// } +// return Response.status(Response.Status.OK).entity("invalid").build(); +// } + + @POST + @Path("/verify/{type}") + public Response verifyCertificate(@PathParam("type") String type, EnrollmentCertificate certificate) { + try { + CertificateManagementService certMgtService = CertificateMgtAPIUtils.getCertificateManagementService(); + + if (DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS.equalsIgnoreCase(type)) { + X509Certificate cert = certMgtService.extractCertificateFromSignature(certificate.getPem()); + String challengeToken = certMgtService.extractChallengeToken(cert); + + if (challengeToken != null) { + challengeToken = challengeToken.substring(challengeToken.indexOf("(") + 1).trim(); + + SCEPManager scepManager = CertificateMgtAPIUtils.getSCEPManagerService(); + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); + deviceIdentifier.setId(challengeToken); + deviceIdentifier.setType(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS); + TenantedDeviceWrapper tenantedDeviceWrapper = scepManager.getValidatedDevice(deviceIdentifier); + + Map claims = new HashMap<>(); + + claims.put("http://wso2.org/claims/enduserTenantId", + String.valueOf(tenantedDeviceWrapper.getTenantId())); + claims.put("http://wso2.org/claims/enduser", + tenantedDeviceWrapper.getDevice().getEnrolmentInfo().getOwner() + "@" + + tenantedDeviceWrapper.getTenantDomain()); + claims.put("http://wso2.org/claims/deviceIdentifier", + tenantedDeviceWrapper.getDevice().getDeviceIdentifier()); + claims.put("http://wso2.org/claims/deviceIdType", tenantedDeviceWrapper.getDevice().getType()); + + String jwdToken; + try { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext() + .setTenantId(tenantedDeviceWrapper.getTenantId()); + PrivilegedCarbonContext.getThreadLocalCarbonContext() + .setTenantDomain(tenantedDeviceWrapper.getTenantDomain()); + JWTClientManagerService jwtClientManagerService = CertificateMgtAPIUtils + .getJwtClientManagerService(); + jwdToken = jwtClientManagerService.getJWTClient() + .getJwtToken(tenantedDeviceWrapper.getDevice().getEnrolmentInfo().getOwner(), claims, + true); + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + + ValidationResponse validationResponse = new ValidationResponse(); + validationResponse.setDeviceId(challengeToken); + validationResponse.setDeviceType(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_IOS); + validationResponse.setJWTToken(jwdToken); + validationResponse.setTenantId(tenantedDeviceWrapper.getTenantId()); + + return Response.status(Response.Status.OK).entity(validationResponse).build(); + } + } + + if (DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_ANDROID.equalsIgnoreCase(type)) { + CertificateResponse certificateResponse = null; + if (certificate.getSerial().toLowerCase().contains(PROXY_AUTH_MUTUAL_HEADER)) { + certificateResponse = certMgtService.verifySubjectDN(certificate.getPem()); + } else { + X509Certificate clientCertificate = certMgtService.pemToX509Certificate(certificate.getPem()); + if (clientCertificate != null) { + certificateResponse = certMgtService.verifyPEMSignature(clientCertificate); + } + } + + if (certificateResponse != null && certificateResponse.getCommonName() != null && !certificateResponse + .getCommonName().isEmpty()) { + return Response.status(Response.Status.OK).entity("valid").build(); + } + } + } catch (SCEPException e) { + String msg = "Error occurred while extracting information from certificate."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()).build(); + } catch (KeystoreException e) { + String msg = "Error occurred while converting PEM file to X509Certificate."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()).build(); + } catch (JWTClientException e) { + String msg = "Error occurred while converting PEM file to X509Certificate."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()).build(); + } + return Response.status(Response.Status.OK).entity("invalid").build(); + } +} \ No newline at end of file diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/swagger/extension/SecurityDefinitionConfigurator.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/swagger/extension/SecurityDefinitionConfigurator.java new file mode 100644 index 0000000000..f981877000 --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/swagger/extension/SecurityDefinitionConfigurator.java @@ -0,0 +1,61 @@ +/* + * + * Copyright (c) ${date}, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * / + */ +package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.swagger.extension; + +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.jaxrs.Reader; +import io.swagger.jaxrs.config.ReaderListener; +import io.swagger.models.Swagger; +import io.swagger.models.auth.OAuth2Definition; +import io.swagger.models.auth.SecuritySchemeDefinition; + +import java.util.HashMap; +import java.util.Map; + +@SwaggerDefinition( + basePath = "/api/certificate-mgt/v0.9", + host = "localhost:9443" +) +public class SecurityDefinitionConfigurator implements ReaderListener { + + public static final String TOKEN_AUTH_SCHEME = "swagger_auth"; + + @Override + public void beforeScan(Reader reader, Swagger swagger) { + + } + + @Override + public void afterScan(Reader reader, Swagger swagger) { + OAuth2Definition tokenScheme = new OAuth2Definition(); + tokenScheme.setType("oauth2"); + tokenScheme.setFlow("application"); + tokenScheme.setTokenUrl("https://" + swagger.getHost() + "/oauth2/token"); + tokenScheme.setAuthorizationUrl("https://" + swagger.getHost() + "/oauth2/authorize"); + tokenScheme.addScope("write:everything", "Full access"); + + Map schemes = new HashMap<>(); + schemes.put(TOKEN_AUTH_SCHEME, tokenScheme); + + swagger.setSecurityDefinitions(schemes); + } + +} + diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/util/ApiOriginFilter.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/util/ApiOriginFilter.java new file mode 100644 index 0000000000..3a192bdf36 --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/util/ApiOriginFilter.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.util; + +import javax.servlet.*; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class ApiOriginFilter implements Filter { + + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + HttpServletResponse res = (HttpServletResponse) response; + res.addHeader("Access-Control-Allow-Origin", "*"); + res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT"); + res.addHeader("Access-Control-Allow-Headers", "Content-Type"); + chain.doFilter(request, response); + } + + public void destroy() { + //do nothing + } + + public void init(FilterConfig filterConfig) throws ServletException { + //do nothing + } + +} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/util/CertificateMgtAPIUtils.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/util/CertificateMgtAPIUtils.java new file mode 100644 index 0000000000..fc5264c4db --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/util/CertificateMgtAPIUtils.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.certificate.mgt.core.scep.SCEPManager; +import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.core.search.mgt.SearchManagerService; +import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; + +import javax.ws.rs.core.MediaType; + +/** + * CertificateMgtAPIUtils class provides utility functions used by Certificate Mgt REST-API classes. + */ +public class CertificateMgtAPIUtils { + + public static final MediaType DEFAULT_CONTENT_TYPE = MediaType.APPLICATION_JSON_TYPE; + private static Log log = LogFactory.getLog(CertificateMgtAPIUtils.class); + + public static CertificateManagementService getCertificateManagementService() { + + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + CertificateManagementService certificateManagementService = (CertificateManagementService) + ctx.getOSGiService(CertificateManagementService.class, null); + + if (certificateManagementService == null) { + String msg = "CertificateManagementAdminServiceImpl Management service not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + + return certificateManagementService; + } + + + public static JWTClientManagerService getJwtClientManagerService() { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + JWTClientManagerService jwtClientManagerService = (JWTClientManagerService) + ctx.getOSGiService(JWTClientManagerService.class, null); + + if (jwtClientManagerService == null) { + String msg = "JWTClientManagerService Management service not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + + return jwtClientManagerService; + } + + + public static SCEPManager getSCEPManagerService() { + + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + SCEPManager scepManagerService = (SCEPManager) + ctx.getOSGiService(SCEPManager.class, null); + + if (scepManagerService == null) { + String msg = "SCEPManagerImpl Management service not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + + return scepManagerService; + } + + + public static MediaType getResponseMediaType(String acceptHeader) { + MediaType responseMediaType; + if (acceptHeader == null || MediaType.WILDCARD.equals(acceptHeader)) { + responseMediaType = DEFAULT_CONTENT_TYPE; + } else { + responseMediaType = MediaType.valueOf(acceptHeader); + } + + return responseMediaType; + } + + public static SearchManagerService getSearchManagerService() { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + SearchManagerService searchManagerService = + (SearchManagerService) ctx.getOSGiService(SearchManagerService.class, null); + if (searchManagerService == null) { + String msg = "DeviceImpl search manager service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + return searchManagerService; + } +} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/util/RequestValidationUtil.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/util/RequestValidationUtil.java new file mode 100644 index 0000000000..233112c342 --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/util/RequestValidationUtil.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.util; + +import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.beans.ErrorResponse; +import org.wso2.carbon.certificate.mgt.cert.jaxrs.api.InputValidationException; + +public class RequestValidationUtil { + + public static void validateSerialNumber(String serialNumber) { + if (serialNumber == null || serialNumber.isEmpty()) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage( + "Serial number cannot be null or empty").build()); + } + } + + public static void validatePaginationInfo(int offset, int limit) { + if (offset < 0) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage( + "Offset number cannot be negative").build()); + } + if (limit < 0) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage( + "Limit number cannot be negative").build()); + } + } + + +} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/util/ResponsePayload.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/util/ResponsePayload.java new file mode 100644 index 0000000000..c0f44afd41 --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/cert/jaxrs/api/util/ResponsePayload.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.certificate.mgt.cert.jaxrs.api.util; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +public class ResponsePayload { + + private int statusCode; + private String messageFromServer; + private Object responseContent; + + @XmlElement + public int getStatusCode() { + return statusCode; + } + + public void setStatusCode(int statusCode) { + this.statusCode = statusCode; + } + + @XmlElement + public String getMessageFromServer() { + return messageFromServer; + } + + public void setMessageFromServer(String messageFromServer) { + this.messageFromServer = messageFromServer; + } + + @XmlElement + public Object getResponseContent() { + return responseContent; + } + + public void setResponseContent(Object responseContent) { + this.responseContent = responseContent; + } + + private ResponsePayloadBuilder getBuilder() { + return new ResponsePayloadBuilder(); + } + + public static ResponsePayloadBuilder statusCode(int statusCode) { + ResponsePayload message = new ResponsePayload(); + return message.getBuilder().statusCode(statusCode); + } + + public static ResponsePayloadBuilder messageFromServer(String messageFromServer) { + ResponsePayload message = new ResponsePayload(); + return message.getBuilder().messageFromServer(messageFromServer); + } + + public static ResponsePayloadBuilder responseContent(String responseContent) { + ResponsePayload message = new ResponsePayload(); + return message.getBuilder().responseContent(responseContent); + } + + public class ResponsePayloadBuilder { + + private int statusCode; + private String messageFromServer; + private Object responseContent; + + public ResponsePayloadBuilder statusCode(int statusCode) { + this.statusCode = statusCode; + return this; + } + + public ResponsePayloadBuilder messageFromServer(String messageFromServer) { + this.messageFromServer = messageFromServer; + return this; + } + + public ResponsePayloadBuilder responseContent(String responseContent) { + this.responseContent = responseContent; + return this; + } + + public ResponsePayload build() { + ResponsePayload payload = new ResponsePayload(); + payload.setStatusCode(statusCode); + payload.setMessageFromServer(messageFromServer); + payload.setResponseContent(responseContent); + return payload; + } + } + +} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/webapp/META-INF/permissions.xml b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/webapp/META-INF/permissions.xml new file mode 100644 index 0000000000..0fc4702145 --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/webapp/META-INF/permissions.xml @@ -0,0 +1,59 @@ + + + + + + + + + + View all certificates + /device-mgt/admin/certificate/GetAll + /admin/certificates + GET + + + Add certificate + /device-mgt/admin/certificate/Add + /admin/certificates + POST + + + Remove certificate + /device-mgt/admin/certificate/Remove + /admin/certificates/* + DELETE + + + View certificate + /device-mgt/admin/certificate/View + /admin/certificates/* + GET + + + diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/webapp/META-INF/webapp-classloading.xml b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/webapp/META-INF/webapp-classloading.xml new file mode 100644 index 0000000000..ed2ed21624 --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/webapp/META-INF/webapp-classloading.xml @@ -0,0 +1,35 @@ + + + + + + + + + false + + + CXF,Carbon + diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/webapp/WEB-INF/cxf-servlet.xml b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/webapp/WEB-INF/cxf-servlet.xml new file mode 100644 index 0000000000..def310421d --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/webapp/WEB-INF/cxf-servlet.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/webapp/WEB-INF/web.xml b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..ca08169c8c --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,119 @@ + + + + Certificate-Webapp + + JAX-WS/JAX-RS Certificate Management Endpoint + JAX-WS/JAX-RS Servlet + CXFServlet + + org.apache.cxf.transport.servlet.CXFServlet + + + swagger.security.filter + ApiAuthorizationFilterImpl + + 1 + + + CXFServlet + /* + + + 60 + + + doAuthentication + true + + + + + managed-api-enabled + true + + + managed-api-owner + admin + + + isSharedWithAllTenants + true + + + + + CertificateMgt-Admin + /* + + + CONFIDENTIAL + + + + + ApiOriginFilter + org.wso2.carbon.certificate.mgt.cert.jaxrs.api.util.ApiOriginFilter + + + + HttpHeaderSecurityFilter + org.apache.catalina.filters.HttpHeaderSecurityFilter + + hstsEnabled + false + + + + + ContentTypeBasedCachePreventionFilter + org.wso2.carbon.ui.filters.cache.ContentTypeBasedCachePreventionFilter + + patterns + text/html" ,application/json" ,text/plain + + + filterAction + enforce + + + httpHeaders + Cache-Control: no-store, no-cache, must-revalidate, private + + + + + HttpHeaderSecurityFilter + /* + + + + ContentTypeBasedCachePreventionFilter + /* + + + + ApiOriginFilter + /* + + + + diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/pom.xml b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/pom.xml new file mode 100644 index 0000000000..85466d6c36 --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/pom.xml @@ -0,0 +1,224 @@ + + + + + + + certificate-mgt + org.wso2.carbon.devicemgt + 3.0.185-SNAPSHOT + ../pom.xml + + + 4.0.0 + org.wso2.carbon.certificate.mgt.v09.api + war + WSO2 Carbon - Certificate Management v09 API + WSO2 Carbon - Certificate Management v09 API + http://wso2.org + + + + + maven-compiler-plugin + + 1.8 + 1.8 + + + + maven-war-plugin + + WEB-INF/lib/*cxf*.jar + api#scep-mgt#v0.9 + + + + org.jacoco + jacoco-maven-plugin + + ${basedir}/target/coverage-reports/jacoco-unit.exec + + + + jacoco-initialize + + prepare-agent + + + + jacoco-site + test + + report + + + ${basedir}/target/coverage-reports/jacoco-unit.exec + ${basedir}/target/coverage-reports/site + + + + + + + + + + deploy + + compile + + + org.apache.maven.plugins + maven-antrun-plugin + 1.7 + + + compile + + run + + + + + + + + + + + + + + + + + + client + + test + + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + + test + + java + + + + + + + + + + + + org.apache.cxf + cxf-rt-frontend-jaxws + + + commons-codec.wso2 + commons-codec + + + commons-codec + commons-codec + + + + + org.apache.cxf + cxf-rt-frontend-jaxrs + + + org.apache.cxf + cxf-rt-transports-http + + + junit + junit + test + + + javax.ws.rs + jsr311-api + provided + + + org.wso2.carbon + org.wso2.carbon.logging + provided + + + org.wso2.carbon.devicemgt + org.wso2.carbon.certificate.mgt.core + provided + + + io.swagger + swagger-annotations + + + io.swagger + swagger-core + + + org.wso2.orbit.com.fasterxml.jackson.core + jackson-annotations + + + org.slf4j + slf4j-api + + + + + io.swagger + swagger-jaxrs + + + com.fasterxml.jackson.module + jackson-module-jaxb-annotations + + + org.slf4j + slf4j-api + + + + + javax.servlet + servlet-api + provided + + + org.wso2.carbon.devicemgt + org.wso2.carbon.apimgt.annotations + provided + + + + diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/api/CertificateMgtService.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/api/CertificateMgtService.java new file mode 100644 index 0000000000..a2b7aee212 --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/api/CertificateMgtService.java @@ -0,0 +1,117 @@ +/* + * + * Copyright (c) ${date}, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * / + */ + +package org.wso2.carbon.certificate.mgt.jaxrs.api; + +import io.swagger.annotations.*; + +import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.certificate.mgt.jaxrs.beans.ErrorResponse; + +import javax.ws.rs.Consumes; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +@SwaggerDefinition( + info = @Info( + version = "0.9.0", + title = "", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "SCEP Management"), + @ExtensionProperty(name = "context", value = "/api/device-mgt/v0.9/scep"), + }) + } + ), + tags = { + @Tag(name = "scep_management", description = "SCEP management related REST-API. " + + "This can be used to manipulated device " + + "certificate related details.") + } +) +@Path("/scep") +@Api(value = "SCEP Management", description = "This API carries all device Certificate management " + + "related operations.") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@Scopes(scopes = { + @Scope( + name = "Sign CSR", + description = "Sign CSR", + key = "perm:sign-csr", + permissions = {"/device-mgt/certificates/manage"} + ) +} +) +public interface CertificateMgtService { + + String SCOPE = "scope"; + + /** + * Sign the client's certificate signing request and save it in the database. + * + * @param binarySecurityToken Base64 encoded Certificate signing request. + * @return X509Certificate type sign certificate. + */ + @POST + @Path("/sign-csr") + @Produces(MediaType.TEXT_PLAIN) + @Consumes(MediaType.TEXT_PLAIN) + @ApiOperation( + consumes = MediaType.TEXT_PLAIN, + produces = MediaType.TEXT_PLAIN, + httpMethod = "POST", + value = "Process a given CSR and return signed certificates.", + notes = "This will return a signed certificate upon a given CSR.", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = SCOPE, value = "perm:sign-csr") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the device location.", + response = String.class), + @ApiResponse( + code = 304, + message = "Not Modified. \n " + + "Empty body because the client already has the latest version of the requested resource."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error occurred while retrieving signed certificate.", + response = ErrorResponse.class) + }) + Response getSignedCertFromCSR( + @ApiParam( + name = "If-Modified-Since", + value = "Validates if the requested variant has not been modified since the time specified", + required = false) + @HeaderParam("If-Modified-Since") String ifModifiedSince, + String binarySecurityToken); +} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/api/common/ErrorHandler.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/api/common/ErrorHandler.java new file mode 100644 index 0000000000..8c3296292d --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/api/common/ErrorHandler.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.certificate.mgt.jaxrs.api.common; + +import javax.ws.rs.Produces; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.ExceptionMapper; + +@Produces({ "application/json", "application/xml" }) +public class ErrorHandler implements ExceptionMapper { + + public Response toResponse(MDMAPIException exception) { + ErrorMessage errorMessage = new ErrorMessage(); + errorMessage.setErrorMessage(exception.getErrorMessage()); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build(); + } +} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/api/common/ErrorMessage.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/api/common/ErrorMessage.java new file mode 100644 index 0000000000..66777c0f65 --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/api/common/ErrorMessage.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.certificate.mgt.jaxrs.api.common; + + +public class ErrorMessage { + + private String errorMessage; + private String errorCode; + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + public String getErrorCode() { + return errorCode; + } + + public void setErrorCode(String errorCode) { + this.errorCode = errorCode; + } +} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/api/common/GsonMessageBodyHandler.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/api/common/GsonMessageBodyHandler.java new file mode 100644 index 0000000000..91b3283e68 --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/api/common/GsonMessageBodyHandler.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.certificate.mgt.jaxrs.api.common; + + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import javax.ws.rs.Consumes; +import javax.ws.rs.Produces; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.ext.MessageBodyReader; +import javax.ws.rs.ext.MessageBodyWriter; +import javax.ws.rs.ext.Provider; +import java.io.*; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +import static javax.ws.rs.core.MediaType.APPLICATION_JSON; + +@Provider +@Produces(APPLICATION_JSON) +@Consumes(APPLICATION_JSON) +public class GsonMessageBodyHandler implements MessageBodyWriter, MessageBodyReader { + + private Gson gson; + private static final String UTF_8 = "UTF-8"; + + public boolean isReadable(Class aClass, Type type, Annotation[] annotations, MediaType mediaType) { + return true; + } + + private Gson getGson() { + if (gson == null) { + final GsonBuilder gsonBuilder = new GsonBuilder(); + gson = gsonBuilder.create(); + } + return gson; + } + + public Object readFrom(Class objectClass, Type type, Annotation[] annotations, MediaType mediaType, + MultivaluedMap stringStringMultivaluedMap, InputStream entityStream) + throws IOException, WebApplicationException { + + InputStreamReader reader = new InputStreamReader(entityStream, "UTF-8"); + + try { + return getGson().fromJson(reader, type); + } finally { + reader.close(); + } + } + + public boolean isWriteable(Class aClass, Type type, Annotation[] annotations, MediaType mediaType) { + return true; + } + + public long getSize(Object o, Class aClass, Type type, Annotation[] annotations, MediaType mediaType) { + return -1; + } + + public void writeTo(Object object, Class aClass, Type type, Annotation[] annotations, MediaType mediaType, + MultivaluedMap stringObjectMultivaluedMap, OutputStream entityStream) + throws IOException, WebApplicationException { + + OutputStreamWriter writer = new OutputStreamWriter(entityStream, UTF_8); + try { + getGson().toJson(object, type, writer); + } finally { + writer.close(); + } + } +} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/api/common/MDMAPIException.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/api/common/MDMAPIException.java new file mode 100644 index 0000000000..c06dc48f3e --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/api/common/MDMAPIException.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.certificate.mgt.jaxrs.api.common; + +/** + * Custom exception class for handling CDM API related exceptions. + */ +public class MDMAPIException extends Exception { + + private static final long serialVersionUID = 7950151650447893900L; + private String errorMessage; + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + public MDMAPIException(String msg, Exception e) { + super(msg, e); + setErrorMessage(msg); + } + + public MDMAPIException(String msg, Throwable cause) { + super(msg, cause); + setErrorMessage(msg); + } + + public MDMAPIException(String msg) { + super(msg); + setErrorMessage(msg); + } + + public MDMAPIException() { + super(); + } + + public MDMAPIException(Throwable cause) { + super(cause); + } +} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/api/impl/CertificateMgtServiceImpl.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/api/impl/CertificateMgtServiceImpl.java new file mode 100644 index 0000000000..71c03b6e1c --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/api/impl/CertificateMgtServiceImpl.java @@ -0,0 +1,56 @@ +package org.wso2.carbon.certificate.mgt.jaxrs.api.impl; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException; +import org.wso2.carbon.certificate.mgt.core.impl.CertificateGenerator; +import org.wso2.carbon.certificate.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.certificate.mgt.jaxrs.exception.UnexpectedServerErrorException; +import org.wso2.carbon.certificate.mgt.jaxrs.api.CertificateMgtService; +import org.wso2.carbon.certificate.mgt.jaxrs.exception.Message; + +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; + +@Path("/scep") +public class CertificateMgtServiceImpl implements CertificateMgtService { + private static Log log = LogFactory.getLog(CertificateMgtServiceImpl.class); + + @POST + @Path("/sign-csr") + @Produces(MediaType.TEXT_PLAIN) + @Consumes(MediaType.TEXT_PLAIN) + public Response getSignedCertFromCSR( + @HeaderParam("If-Modified-Since") String ifModifiedSince, String binarySecurityToken) { + Message message = new Message(); + X509Certificate signedCert; + String singedCertificate; + Base64 base64 = new Base64(); + CertificateGenerator certificateGenerator = new CertificateGenerator(); + try { + if (certificateGenerator.getSignedCertificateFromCSR(binarySecurityToken) == null) { + message.setErrorMessage("Error occurred while signing the CSR."); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR). + entity(message).build(); + } else { + signedCert = certificateGenerator.getSignedCertificateFromCSR(binarySecurityToken); + singedCertificate = base64.encodeToString(signedCert.getEncoded()); + return Response.status(Response.Status.OK).entity(singedCertificate).build(); + } + } catch (KeystoreException e) { + String msg = "Error occurred while fetching certificate."; + log.error(msg, e); + throw new UnexpectedServerErrorException(new ErrorResponse.ErrorResponseBuilder().setCode( + 500l).setMessage(msg).build()); + } catch (CertificateEncodingException e) { + String msg = "Error occurred while encoding the certificate."; + log.error(msg, e); + throw new UnexpectedServerErrorException(new ErrorResponse.ErrorResponseBuilder().setCode( + 500l).setMessage(msg).build()); + } + } +} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/api/util/ResponsePayload.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/api/util/ResponsePayload.java new file mode 100644 index 0000000000..2e0f21cc4d --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/api/util/ResponsePayload.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.certificate.mgt.jaxrs.api.util; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +public class ResponsePayload { + + private int statusCode; + private String messageFromServer; + private Object responseContent; + + @XmlElement + public int getStatusCode() { + return statusCode; + } + + public void setStatusCode(int statusCode) { + this.statusCode = statusCode; + } + + @XmlElement + public String getMessageFromServer() { + return messageFromServer; + } + + public void setMessageFromServer(String messageFromServer) { + this.messageFromServer = messageFromServer; + } + + @XmlElement + public Object getResponseContent() { + return responseContent; + } + + public void setResponseContent(Object responseContent) { + this.responseContent = responseContent; + } + + private ResponsePayloadBuilder getBuilder() { + return new ResponsePayloadBuilder(); + } + + public static ResponsePayloadBuilder statusCode(int statusCode) { + ResponsePayload message = new ResponsePayload(); + return message.getBuilder().statusCode(statusCode); + } + + public static ResponsePayloadBuilder messageFromServer(String messageFromServer) { + ResponsePayload message = new ResponsePayload(); + return message.getBuilder().messageFromServer(messageFromServer); + } + + public static ResponsePayloadBuilder responseContent(String responseContent) { + ResponsePayload message = new ResponsePayload(); + return message.getBuilder().responseContent(responseContent); + } + + public class ResponsePayloadBuilder { + + private int statusCode; + private String messageFromServer; + private Object responseContent; + + public ResponsePayloadBuilder statusCode(int statusCode) { + this.statusCode = statusCode; + return this; + } + + public ResponsePayloadBuilder messageFromServer(String messageFromServer) { + this.messageFromServer = messageFromServer; + return this; + } + + public ResponsePayloadBuilder responseContent(String responseContent) { + this.responseContent = responseContent; + return this; + } + + public ResponsePayload build() { + ResponsePayload payload = new ResponsePayload(); + payload.setStatusCode(statusCode); + payload.setMessageFromServer(messageFromServer); + payload.setResponseContent(responseContent); + return payload; + } + } + +} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/beans/ErrorListItem.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/beans/ErrorListItem.java new file mode 100644 index 0000000000..b9b6e6c67c --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/beans/ErrorListItem.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.certificate.mgt.jaxrs.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.NotNull; + +@ApiModel(description = "Error List Item") +public class ErrorListItem { + + @NotNull + private String code = null; + @NotNull + private String message = null; + + @ApiModelProperty(required = true, value = "") + @JsonProperty("code") + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public ErrorListItem() { + } + + public ErrorListItem(String code, String msg) { + this.code = code; + this.message = msg; + } + + + /** + * Description about individual errors occurred + */ + @ApiModelProperty(required = true, value = "Description about individual errors occurred") + @JsonProperty("message") + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("errorItem {\n"); + + sb.append(" code: ").append(code).append("\n"); + sb.append(" message: ").append(message).append("\n"); + sb.append("}\n"); + return sb.toString(); + } + +} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/beans/ErrorResponse.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/beans/ErrorResponse.java new file mode 100644 index 0000000000..81b49c5da5 --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/beans/ErrorResponse.java @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.certificate.mgt.jaxrs.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.ArrayList; +import java.util.List; + +@ApiModel(description = "Error Response") +public class ErrorResponse { + + private Long code = null; + private String message = null; + private String description = null; + private String moreInfo = null; + private List errorItems = new ArrayList<>(); + + private ErrorResponse() { + } + + @JsonProperty(value = "code") + @ApiModelProperty(required = true, value = "") + public Long getCode() { + return code; + } + + public void setCode(Long code) { + this.code = code; + } + + @JsonProperty(value = "message") + @ApiModelProperty(required = true, value = "ErrorResponse message.") + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + @JsonProperty(value = "description") + @ApiModelProperty(value = "A detail description about the error message.") + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @JsonProperty(value = "moreInfo") + @ApiModelProperty(value = "Preferably an url with more details about the error.") + public String getMoreInfo() { + return moreInfo; + } + + public void setMoreInfo(String moreInfo) { + this.moreInfo = moreInfo; + } + + public void addErrorListItem(ErrorListItem item) { + this.errorItems.add(item); + } + + /** + * If there are more than one error list them out. \nFor example, list out validation errors by each field. + */ + @JsonProperty(value = "errorItems") + @ApiModelProperty(value = "If there are more than one error list them out. \n" + + "For example, list out validation errors by each field.") + public List getErrorItems() { + return errorItems; + } + + public void setErrorItems(List error) { + this.errorItems = error; + } + + @Override + public String toString() { +// StringBuilder sb = new StringBuilder(); +// sb.append("{"); +// boolean cont = false; +// if (code != null) { +// cont = true; +// sb.append(" \"code\": ").append(code); +// } +// if (message != null) { +// if (cont) { +// sb.append(","); +// } +// cont = true; +// sb.append(" \"message\": \"").append(message).append("\""); +// } +// if (description != null) { +// if (cont) { +// sb.append(","); +// } +// cont = true; +// sb.append(" \"description\": ").append(description).append("\""); +// } +// if (moreInfo != null) { +// if (cont) { +// sb.append(","); +// } +// cont = true; +// sb.append(" \"moreInfo\": \"").append(moreInfo).append("\""); +// } +// if (error != null && error.size() > 0) { +// if (cont) { +// sb.append(","); +// } +// sb.append(" \"errorItems\": ").append(error); +// } +// sb.append("}"); +// return sb.toString(); + return null; + } + + public static class ErrorResponseBuilder { + + private Long code = null; + private String message = null; + private String description = null; + private String moreInfo = null; + private List error; + + + public ErrorResponseBuilder() { + this.error = new ArrayList<>(); + } + + public ErrorResponseBuilder setCode(long code) { + this.code = code; + return this; + } + + public ErrorResponseBuilder setMessage(String message) { + this.message = message; + return this; + } + + public ErrorResponseBuilder setDescription(String description) { + this.description = description; + return this; + } + + public ErrorResponseBuilder setMoreInfo(String moreInfo) { + this.moreInfo = moreInfo; + return this; + } + + public ErrorResponseBuilder addErrorItem(String code, String msg) { + ErrorListItem item = new ErrorListItem(); + item.setCode(code); + item.setMessage(msg); + this.error.add(item); + return this; + } + + public ErrorResponse build() { + ErrorResponse errorResponse = new ErrorResponse(); + errorResponse.setCode(code); + errorResponse.setMessage(message); + errorResponse.setErrorItems(error); + errorResponse.setDescription(description); + errorResponse.setMoreInfo(moreInfo); + return errorResponse; + } + } + +} + + diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/exception/BadRequestException.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/exception/BadRequestException.java new file mode 100644 index 0000000000..1637031d48 --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/exception/BadRequestException.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.certificate.mgt.jaxrs.exception; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +public class BadRequestException extends WebApplicationException { + + public BadRequestException(Message message, MediaType mediaType) { + super(Response.status(Response.Status.BAD_REQUEST).entity(message).type(mediaType).build()); + } + +} \ No newline at end of file diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/exception/Message.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/exception/Message.java new file mode 100644 index 0000000000..42a23d599a --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/exception/Message.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.certificate.mgt.jaxrs.exception; + +public class Message { + + private String errorMessage; + private String discription; + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + public String getDiscription() { + return discription; + } + + public void setDiscription(String discription) { + this.discription = discription; + } +} \ No newline at end of file diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/exception/UnexpectedServerErrorException.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/exception/UnexpectedServerErrorException.java new file mode 100644 index 0000000000..9b6e2d4ef2 --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/java/org/wso2/carbon/certificate/mgt/jaxrs/exception/UnexpectedServerErrorException.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.certificate.mgt.jaxrs.exception; + +import org.wso2.carbon.certificate.mgt.jaxrs.beans.ErrorResponse; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; + +public class UnexpectedServerErrorException extends WebApplicationException { + + private static final long serialVersionUID = 147943679458906890L; + + public UnexpectedServerErrorException(ErrorResponse error) { + super(Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build()); + } + +} diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/webapp/META-INF/permissions.xml b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/webapp/META-INF/permissions.xml new file mode 100644 index 0000000000..5a63c7f533 --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/webapp/META-INF/permissions.xml @@ -0,0 +1,40 @@ + + + + + + + + + get certificate in the database + /device-mgt/certificate/GetSignCSR + /certificates/scep/signcsr + POST + emm_admin + + diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/webapp/META-INF/webapp-classloading.xml b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/webapp/META-INF/webapp-classloading.xml new file mode 100644 index 0000000000..ed2ed21624 --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/webapp/META-INF/webapp-classloading.xml @@ -0,0 +1,35 @@ + + + + + + + + + false + + + CXF,Carbon + diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/webapp/WEB-INF/cxf-servlet.xml b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/webapp/WEB-INF/cxf-servlet.xml new file mode 100644 index 0000000000..4bb0c0aca1 --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/webapp/WEB-INF/cxf-servlet.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/webapp/WEB-INF/web.xml b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..6fd45f33b3 --- /dev/null +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,91 @@ + + + + Certificate-Webapp + + JAX-WS/JAX-RS Certificate Management Endpoint + JAX-WS/JAX-RS Servlet + CXFServlet + + org.apache.cxf.transport.servlet.CXFServlet + + + + CXFServlet + /* + + + 60 + + + doAuthentication + true + + + + + managed-api-enabled + true + + + managed-api-owner + admin + + + isSharedWithAllTenants + true + + + + HttpHeaderSecurityFilter + org.apache.catalina.filters.HttpHeaderSecurityFilter + + hstsEnabled + false + + + + + ContentTypeBasedCachePreventionFilter + org.wso2.carbon.ui.filters.cache.ContentTypeBasedCachePreventionFilter + + patterns + text/html" ,application/json" ,text/plain + + + filterAction + enforce + + + httpHeaders + Cache-Control: no-store, no-cache, must-revalidate, private + + + + + HttpHeaderSecurityFilter + /* + + + + ContentTypeBasedCachePreventionFilter + /* + + + diff --git a/components/certificate-mgt/pom.xml b/components/certificate-mgt/pom.xml index a3f61ac277..7bdfe9ac48 100644 --- a/components/certificate-mgt/pom.xml +++ b/components/certificate-mgt/pom.xml @@ -37,7 +37,9 @@ org.wso2.carbon.certificate.mgt.core org.wso2.carbon.certificate.mgt.api - org.wso2.carbon.certificate.mgt.cert.admin.api + org.wso2.carbon.certificate.mgt.cert.admin.api + org.wso2.carbon.certificate.mgt.cert.admin.v09.api + org.wso2.carbon.certificate.mgt.v09.api diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java index 84e07d11c0..4fbc97f41b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java @@ -299,143 +299,6 @@ public interface DeviceManagementService { @QueryParam("limit") int limit); - @GET - @ApiOperation( - produces = MediaType.APPLICATION_JSON, - httpMethod = "GET", - value = "Getting Details of Registered Devices", - notes = "Provides details of all the devices enrolled with WSO2 IoT Server.", - tags = "Device Management", - extensions = { - @Extension(properties = { - @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:view") - }) - } - ) - @ApiResponses(value = { - @ApiResponse(code = 200, message = "OK. \n Successfully fetched the list of devices.", - response = DeviceList.class, - responseHeaders = { - @ResponseHeader( - name = "Content-Type", - description = "The content type of the body"), - @ResponseHeader( - name = "ETag", - description = "Entity Tag of the response resource.\n" + - "Used by caches, or in conditional requests."), - @ResponseHeader( - name = "Last-Modified", - description = "Date and time the resource was last modified.\n" + - "Used by caches, or in conditional requests."), - }), - @ApiResponse( - code = 304, - message = "Not Modified. \n Empty body because the client already has the latest version of " + - "the requested resource.\n"), - @ApiResponse( - code = 400, - message = "The incoming request has more than one selection criteria defined via the query parameters.", - response = ErrorResponse.class), - @ApiResponse( - code = 404, - message = "The search criteria did not match any device registered with the server.", - response = ErrorResponse.class), - @ApiResponse( - code = 406, - message = "Not Acceptable.\n The requested media type is not supported."), - @ApiResponse( - code = 500, - message = "Internal Server Error. \n Server error occurred while fetching the device list.", - response = ErrorResponse.class) - }) - @Path("/v2") - Response getDevicesDep( - @ApiParam( - name = "name", - value = "The device name, such as shamu, bullhead or angler Nexus device names. ", - required = false) - @Size(max = 45) - String name, - @ApiParam( - name = "type", - value = "The device type, such as ios, android or windows.", - required = false) - @QueryParam("type") - @Size(max = 45) - String type, - @ApiParam( - name = "user", - value = "The username of the owner of the device.", - required = false) - @QueryParam("user") - String user, - @ApiParam( - name = "userPattern", - value = "The pattern of username of the owner of the device.", - required = false) - @QueryParam("userPattern") - String userPattern, - @ApiParam( - name = "role", - value = "A role of device owners. Ex : store-admin", - required = false) - @QueryParam("role") - @Size(max = 45) - String role, - @ApiParam( - name = "ownership", - allowableValues = "BYOD, COPE", - value = "Provide the ownership status of the device. The following values can be assigned:\n" + - "- BYOD: Bring Your Own Device\n" + - "- COPE: Corporate-Owned, Personally-Enabled", - required = false) - @QueryParam("ownership") - @Size(max = 45) - String ownership, - @ApiParam( - name = "status", - value = "Provide the device status details, such as active or inactive.", - required = false) - @QueryParam("status") - @Size(max = 45) - String status, - @ApiParam( - name = "groupId", - value = "Id of the group which device belongs", - required = false) - @QueryParam("groupId") - int groupId, - @ApiParam( - name = "since", - value = "Checks if the requested variant was created since the specified date-time.\n" + - "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" + - "Example: Mon, 05 Jan 2014 15:10:00 +0200", - required = false) - @QueryParam("since") - String since, - @ApiParam( - name = "If-Modified-Since", - value = "Checks if the requested variant was modified, since the specified date-time.\n" + - "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z\n" + - "Example: Mon, 05 Jan 2014 15:10:00 +0200", - required = false) - @HeaderParam("If-Modified-Since") - String timestamp, - @ApiParam( - name = "offset", - value = "The starting pagination index for the complete list of qualified items.", - required = false, - defaultValue = "0") - @QueryParam("offset") - int offset, - @ApiParam( - name = "limit", - value = "Provide how many device details you require from the starting pagination index/offset.", - required = false, - defaultValue = "5") - @QueryParam("limit") - int limit); - @GET @ApiOperation( produces = MediaType.APPLICATION_JSON, @@ -1322,107 +1185,6 @@ public interface DeviceManagementService { @QueryParam("owner") String owner); - @GET - @Path("/{type}/{id}/operations/v2") - @ApiOperation( - produces = MediaType.APPLICATION_JSON, - httpMethod = "GET", - value = "Getting Device Operation Details", - notes = "Get the details of operations carried out on a selected device.", - tags = "Device Management", - extensions = { - @Extension(properties = { - @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:operations") - }) - } - ) - @ApiResponses( - value = { - @ApiResponse( - code = 200, - message = "OK. \n Successfully fetched the list of operations scheduled for the device.", - response = Operation.class, - responseContainer = "List", - responseHeaders = { - @ResponseHeader( - name = "Content-Type", - description = "The content type of the body"), - @ResponseHeader( - name = "ETag", - description = "Entity Tag of the response resource.\n" + - "Used by caches, or in conditional requests."), - @ResponseHeader( - name = "Last-Modified", - description = "Date and time the resource was last modified" + - "Used by caches, or in conditional requests.")}), - @ApiResponse( - code = 303, - message = "See Other. \n " + - "The source can be retrieved from the URL specified in the location header.\n", - responseHeaders = { - @ResponseHeader( - name = "Content-Location", - description = "The Source URL of the document.")}), - @ApiResponse( - code = 304, - message = "Not Modified. \n " + - "Empty body because the client already has the latest version of the requested resource."), - @ApiResponse( - code = 400, - message = "Bad Request. \n Invalid request or validation error.", - response = ErrorResponse.class), - @ApiResponse( - code = 404, - message = "Not Found. \n The specified device does not exist.", - response = ErrorResponse.class), - @ApiResponse( - code = 406, - message = "Not Acceptable. \n The requested media type is not supported."), - @ApiResponse( - code = 500, - message = "Internal Server Error. \n " + - "Server error occurred while retrieving the operation list scheduled for the device.", - response = ErrorResponse.class) - }) - Response getDeviceOperationsDep( - @ApiParam( - name = "type", - value = "The device type name, such as ios, android, windows or fire-alarm.", - required = true) - @PathParam("type") - @Size(max = 45) - String type, - @ApiParam( - name = "id", - value = "The device identifier of the device you wish to get details.\n" + - "INFO: Make sure to add the ID of a device that is already registered with WSO2 IoTS.", - required = true) - @PathParam("id") - @Size(max = 45) - String id, - @ApiParam( - name = "If-Modified-Since", - value = "Checks if the requested variant was modified, since the specified date-time. \n" + - "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" + - "Example: Mon, 05 Jan 2014 15:10:00 +0200", - required = false) - @HeaderParam("If-Modified-Since") - String ifModifiedSince, - @ApiParam( - name = "offset", - value = "The starting pagination index for the complete list of qualified items.", - required = false, - defaultValue = "0") - @QueryParam("offset") - int offset, - @ApiParam( - name = "limit", - value = "Provide how many activity details you require from the starting pagination index/offset.", - required = false, - defaultValue = "5") - @QueryParam("limit") - int limit); - @GET @Path("/{type}/{id}/effective-policy") @ApiOperation( diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java index b6a0397df0..1d17ac9450 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java @@ -269,149 +269,6 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { } } - @GET - @Path("/v2") - @Deprecated - @Override - public Response getDevicesDep( - @QueryParam("name") String name, - @QueryParam("type") String type, - @QueryParam("user") String user, - @QueryParam("userPattern") String userPattern, - @QueryParam("role") String role, - @QueryParam("ownership") String ownership, - @QueryParam("status") String status, - @QueryParam("groupId") int groupId, - @QueryParam("since") String since, - @HeaderParam("If-Modified-Since") String ifModifiedSince, - @QueryParam("offset") int offset, - @QueryParam("limit") int limit) { - try { - if (!StringUtils.isEmpty(name) && !StringUtils.isEmpty(role)) { - return Response.status(Response.Status.BAD_REQUEST).entity( - new ErrorResponse.ErrorResponseBuilder().setMessage("Request contains both name and role " + - "parameters. Only one is allowed " + - "at once.").build()).build(); - } - RequestValidationUtil.validatePaginationParameters(offset, limit); - DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService(); - DeviceAccessAuthorizationService deviceAccessAuthorizationService = - DeviceMgtAPIUtils.getDeviceAccessAuthorizationService(); - if (deviceAccessAuthorizationService == null) { - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( - new ErrorResponse.ErrorResponseBuilder().setMessage("Device access authorization service is " + - "failed").build()).build(); - } - PaginationRequest request = new PaginationRequest(offset, limit); - PaginationResult result; - DeviceList devices = new DeviceList(); - - if (name != null && !name.isEmpty()) { - request.setDeviceName(name); - } - if (type != null && !type.isEmpty()) { - request.setDeviceType(type); - } - if (ownership != null && !ownership.isEmpty()) { - RequestValidationUtil.validateOwnershipType(ownership); - request.setOwnership(ownership); - } - if (status != null && !status.isEmpty()) { - RequestValidationUtil.validateStatus(status); - request.setStatus(status); - } - if (groupId != 0) { - request.setGroupId(groupId); - } - if (role != null && !role.isEmpty()) { - request.setOwnerRole(role); - } - - String authorizedUser = MultitenantUtils.getTenantAwareUsername(CarbonContext.getThreadLocalCarbonContext().getUsername()); - - if (deviceAccessAuthorizationService.isDeviceAdminUser()) { - if (user != null && !user.isEmpty()) { - request.setOwner(MultitenantUtils.getTenantAwareUsername(user)); - } else if (userPattern != null && !userPattern.isEmpty()) { - request.setOwnerPattern(userPattern); - } - } else { - if (user != null && !user.isEmpty()) { - user = MultitenantUtils.getTenantAwareUsername(user); - if (user.equals(authorizedUser)) { - request.setOwner(user); - } else { - String msg = "User '" + authorizedUser + "' is not authorized to retrieve devices of '" + user - + "' user"; - log.error(msg); - return Response.status(Response.Status.UNAUTHORIZED).entity( - new ErrorResponse.ErrorResponseBuilder().setCode(401l).setMessage(msg).build()).build(); - } - } else { - request.setOwner(authorizedUser); - } - } - - if (ifModifiedSince != null && !ifModifiedSince.isEmpty()) { - Date sinceDate; - SimpleDateFormat format = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z"); - try { - sinceDate = format.parse(ifModifiedSince); - } catch (ParseException e) { - return Response.status(Response.Status.BAD_REQUEST).entity( - new ErrorResponse.ErrorResponseBuilder().setMessage("Invalid date " + - "string is provided in 'If-Modified-Since' header").build()).build(); - } - request.setSince(sinceDate); - result = dms.getAllDevices(request); - - if (result == null || result.getData() == null || result.getData().size() <= 0) { - return Response.status(Response.Status.NOT_MODIFIED).entity("No device is modified " + - "after the timestamp provided in 'If-Modified-Since' header").build(); - } - } else if (since != null && !since.isEmpty()) { - Date sinceDate; - SimpleDateFormat format = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z"); - try { - sinceDate = format.parse(since); - } catch (ParseException e) { - return Response.status(Response.Status.BAD_REQUEST).entity( - new ErrorResponse.ErrorResponseBuilder().setMessage("Invalid date " + - "string is provided in 'since' filter").build()).build(); - } - request.setSince(sinceDate); - result = dms.getAllDevices(request); - - if (result == null || result.getData() == null || result.getData().size() <= 0) { - devices.setList(new ArrayList()); - devices.setCount(0); - return Response.status(Response.Status.OK).entity(devices).build(); - } - } else { - result = dms.getAllDevices(request); - int resultCount = result.getRecordsTotal(); - if (resultCount == 0) { - Response.status(Response.Status.OK).entity(devices).build(); - } - } - - devices.setList((List) result.getData()); - devices.setCount(result.getRecordsTotal()); - return Response.status(Response.Status.OK).entity(devices).build(); - } catch (DeviceManagementException e) { - String msg = "Error occurred while fetching all enrolled devices"; - log.error(msg, e); - return Response.serverError().entity( - new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); - } catch (DeviceAccessAuthorizationException e) { - String msg = "Error occurred while checking device access authorization"; - log.error(msg, e); - return Response.serverError().entity( - new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); - } - } - - @GET @Override @Path("/user-devices") @@ -738,47 +595,8 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { DeviceManagementProviderService dms; try { RequestValidationUtil.validateDeviceIdentifier(type, id); - - dms = DeviceMgtAPIUtils.getDeviceManagementService(); - result = dms.getOperations(new DeviceIdentifier(id, type), request); - - operationsList.setList((List) result.getData()); - operationsList.setCount(result.getRecordsTotal()); - return Response.status(Response.Status.OK).entity(operationsList).build(); - } catch (OperationManagementException e) { - String msg = "Error occurred while fetching the operations for the '" + type + "' device, which " + - "carries the id '" + id + "'"; - log.error(msg, e); - return Response.serverError().entity( - new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); - } - } - - @GET - @Path("/{type}/{id}/operations/v2") - @Deprecated - @Override - public Response getDeviceOperationsDep( - @PathParam("type") @Size(max = 45) String type, - @PathParam("id") @Size(max = 45) String id, - @HeaderParam("If-Modified-Since") String ifModifiedSince, - @QueryParam("offset") int offset, - @QueryParam("limit") int limit) - { - OperationList operationsList = new OperationList(); - String owner = CarbonContext.getThreadLocalCarbonContext().getUsername(); - RequestValidationUtil.validateOwnerParameter(owner); - RequestValidationUtil.validatePaginationParameters(offset, limit); - PaginationRequest request = new PaginationRequest(offset, limit); - request.setOwner(owner); - PaginationResult result; - DeviceManagementProviderService dms; - try { - RequestValidationUtil.validateDeviceIdentifier(type, id); - dms = DeviceMgtAPIUtils.getDeviceManagementService(); result = dms.getOperations(new DeviceIdentifier(id, type), request); - operationsList.setList((List) result.getData()); operationsList.setCount(result.getRecordsTotal()); return Response.status(Response.Status.OK).entity(operationsList).build(); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/pom.xml b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/pom.xml new file mode 100644 index 0000000000..ac4cbe45fb --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/pom.xml @@ -0,0 +1,421 @@ + + + + + + + device-mgt + org.wso2.carbon.devicemgt + 3.0.185-SNAPSHOT + ../pom.xml + + + 4.0.0 + org.wso2.carbon.device.mgt.v09.api + war + WSO2 Carbon - Mobile Device Management v0.9 API + WSO2 Carbon - Mobile Device Management v0.9 API + http://wso2.org + + + + + maven-compiler-plugin + + 1.8 + 1.8 + + + + maven-war-plugin + + WEB-INF/lib/*cxf*.jar + api#device-mgt#v0.9 + + + + org.jacoco + jacoco-maven-plugin + + ${basedir}/target/coverage-reports/jacoco-unit.exec + + + + jacoco-initialize + + prepare-agent + + + + jacoco-site + test + + report + + + ${basedir}/target/coverage-reports/jacoco-unit.exec + ${basedir}/target/coverage-reports/site + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + file:src/test/resources/log4j.properties + + + src/test/resources/testng.xml + + + + + + + + + deploy + + compile + + + org.apache.maven.plugins + maven-antrun-plugin + 1.7 + + + compile + + run + + + + + + + + + + + + + + + + + + client + + test + + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + + test + + java + + + + + + + + + + + + org.apache.cxf + cxf-rt-frontend-jaxws + provided + + + org.apache.cxf + cxf-rt-frontend-jaxrs + provided + + + org.apache.cxf + cxf-rt-transports-http + provided + + + commons-httpclient.wso2 + commons-httpclient + provided + + + javax.ws.rs + jsr311-api + provided + + + org.wso2.carbon + org.wso2.carbon.utils + provided + + + org.wso2.carbon.identity.framework + org.wso2.carbon.user.mgt + provided + + + org.slf4j + slf4j-api + + + org.slf4j + jcl-over-slf4j + + + + + org.wso2.carbon + org.wso2.carbon.logging + provided + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.common + provided + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.analytics.data.publisher + provided + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.extensions + provided + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.core + provided + + + org.apache.axis2.wso2 + axis2-client + + + org.mockito + mockito-core + + + javassist + javassist + + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.policy.mgt.core + provided + + + org.apache.axis2.wso2 + axis2-client + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.core + + + org.mockito + mockito-core + + + + + org.wso2.carbon.identity.inbound.auth.oauth2 + org.wso2.carbon.identity.oauth.stub + provided + + + org.apache.axis2.wso2 + axis2-client + + + + + org.json.wso2 + json + + + commons-codec.wso2 + commons-codec + provided + + + org.wso2.carbon.devicemgt + org.wso2.carbon.certificate.mgt.core + provided + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.core + + + + + io.swagger + swagger-annotations + + + io.swagger + swagger-core + + + com.fasterxml.jackson.module + jackson-module-jaxb-annotations + + + org.slf4j + slf4j-api + + + org.wso2.orbit.com.fasterxml.jackson.core + jackson-core + + + + + io.swagger + swagger-jaxrs + + + com.fasterxml.jackson.module + jackson-module-jaxb-annotations + + + org.slf4j + slf4j-api + + + org.wso2.orbit.com.fasterxml.jackson.core + jackson-core + + + + + javax.servlet + servlet-api + provided + + + org.wso2.carbon.devicemgt + org.wso2.carbon.apimgt.annotations + provided + + + org.wso2.orbit.com.fasterxml.jackson.core + jackson-annotations + + + org.hibernate + hibernate-validator + + + javax.ws.rs + javax.ws.rs-api + + + org.wso2.carbon.commons + org.wso2.carbon.application.mgt.stub + provided + + + org.wso2.carbon.analytics + org.wso2.carbon.analytics.api + provided + + + org.wso2.carbon.analytics + org.wso2.carbon.analytics.datasource.commons + provided + + + org.wso2.carbon.devicemgt + org.wso2.carbon.identity.jwt.client.extension + provided + + + org.wso2.carbon + org.wso2.carbon.registry.core + provided + + + org.wso2.carbon.registry + org.wso2.carbon.registry.resource + provided + + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.user.store.count + ${carbon.identity.framework.version} + provided + + + org.wso2.carbon.analytics + org.wso2.carbon.analytics.dataservice.commons + provided + + + org.wso2.carbon.analytics-common + org.wso2.carbon.event.receiver.stub + provided + + + org.wso2.carbon.analytics-common + org.wso2.carbon.event.stream.stub + provided + + + org.wso2.carbon.analytics-common + org.wso2.carbon.event.publisher.stub + provided + + + org.wso2.carbon.analytics-common + org.wso2.carbon.event.stream.persistence.stub + provided + + + org.wso2.carbon.devicemgt + org.wso2.carbon.apimgt.integration.client + provided + + + org.powermock + powermock-module-testng + test + + + org.powermock + powermock-api-mockito + test + + + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/ApiOriginFilter.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/ApiOriginFilter.java new file mode 100644 index 0000000000..9ba3b5b97b --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/ApiOriginFilter.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs; + +import javax.servlet.*; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class ApiOriginFilter implements Filter { + + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + HttpServletResponse res = (HttpServletResponse) response; + res.addHeader("Access-Control-Allow-Origin", "*"); + res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT"); + res.addHeader("Access-Control-Allow-Headers", "Content-Type"); + chain.doFilter(request, response); + } + + public void destroy() { + //do nothing + } + + public void init(FilterConfig filterConfig) throws ServletException { + //do nothing + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/NotificationContext.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/NotificationContext.java new file mode 100644 index 0000000000..3d7d48c2f3 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/NotificationContext.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.notification.mgt.Notification; + +@ApiModel(value = "NotificationContext") +public class NotificationContext { + + private DeviceIdentifier deviceId; + private Notification notification; + + public NotificationContext(DeviceIdentifier deviceId, Notification notification) { + this.deviceId = deviceId; + this.notification = notification; + } + + @ApiModelProperty(value = "deviceId") + @JsonProperty("deviceId") + public DeviceIdentifier getDeviceId() { + return deviceId; + } + + public void setDeviceId(DeviceIdentifier deviceId) { + this.deviceId = deviceId; + } + + @ApiModelProperty(value = "notification") + @JsonProperty("notification") + public Notification getNotification() { + return notification; + } + + public void setNotification(Notification notification) { + this.notification = notification; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/NotificationList.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/NotificationList.java new file mode 100644 index 0000000000..641bd5c93a --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/NotificationList.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.device.mgt.common.notification.mgt.Notification; + +import java.util.ArrayList; +import java.util.List; + +@ApiModel(value = "Notifications") +public class NotificationList { + + private int count; + private String next; + private String previous; + + private List notifications = new ArrayList<>(); + + /** + * Number of notifications returned. + */ + @ApiModelProperty(value = "Number of Devices returned.") + @JsonProperty("count") + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + + /** + * Link to the next subset of resources qualified. \nEmpty if no more resources are to be returned. + */ + @ApiModelProperty(value = "Link to the next subset of resources qualified. \n " + + "Empty if no more resources are to be returned.") + @JsonProperty("next") + public String getNext() { + return next; + } + + public void setNext(String next) { + this.next = next; + } + + /** + * Link to the previous subset of resources qualified. \nEmpty if current subset is the first subset returned. + */ + @ApiModelProperty(value = "Link to the previous subset of resources qualified. \n" + + "Empty if current subset is the first subset returned.") + @JsonProperty("previous") + public String getPrevious() { + return previous; + } + + public void setPrevious(String previous) { + this.previous = previous; + } + + /** + **/ + @ApiModelProperty(value = "List of devices returned") + @JsonProperty("devices") + public List getList() { + return notifications; + } + + public void setList(List notifications) { + this.notifications = notifications; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("{\n"); + + sb.append(" count: ").append(count).append(",\n"); + sb.append(" next: ").append(next).append(",\n"); + sb.append(" previous: ").append(previous).append(",\n"); + sb.append(" notifications: [").append(notifications).append("\n"); + sb.append("]}\n"); + return sb.toString(); + } + + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ActivityList.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ActivityList.java new file mode 100644 index 0000000000..08e6f268df --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ActivityList.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; + +import java.util.ArrayList; +import java.util.List; + +@ApiModel(value = "List of activities", description = "This contains a set of activities that matches a given" + + " criteria as a collection") +public class ActivityList extends BasePaginatedResult { + + private List activities; + + @ApiModelProperty(value = "Returns the list of activities that match the offset and limit parameter values" + + " that were specified.") + @JsonProperty("activities") + public List getList() { + return activities; + } + + public void setList(List activities) { + this.activities = activities; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("{\n"); + sb.append(" count: ").append(getCount()).append(",\n"); + sb.append(" devices: [").append(activities).append("\n"); + sb.append("]}\n"); + return sb.toString(); + } + + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ApplicationWrapper.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ApplicationWrapper.java new file mode 100644 index 0000000000..39d6de263e --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ApplicationWrapper.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; + +import java.util.List; + + +@ApiModel(value = "ApplicationWrapper", description = "Application details together with user, " + + "role or devices the application is associated with.") +public class ApplicationWrapper { + + @ApiModelProperty( + name = "userNameList", + value = "List of user names.", + required = true) + private List userNameList; + + @ApiModelProperty( + name = "roleNameList", + value = "List of role names.", + required = true) + private List roleNameList; + + @ApiModelProperty( + name = "deviceIdentifiers", + value = "List of device identifiers.", + required = true, + dataType = "List[org.wso2.carbon.device.mgt.common.DeviceIdentifier]") + private List deviceIdentifiers; + + @ApiModelProperty( + name = "application", + value = "Details of the mobile application.", + required = true) + private MobileApp application; + + public MobileApp getApplication() { + return application; + } + + public void setApplication(MobileApp application) { + this.application = application; + } + + public List getUserNameList() { + return userNameList; + } + + public void setUserNameList(List userNameList) { + this.userNameList = userNameList; + } + + public List getRoleNameList() { + return roleNameList; + } + + public void setRoleNameList(List roleNameList) { + this.roleNameList = roleNameList; + } + + public List getDeviceIdentifiers() { + return deviceIdentifiers; + } + + public void setDeviceIdentifiers(List deviceIdentifiers) { + this.deviceIdentifiers = deviceIdentifiers; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/AuthorizationRequest.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/AuthorizationRequest.java new file mode 100644 index 0000000000..d37183abc7 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/AuthorizationRequest.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; + +import java.util.List; + +@ApiModel(value = "AuthorizationRequest", description = "Authorization details together with deviceIdentifier and permission") +public class AuthorizationRequest { + + @ApiModelProperty(name = "tenantDomain", value = "tenant domain.", required = false) + String tenantDomain; + @ApiModelProperty(name = "username", value = "username of the user, to whom the device identifiers needs to be verified", required = true) + String username; + @ApiModelProperty(name = "deviceIdentifiers", value = "list of devices that needs to be verified against the user", required = true) + List deviceIdentifiers; + @ApiModelProperty(name = "permission", value = "if null then checks against the owner else it could be grouping permission", required = false) + List permissions; + + public String getTenantDomain() { + return tenantDomain; + } + + public void setTenantDomain(String tenantDomain) { + this.tenantDomain = tenantDomain; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public List getDeviceIdentifiers() { + return deviceIdentifiers; + } + + public void setDeviceIdentifiers(List deviceIdentifiers) { + this.deviceIdentifiers = deviceIdentifiers; + } + + public List getPermissions() { + return permissions; + } + + public void setPermissions(List permissions) { + this.permissions = permissions; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/BasePaginatedResult.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/BasePaginatedResult.java new file mode 100644 index 0000000000..5c2936a1a3 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/BasePaginatedResult.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; + +public class BasePaginatedResult { + + /** + * Number of Resources returned. + */ + @ApiModelProperty( + value = "Number of total resources.", + example = "1") + @JsonProperty("count") + private long count; + + public long getCount() { + return count; + } + + public void setCount(long count) { + this.count = count; + } +} \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/BasicUserInfo.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/BasicUserInfo.java new file mode 100644 index 0000000000..d7c82a9edc --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/BasicUserInfo.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +@ApiModel(value = "BasicUserInfo", description = "Basic user information and the roles of the user.") +public class BasicUserInfo { + + @ApiModelProperty(name = "username", value = "The login name of the user.", required = true ) + private String username; + @ApiModelProperty(name = "firstname", value = "The first name of the user.", required = true ) + private String firstname; + @ApiModelProperty(name = "lastname", value = "The last name of the user.", required = true ) + private String lastname; + @ApiModelProperty(name = "emailAddress", value = "The email address of the user.", required = true ) + private String emailAddress; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getFirstname() { + return firstname; + } + + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + public String getLastname() { + return lastname; + } + + public void setLastname(String lastname) { + this.lastname = lastname; + } + + public String getEmailAddress() { + return emailAddress; + } + + public void setEmailAddress(String emailAddress) { + this.emailAddress = emailAddress; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/BasicUserInfoList.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/BasicUserInfoList.java new file mode 100644 index 0000000000..3cf94cbb97 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/BasicUserInfoList.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.ArrayList; +import java.util.List; + +@ApiModel(value = "BasicUserInfoList", description = "This contains basic details of a set of users that matches " + + "a given criteria as a collection") +public class BasicUserInfoList extends BasePaginatedResult { + + private List users = new ArrayList<>(); + + @ApiModelProperty(value = "List of devices returned") + @JsonProperty("users") + public List getList() { + return users; + } + + public void setList(List users) { + this.users = users; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("{\n"); + + sb.append(" count: ").append(getCount()).append(",\n"); + sb.append(" users: [").append(users).append("\n"); + sb.append("]}\n"); + return sb.toString(); + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/BasicUserInfoWrapper.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/BasicUserInfoWrapper.java new file mode 100644 index 0000000000..651b4766b3 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/BasicUserInfoWrapper.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +@ApiModel(value = "BasicUserInfoWrapper", description = "This contains basic details of a set of users that matches " + + "a given criteria as a collection and a message if there's any.") +public class BasicUserInfoWrapper { + + @ApiModelProperty( + name = "basicUserInfo", + value = "Details of the User.", + required = true) + private BasicUserInfo basicUserInfo; + + @ApiModelProperty( + name = "message", + value = "Response message if there's any.") + private String message; + + public BasicUserInfo getBasicUserInfo() { + return basicUserInfo; + } + + public void setBasicUserInfo(BasicUserInfo basicUserInfo) { + this.basicUserInfo = basicUserInfo; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DashboardGadgetDataWrapper.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DashboardGadgetDataWrapper.java new file mode 100644 index 0000000000..7e4436e597 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DashboardGadgetDataWrapper.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import java.util.List; + +public class DashboardGadgetDataWrapper { + + private String context; + private String groupingAttribute; + private List data; + + @SuppressWarnings("unused") + public String getContext() { + return context; + } + + public void setContext(String context) { + this.context = context; + } + + @SuppressWarnings("unused") + public String getGroupingAttribute() { + return groupingAttribute; + } + + public void setGroupingAttribute(String groupingAttribute) { + this.groupingAttribute = groupingAttribute; + } + + @SuppressWarnings("unused") + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DashboardPaginationGadgetDataWrapper.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DashboardPaginationGadgetDataWrapper.java new file mode 100644 index 0000000000..c78f63f5c0 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DashboardPaginationGadgetDataWrapper.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.beans; + +public class DashboardPaginationGadgetDataWrapper extends DashboardGadgetDataWrapper { + + private int totalRecordCount; + + @SuppressWarnings("unused") + public int getTotalRecordCount() { + return totalRecordCount; + } + + public void setTotalRecordCount(int totalRecordCount) { + this.totalRecordCount = totalRecordCount; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DeviceCompliance.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DeviceCompliance.java new file mode 100644 index 0000000000..270d01bf76 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DeviceCompliance.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import io.swagger.annotations.ApiModel; +import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.NonComplianceData; + +@ApiModel(value = "DeviceCompliance", description = "Device's policy compliance status") +public class DeviceCompliance { + + private String deviceID; + private NonComplianceData complianceData; + private Long code; + + public NonComplianceData getComplianceData() { + return complianceData; + } + + public void setComplianceData(NonComplianceData complianceData) { + this.complianceData = complianceData; + } + + public Long getCode() { + return code; + } + + public void setCode(Long code) { + this.code = code; + } + + public String getDeviceID() { + return deviceID; + } + + public void setDeviceID(String deviceID) { + this.deviceID = deviceID; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DeviceGroupList.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DeviceGroupList.java new file mode 100644 index 0000000000..3e588444da --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DeviceGroupList.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; + +import java.util.ArrayList; +import java.util.List; + +public class DeviceGroupList extends BasePaginatedResult { + + @ApiModelProperty(value = "List of device groups returned") + @JsonProperty("groups") + private List deviceGroups = new ArrayList<>(); + + public List getList() { + return deviceGroups; + } + + public void setList(List deviceGroups) { + this.deviceGroups = deviceGroups; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("{\n"); + sb.append(" count: ").append(getCount()).append(",\n"); + sb.append(" groups: [").append(deviceGroups).append("\n"); + sb.append("]}\n"); + return sb.toString(); + } + +} + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DeviceList.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DeviceList.java new file mode 100644 index 0000000000..5adb83af03 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DeviceList.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.device.mgt.common.Device; + +import java.util.ArrayList; +import java.util.List; + +public class DeviceList extends BasePaginatedResult { + + private List devices = new ArrayList<>(); + + @ApiModelProperty(value = "List of devices returned") + @JsonProperty("devices") + public List getList() { + return devices; + } + + public void setList(List devices) { + this.devices = devices; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("{\n"); + + sb.append(" count: ").append(getCount()).append(",\n"); + sb.append(" devices: [").append(devices).append("\n"); + sb.append("]}\n"); + return sb.toString(); + } + +} + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DeviceToGroupsAssignment.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DeviceToGroupsAssignment.java new file mode 100644 index 0000000000..ef696f0c27 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DeviceToGroupsAssignment.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.jaxrs.beans.BasePaginatedResult; + +import java.util.ArrayList; +import java.util.List; + +public class DeviceToGroupsAssignment extends BasePaginatedResult { + + @ApiModelProperty(value = "List of device group ids.") + @JsonProperty("deviceGroupIds") + private List deviceGroupIds = new ArrayList<>(); + + @ApiModelProperty(value = "Device identifier of the device needed to be assigned with group") + @JsonProperty("deviceIdentifier") + private DeviceIdentifier deviceIdentifier; + + + public List getDeviceGroupIds() { + return deviceGroupIds; + } + + public void setDeviceGroupIds(List deviceGroupIds) { + this.deviceGroupIds = deviceGroupIds; + } + + public DeviceIdentifier getDeviceIdentifier() { + return deviceIdentifier; + } + + public void setDeviceIdentifier(DeviceIdentifier deviceIdentifier) { + this.deviceIdentifier = deviceIdentifier; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DeviceTypeList.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DeviceTypeList.java new file mode 100644 index 0000000000..c33150631e --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/DeviceTypeList.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.device.mgt.common.Device; + +import java.util.ArrayList; +import java.util.List; + +public class DeviceTypeList { + + private int count; + private String next; + private String previous; + private List deviceTypes = new ArrayList<>(); + + /** + * Number of Devices Types returned. + */ + @ApiModelProperty(value = "Number of resources returned.") + @JsonProperty("count") + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + + /** + * Link to the next subset of resources qualified. \nEmpty if no more resources are to be returned. + */ + @ApiModelProperty(value = "Link to the next subset of resources qualified. \n " + + "Empty if no more resources are to be returned.") + @JsonProperty("next") + public String getNext() { + return next; + } + + public void setNext(String next) { + this.next = next; + } + + /** + * Link to the previous subset of resources qualified. \nEmpty if current subset is the first subset returned. + */ + @ApiModelProperty(value = "Link to the previous subset of resources qualified. \n" + + "Empty if current subset is the first subset returned.") + @JsonProperty("previous") + public String getPrevious() { + return previous; + } + + public void setPrevious(String previous) { + this.previous = previous; + } + + @ApiModelProperty(value = "List of device types returned") + @JsonProperty("devicesTypes") + public List getList() { + return deviceTypes; + } + + public void setList(List deviceTypes) { + this.deviceTypes = deviceTypes; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("{\n"); + + sb.append(" count: ").append(getCount()).append(",\n"); + sb.append(" deviceTypes: [").append(deviceTypes).append("\n"); + sb.append("]}\n"); + return sb.toString(); + } + + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/EnrollmentCertificate.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/EnrollmentCertificate.java new file mode 100644 index 0000000000..d6a79db6f9 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/EnrollmentCertificate.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +@ApiModel(value = "EnrollmentCertificate", description = "Details of certificates used in enrollment.") +public class EnrollmentCertificate { + + @ApiModelProperty(name = "serial", value = "The unique ID used to identify a certificate. This is the devices " + + "serial number in case of mutual SSL is used for enrollment.", + required = true ) + String serial; + @ApiModelProperty(name = "pem", value = "Case 64 encode .pem file content.", required = true ) + String pem; + @ApiModelProperty(name = "tenantId", value = "The ID of the tenant who adds the certificate.", required = true ) + int tenantId; + + public int getTenantId() { + return tenantId; + } + + public void setTenantId(int tenantId) { + this.tenantId = tenantId; + } + + public String getSerial() { + return serial; + } + + public void setSerial(String serial) { + this.serial = serial; + } + + public String getPem() { + return pem; + } + + public void setPem(String pem) { + this.pem = pem; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/EnrollmentInvitation.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/EnrollmentInvitation.java new file mode 100644 index 0000000000..5703339a39 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/EnrollmentInvitation.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.List; + +@ApiModel(value = "EnrollmentInvitation", description = "Holds data to send enrollment invitation to list of recipients.") +public class EnrollmentInvitation { + + @ApiModelProperty(name = "deviceType", value = "Device type name.", required = true) + private String deviceType; + + @ApiModelProperty(name = "recipients", value = "List of recipients.", required = true) + private List recipients; + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public List getRecipients() { + return recipients; + } + + public void setRecipients(List recipients) { + this.recipients = recipients; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ErrorListItem.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ErrorListItem.java new file mode 100644 index 0000000000..bc63ac10b1 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ErrorListItem.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.NotNull; + +@ApiModel(description = "") +public class ErrorListItem { + + @NotNull + private String code = null; + @NotNull + private String message = null; + + @ApiModelProperty(required = true, value = "") + @JsonProperty("code") + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + + public ErrorListItem() {} + + public ErrorListItem(String code, String msg) { + this.code = code; + this.message = msg; + } + + + /** + * Description about individual errors occurred + **/ + @ApiModelProperty(required = true, value = "Description about individual errors occurred") + @JsonProperty("message") + public String getMessage() { + return message; + } + public void setMessage(String message) { + this.message = message; + } + + + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("errorItem {\n"); + + sb.append(" code: ").append(code).append("\n"); + sb.append(" message: ").append(message).append("\n"); + sb.append("}\n"); + return sb.toString(); + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ErrorResponse.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ErrorResponse.java new file mode 100644 index 0000000000..c695932eae --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ErrorResponse.java @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.ArrayList; +import java.util.List; + +@ApiModel(description = "") +public class ErrorResponse { + + private Long code = null; + private String message = null; + private String description = null; + private String moreInfo = null; + private List errorItems = new ArrayList<>(); + + public ErrorResponse() { + } + + @JsonProperty(value = "code") + @ApiModelProperty(required = true, value = "") + public Long getCode() { + return code; + } + + public void setCode(Long code) { + this.code = code; + } + + @JsonProperty(value = "message") + @ApiModelProperty(required = true, value = "ErrorResponse message.") + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + @JsonProperty(value = "description") + @ApiModelProperty(value = "A detail description about the error message.") + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @JsonProperty(value = "moreInfo") + @ApiModelProperty(value = "Preferably an url with more details about the error.") + public String getMoreInfo() { + return moreInfo; + } + + public void setMoreInfo(String moreInfo) { + this.moreInfo = moreInfo; + } + + public void addErrorListItem(ErrorListItem item) { + this.errorItems.add(item); + } + + /** + * If there are more than one error list them out. \nFor example, list out validation errors by each field. + */ + @JsonProperty(value = "errorItems") + @ApiModelProperty(value = "If there are more than one error list them out. \n" + + "For example, list out validation errors by each field.") + public List getErrorItems() { + return errorItems; + } + + public void setErrorItems(List error) { + this.errorItems = error; + } + + @Override + public String toString() { +// StringBuilder sb = new StringBuilder(); +// sb.append("{"); +// boolean cont = false; +// if (code != null) { +// cont = true; +// sb.append(" \"code\": ").append(code); +// } +// if (message != null) { +// if (cont) { +// sb.append(","); +// } +// cont = true; +// sb.append(" \"message\": \"").append(message).append("\""); +// } +// if (description != null) { +// if (cont) { +// sb.append(","); +// } +// cont = true; +// sb.append(" \"description\": ").append(description).append("\""); +// } +// if (moreInfo != null) { +// if (cont) { +// sb.append(","); +// } +// cont = true; +// sb.append(" \"moreInfo\": \"").append(moreInfo).append("\""); +// } +// if (error != null && error.size() > 0) { +// if (cont) { +// sb.append(","); +// } +// sb.append(" \"errorItems\": ").append(error); +// } +// sb.append("}"); +// return sb.toString(); + return null; + } + + public static class ErrorResponseBuilder { + + private Long code = null; + private String message = null; + private String description = null; + private String moreInfo = null; + private List error; + + + public ErrorResponseBuilder() { + this.error = new ArrayList<>(); + } + + public ErrorResponseBuilder setCode(long code) { + this.code = code; + return this; + } + + public ErrorResponseBuilder setMessage(String message) { + this.message = message; + return this; + } + + public ErrorResponseBuilder setDescription(String description) { + this.description = description; + return this; + } + + public ErrorResponseBuilder setMoreInfo(String moreInfo) { + this.moreInfo = moreInfo; + return this; + } + + public ErrorResponseBuilder addErrorItem(String code, String msg) { + ErrorListItem item = new ErrorListItem(); + item.setCode(code); + item.setMessage(msg); + this.error.add(item); + return this; + } + + public ErrorResponse build() { + ErrorResponse errorResponse = new ErrorResponse(); + errorResponse.setCode(code); + errorResponse.setMessage(message); + errorResponse.setErrorItems(error); + errorResponse.setDescription(description); + errorResponse.setMoreInfo(moreInfo); + return errorResponse; + } + } + +} + + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/MobileApp.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/MobileApp.java new file mode 100644 index 0000000000..fe7f4e0268 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/MobileApp.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.Properties; + +/** + * This class represents the generic mobile AuthenticationImpl information + * which is used by AppM. + */ +@ApiModel(value = "MobileApp", description = "Details of a mobile application.") +public class MobileApp { + + @ApiModelProperty(name = "id", value = "Id of the app used internally.", required = true) + private String id; + @ApiModelProperty(name = "name", value = "The name of the application.", required = true) + private String name; + @ApiModelProperty(name = "type", value = "The type of the application. The following types of applications are " + + "supported: enterprise, public and webapp..", required = true) + private MobileAppTypes type; + @ApiModelProperty(name = "platform", value = "Platform the app can be installed on .", required = true) + private String platform; + @ApiModelProperty(name = "version", value = "Version of the application.", required = true) + private String version; + @ApiModelProperty(name = "identifier", value = "The package name of the application.", required = true) + private String identifier; + @ApiModelProperty(name = "iconImage", value = "Link to the icon of the app.", required = true) + private String iconImage; + @ApiModelProperty(name = "packageName", value = "Define the exact name of the application package. You can use one " + + "of the following methods to get the package name.\n" + + "Go to the respective application in the play store and copy the" + + " ID or package name from the URL.\n" + + "Example: The play store application URL for the Viber app is " + + "https://play.google.com/store/apps/details?id=com.viber.voip&hl=en." + + " Therefore, the package name or " + + "the application ID is: id=com.viber.voip \n" + + "Download the System Info for Android to your device from the" + + " play store. \n" + + "Once the application is successfully installed go to the Tasks " + + "tab and you will see the package name under the respective " + + "application..", required = true) + private String packageName; + @ApiModelProperty(name = "appIdentifier", value = "The package name of the application.", required = true) + private String appIdentifier; + private String location; + @ApiModelProperty(name = "properties", value = "List of meta data.", required = true) + private Properties properties; + + public MobileAppTypes getType() { + return type; + } + + public void setType(MobileAppTypes type) { + this.type = type; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPlatform() { + return platform; + } + + public void setPlatform(String platform) { + this.platform = platform; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getIdentifier() { + return identifier; + } + + public void setIdentifier(String identifier) { + this.identifier = identifier; + } + + public String getIconImage() { + return iconImage; + } + + public void setIconImage(String iconImage) { + this.iconImage = iconImage; + } + + public String getPackageName() { + return packageName; + } + + public void setPackageName(String packageName) { + this.packageName = packageName; + } + + public String getAppIdentifier() { + return appIdentifier; + } + + public void setAppIdentifier(String appIdentifier) { + this.appIdentifier = appIdentifier; + } + + public String getLocation() { + return location; + } + + public void setLocation(String location) { + this.location = location; + } + + public Properties getProperties() { + return properties; + } + + public void setProperties(Properties properties) { + this.properties = properties; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/MobileAppTypes.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/MobileAppTypes.java new file mode 100644 index 0000000000..3997da90d7 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/MobileAppTypes.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.beans; + +public enum MobileAppTypes { + ENTERPRISE,WEBAPP,PUBLIC +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/NotificationList.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/NotificationList.java new file mode 100644 index 0000000000..7a7b013b0e --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/NotificationList.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.device.mgt.common.notification.mgt.Notification; + +import java.util.List; + +@ApiModel(value = "notificationList") +public class NotificationList extends BasePaginatedResult { + + private List notifications; + + @JsonProperty("notifications") + @ApiModelProperty("notifications") + public List getNotifications() { + return notifications; + } + + public void setNotifications(List notifications) { + this.notifications = notifications; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("{"); + + sb.append(" count: ").append(getCount()).append(","); + sb.append(" notifications: [").append(notifications).append(""); + sb.append("]}"); + return sb.toString(); + } + + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/OldPasswordResetWrapper.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/OldPasswordResetWrapper.java new file mode 100644 index 0000000000..bbd8a3dcdf --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/OldPasswordResetWrapper.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +@ApiModel(value = "OldPasswordResetWrapper", description = "User credentials are included in this class.") +public class OldPasswordResetWrapper extends PasswordResetWrapper{ + + /* + Base64 encoded password + */ + @ApiModelProperty( + name = "oldPassword", + value = "Old password of the user.", + required = true ) + private String oldPassword; + + public String getOldPassword() { + return oldPassword; + } + + public void setOldPassword(String oldPassword) { + this.oldPassword = oldPassword; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/OperationList.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/OperationList.java new file mode 100644 index 0000000000..855f682f1b --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/OperationList.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; + +import java.util.List; + +public class OperationList extends BasePaginatedResult { + private List operations; + + @ApiModelProperty(value = "List of operations returned") + @JsonProperty("operations") + public List getList() { + return operations; + } + + public void setList(List operations) { + this.operations = operations; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("{\n"); + sb.append(" count: ").append(getCount()).append(",\n"); + sb.append(" operations: [").append(operations).append("\n"); + sb.append("]}\n"); + return sb.toString(); + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/OperationRequest.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/OperationRequest.java new file mode 100644 index 0000000000..d8cd2ec769 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/OperationRequest.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; + +import java.util.List; + +@ApiModel(value = "OperationRequest", description = "Operation details together with deviceIdentifier") +public class OperationRequest { + + @ApiModelProperty(name = "deviceIdentifiers", value = "list of devices that needs to be verified against the user", required = true) + List deviceIdentifiers; + @ApiModelProperty(name = "operation", value = "operation data", required = false) + Operation operation; + + public List getDeviceIdentifiers() { + return deviceIdentifiers; + } + + public void setDeviceIdentifiers(List deviceIdentifiers) { + this.deviceIdentifiers = deviceIdentifiers; + } + + public Operation getOperation() { + return operation; + } + + public void setOperation(Operation operation) { + this.operation = operation; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/PasswordResetWrapper.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/PasswordResetWrapper.java new file mode 100644 index 0000000000..ae28860466 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/PasswordResetWrapper.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +@ApiModel(value = "PasswordResetWrapper", description = "User credential is included in this class.") +public class PasswordResetWrapper { + + /* + Base64 encoded password + */ + @ApiModelProperty( + name = "newPassword", + value = "New password of the user.", + required = true, + example = "JiM&100%pW") + private String newPassword; + + public String getNewPassword() { + return newPassword; + } + + public void setNewPassword(String newPassword) { + this.newPassword = newPassword; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/PolicyList.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/PolicyList.java new file mode 100644 index 0000000000..714bcd09c7 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/PolicyList.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.device.mgt.common.policy.mgt.Policy; + +import java.util.List; + +@ApiModel(value = "Policy List") +public class PolicyList extends BasePaginatedResult { + + private List policies; + + @ApiModelProperty(value = "Returns the list of policies that match the offset and limit parameter values" + + " that were specified.") + @JsonProperty("policies") + public List getList() { + return policies; + } + + public void setList(List policies) { + this.policies = policies; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("{\n"); + sb.append(" count: ").append(getCount()).append(",\n"); + sb.append(" policies: [").append(policies).append("\n"); + sb.append("]}\n"); + return sb.toString(); + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/PolicyWrapper.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/PolicyWrapper.java new file mode 100644 index 0000000000..06e99cd74d --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/PolicyWrapper.java @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.policy.mgt.DeviceGroupWrapper; + +import javax.validation.constraints.Size; +import java.util.List; + +@ApiModel(value = "PolicyWrapper", description = "This class carries all information related to Policy " + + "Wrappers") +public class PolicyWrapper { + + @ApiModelProperty( + name = "policyName", + value = "The name of the policy", + required = true) + @Size(max = 45) + private String policyName; + + @ApiModelProperty( + name = "description", + value = "Gives a description on the policy", + required = true) + @Size(max = 1000) + private String description; + + @ApiModelProperty( + name = "compliance", + value = "Provides the non-compliance rules. WSO2 EMM provides the following non-compliance rules:\n" + + "Enforce - Forcefully enforce the policies on the devices\n" + + "Warning - If the device does not adhere to the given policies a warning message will be sent\n" + + "Monitor - If the device does not adhere to the given policies the server is notified of the " + + "violation unknown to the user and the administrator can take the necessary actions with regard" + + " to the reported", + required = true) + @Size(max = 100) + private String compliance; + + @ApiModelProperty( + name = "ownershipType", + value = "The policy ownership type. It can be any of the following values:\n" + + "ANY - The policy will be applied on the BYOD and COPE device types\n" + + "BYOD (Bring Your Own Device) - The policy will only be applied on the BYOD device type\n" + + "COPE (Corporate-Owned, Personally-Enabled) - The policy will only be applied on the COPE " + + "device type", + required = true) + @Size(max = 45) + private String ownershipType; + + @ApiModelProperty( + name = "active", + value = "If the value is true it indicates that the policy is active. If the value is false it " + + "indicates that the policy is inactive", + required = true) + private boolean active; + + @ApiModelProperty( + name = "profile", + value = "Contains the details of the profile that is included in the policy", + required = true) + private Profile profile; + + @ApiModelProperty( + name = "roles", + value = "The roles to whom the policy is applied on", + required = true) + private List roles; + + @ApiModelProperty( + name = "deviceIdentifiers", + value = "Lists out the devices the policy is enforced on", + required = true) + private List deviceIdentifiers; + + @ApiModelProperty( + name = "users", + value = "Lists out the users on whose devices the policy is enforced", + required = true) + private List users; + + @ApiModelProperty(name = "deviceGroups", value = "Lists out the groups on whose devices the policy is enforced", + required = true) + private List deviceGroups; + + public Profile getProfile() { + return profile; + } + + public void setProfile(Profile profile) { + this.profile = profile; + } + + public String getCompliance() { + return compliance; + } + + public void setCompliance(String compliance) { + this.compliance = compliance; + } + + public String getPolicyName() { + return policyName; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public void setPolicyName(String policyName) { + this.policyName = policyName; + } + + public List getRoles() { + return roles; + } + + public void setRoles(List roles) { + this.roles = roles; + } + + public String getOwnershipType() { + return ownershipType; + } + + public void setOwnershipType(String ownershipType) { + this.ownershipType = ownershipType; + } + + public boolean isActive() { + return active; + } + + public void setActive(boolean active) { + this.active = active; + } + + public List getDeviceIdentifiers() { + return deviceIdentifiers; + } + + public void setDeviceIdentifier(List deviceIdentifiers) { + this.deviceIdentifiers = deviceIdentifiers; + } + + public List getUsers() { + return users; + } + + public void setUsers(List users) { + this.users = users; + } + + public List getDeviceGroups() { + return deviceGroups; + } + + public void setDeviceGroups(List deviceGroups) { + this.deviceGroups = deviceGroups; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/PriorityUpdatedPolicyWrapper.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/PriorityUpdatedPolicyWrapper.java new file mode 100644 index 0000000000..56a4764d0b --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/PriorityUpdatedPolicyWrapper.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +@ApiModel(value = "PriorityUpdatedPolicyWrapper", description = "This class carries all information related " + + "to Priority Updated Policy Wrapper ") +public class PriorityUpdatedPolicyWrapper { + + @ApiModelProperty(name = "id", value = "Define the ID of the policy", required = true) + private int id; + @ApiModelProperty(name = "priority", value = "Define the priority of the order, where 1 indicates the " + + "highest priority", required = true) + private int priority; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getPriority() { + return priority; + } + + public void setPriority(int priority) { + this.priority = priority; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/Profile.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/Profile.java new file mode 100644 index 0000000000..89f0dbff7d --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/Profile.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.sql.Timestamp; +import java.util.List; + +@XmlRootElement +@ApiModel(value = "Profile", description = "This class carries all information related to policy profiles") +public class Profile { + + @ApiModelProperty(name = "profileId", + value = "The ID of each profile that is in the selected policy", + required = true, + example = "1") + private int profileId; + @ApiModelProperty(name = "profileName", + value = "The name of the profile", + required = true, + example = "Block Camera") + private String profileName; + @ApiModelProperty(name = "tenantId", + value = "The ID of the tenant that added the policy", + required = true, + example = "-1234") + private int tenantId; + @ApiModelProperty(name = "deviceType", + value = "Contains the device type details the policy was created for", + required = true, + example = "android") + private String deviceType; + @ApiModelProperty(name = "createdDate", + value = "The date the policy was created", + required = true, + example = "Thu, 6 Oct 2016 14:39:32 +0530") + private Timestamp createdDate; + @ApiModelProperty(name = "updatedDate", + value = "The date the changes made to the policy was published to the devices registered with the EMM", + required = true, + example = "Thu, 6 Oct 2016 14:39:32 +0530") + private Timestamp updatedDate; + @ApiModelProperty(name = "profileFeaturesList", + value = "Contains the features specific to each profile in the policy", + required = true) + private List profileFeaturesList; // Features included in the policies. + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + @XmlElement + public int getTenantId() { + return tenantId; + } + + public void setTenantId(int tenantId) { + this.tenantId = tenantId; + } + +/* public List getFeaturesList() { + return featuresList; + } + + public void setFeaturesList(List featuresList) { + this.featuresList = featuresList; + }*/ + @XmlElement + public int getProfileId() { + return profileId; + } + + public void setProfileId(int profileId) { + this.profileId = profileId; + } + + @XmlElement + public String getProfileName() { + return profileName; + } + + public void setProfileName(String profileName) { + this.profileName = profileName; + } + + @XmlElement + public Timestamp getCreatedDate() { + return createdDate; + } + + public void setCreatedDate(Timestamp createdDate) { + this.createdDate = createdDate; + } + + @XmlElement + public Timestamp getUpdatedDate() { + return updatedDate; + } + + public void setUpdatedDate(Timestamp updatedDate) { + this.updatedDate = updatedDate; + } + + @XmlElement + public List getProfileFeaturesList() { + return profileFeaturesList; + } + + public void setProfileFeaturesList(List profileFeaturesList) { + this.profileFeaturesList = profileFeaturesList; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ProfileFeature.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ProfileFeature.java new file mode 100644 index 0000000000..b32c7613f4 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ProfileFeature.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import com.google.gson.Gson; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; + +@ApiModel(value = "ProfileFeature", description = "This class carries all information related to profile " + + "features") +public class ProfileFeature implements Serializable { + + @ApiModelProperty(name = "id", + value = "Define the ID", + required = true, + example = "1") + private int id; + @ApiModelProperty(name = "featureCode", + value = "Provide the code that defines the policy you wish to add", + required = true, + example = "CAMERA") + private String featureCode; + @ApiModelProperty(name = "profileId", + value = "Define the ID of the profile", + required = true, + example = "1") + private int profileId; + @ApiModelProperty(name = "deviceTypeId", + value = "The ID used to define the type of the device platform", + required = true, + example = "android") + private String deviceType; + @ApiModelProperty(name = "content", + value = "The list of parameters that define the policy", + required = true, + example = "{\\\"enabled\\\":false}") + private Object content; + @ApiModelProperty(name = "payLoad", + value = "The payload which is submitted to each feature", + required = true) + private String payLoad; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getFeatureCode() { + return featureCode; + } + + public void setFeatureCode(String featureCode) { + this.featureCode = featureCode; + } + + public int getProfileId() { + return profileId; + } + + public void setProfileId(int profileId) { + this.profileId = profileId; + } + + public String getDeviceTypeId() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + + public String getPayLoad() { + Gson gson = new Gson(); + this.payLoad = gson.toJson(content); + return payLoad; + } + + public void setPayLoad(String payLoad) { + this.payLoad = payLoad; + } + + + public Object getContent() { + return content; + } + + public void setContent(Object content) { + this.content = content; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/RemoteSessionInfo.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/RemoteSessionInfo.java new file mode 100644 index 0000000000..34883532f1 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/RemoteSessionInfo.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; + +import java.util.List; + +@ApiModel(value = "RemoteSessionInfo", description = "Template of the remote session") +public class RemoteSessionInfo { + + @ApiModelProperty(name = "Server Url", value = "Url of the remote session server.", required = true) + private String serverUrl; + + @ApiModelProperty(name = "isEnabled", value = "Is remote session functionality enabled", required = true) + private Boolean isEnabled; + + public String getServerUrl() { + return serverUrl; + } + + public void setServerUrl(String serverUrl) { + this.serverUrl = serverUrl; + } + + public Boolean getEnabled() { + return isEnabled; + } + + public void setEnabled(Boolean enabled) { + isEnabled = enabled; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/RoleInfo.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/RoleInfo.java new file mode 100644 index 0000000000..80ed6c8b2a --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/RoleInfo.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.user.mgt.common.UIPermissionNode; + +import java.util.List; + +@ApiModel(value = "RoleInfo", description = "Role details including permission and the users in the roles are " + + "wrapped here.") +public class RoleInfo { + + @ApiModelProperty(name = "roleName", value = "The name of the role.", required = true) + private String roleName; + @ApiModelProperty(name = "permissions", value = "Lists out all the permissions associated with roles.", + required = true, dataType = "List[java.lang.String]") + private String[] permissions; + @ApiModelProperty(name = "users", value = "The list of users assigned to the selected role.", + required = true, dataType = "List[java.lang.String]") + private String[] users; + @ApiModelProperty(name = "permissionList", value = "This contain the following, " + + "\n resourcePath\tThe path related to the API.\n " + + "displayName\tThe name of the permission that is shown " + + "in the UI.\n" + + "nodeList\tLists out the nested permissions.", + required = true) + private UIPermissionNode permissionList; + + public String getRoleName() { + return roleName; + } + + public void setRoleName(String roleName) { + this.roleName = roleName; + } + + public String[] getPermissions() { + return permissions; + } + + public void setPermissions(String[] permissions) { + this.permissions = permissions; + } + + public String[] getUsers() { + return users; + } + + public void setUsers(String[] users) { + this.users = users; + } + + public UIPermissionNode getPermissionList() { + return permissionList; + } + + public void setPermissionList(UIPermissionNode permissionList) { + this.permissionList = permissionList; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/RoleList.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/RoleList.java new file mode 100644 index 0000000000..bfd9afe99d --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/RoleList.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.List; + +@ApiModel(value = "Role List") +public class RoleList extends BasePaginatedResult { + + private List roles; + + @ApiModelProperty(value = "Returns the list of roles that match the offset and limit parameter values " + + "that were specified.") + @JsonProperty("roles") + public List getList() { + return roles; + } + + public void setList(List roles) { + this.roles = roles; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("{\n"); + sb.append(" count: ").append(getCount()).append(",\n"); + sb.append(" roles: [").append(roles).append("\n"); + sb.append("]}\n"); + return sb.toString(); + } + + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/Scope.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/Scope.java new file mode 100644 index 0000000000..0badaa417c --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/Scope.java @@ -0,0 +1,71 @@ +/* +* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* 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. +*/ +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +@ApiModel(value = "Scope", description = "Template of the authorization scope") +public class Scope { + + @ApiModelProperty(name = "scope key", value = "An unique string as a key.", required = true) + private String key; + + @ApiModelProperty(name = "scope name", value = "Scope name.", required = true) + private String name; + + @ApiModelProperty(name = "roles", value = "List of roles to be associated with the scope", required = true) + private String roles; + + @ApiModelProperty(name = "scope description", value = "A description of the scope", required = true) + private String description; + + public Scope() { + } + + public String getKey() { + return this.key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getRoles() { + return this.roles; + } + + public void setRoles(String roles) { + this.roles = roles; + } + + public String getDescription() { + return this.description; + } + + public void setDescription(String description) { + this.description = description; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/UserInfo.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/UserInfo.java new file mode 100644 index 0000000000..4513c6f647 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/UserInfo.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +@ApiModel(value = "UserInfo", description = "User details and the roles of the user.") +public class UserInfo extends BasicUserInfo { + + @ApiModelProperty(name = "password", value = "Base64 encoded password.", required = true ) + private String password; + + @ApiModelProperty(name = "roles", value = "List of roles.", required = true ) + private String[] roles; + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String[] getRoles() { + String[] copiedRoles = roles; + if (roles != null){ + copiedRoles = roles.clone(); + } + return copiedRoles; + } + + public void setRoles(String[] roles) { + this.roles = roles; + } + +} \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/UserInfoList.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/UserInfoList.java new file mode 100644 index 0000000000..fc3f575f75 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/UserInfoList.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.ArrayList; +import java.util.List; + +@ApiModel(value = "List of users", description = "This contains a set of users that matches a given " + + "criteria as a collection") +public class UserInfoList extends BasePaginatedResult { + + private List users = new ArrayList<>(); + + @ApiModelProperty(value = "List of devices returned") + @JsonProperty("users") + public List getList() { + return users; + } + + public void setList(List users) { + this.users = users; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("{\n"); + sb.append(" count: ").append(getCount()).append(",\n"); + sb.append(" users: [").append(users).append("\n"); + sb.append("]}\n"); + return sb.toString(); + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/analytics/Attribute.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/analytics/Attribute.java new file mode 100644 index 0000000000..276fea9ee4 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/analytics/Attribute.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.beans.analytics; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; + +/** + * This hold the attribute definition. + */ +public class Attribute { + + @ApiModelProperty(value = "Event Attribute Name") + @JsonProperty("name") + private String name; + @ApiModelProperty(value = "Event Attribute Type") + @JsonProperty("type") + private AttributeType type; + + public Attribute() { + + } + + public Attribute(String name, AttributeType attributeType) { + this.name = name; + this.type = attributeType; + } + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public AttributeType getType() { + return type; + } + + public void setType(AttributeType type) { + this.type = type; + } +} + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/analytics/AttributeType.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/analytics/AttributeType.java new file mode 100644 index 0000000000..23235612b9 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/analytics/AttributeType.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.beans.analytics; + +/** + * This hold the definition of the attribute type for the attributes. + */ +public enum AttributeType { + STRING, LONG, BOOL, INT, FLOAT, DOUBLE; + + @Override + public String toString() { + return super.toString().toLowerCase(); + } +} + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/analytics/DeviceTypeEvent.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/analytics/DeviceTypeEvent.java new file mode 100644 index 0000000000..7ff162b357 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/analytics/DeviceTypeEvent.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.beans.analytics; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; + +/** + * This hold stats data record + */ +public class DeviceTypeEvent { + + private EventAttributeList eventAttributes; + private TransportType transport; + + @ApiModelProperty(value = "Attributes related to device type event") + @JsonProperty("eventAttributes") + public EventAttributeList getEventAttributeList() { + return eventAttributes; + } + + public void setEventAttributeList( + EventAttributeList eventAttributes) { + this.eventAttributes = eventAttributes; + } + + @ApiModelProperty(value = "Transport to be used for device to server communication.") + @JsonProperty("transport") + public TransportType getTransportType() { + return transport; + } + + public void setTransportType(TransportType transport) { + this.transport = transport; + } +} + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/analytics/EventAttributeList.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/analytics/EventAttributeList.java new file mode 100644 index 0000000000..fe9bd39e03 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/analytics/EventAttributeList.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.beans.analytics; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.jaxrs.beans.BasePaginatedResult; + +import java.util.ArrayList; +import java.util.List; + +/** + * This holds event attributes + */ +public class EventAttributeList { + + private List attributes = new ArrayList<>(); + + @ApiModelProperty(value = "List of Event Attributes") + @JsonProperty("attributes") + public List getList() { + return attributes; + } + + public void setList(List attributes) { + this.attributes = attributes; + } + +} + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/analytics/EventRecords.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/analytics/EventRecords.java new file mode 100644 index 0000000000..0dacde3833 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/analytics/EventRecords.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.beans.analytics; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.device.mgt.common.Device; + +import java.util.ArrayList; +import java.util.List; +import org.wso2.carbon.analytics.datasource.commons.Record; +import org.wso2.carbon.device.mgt.jaxrs.beans.BasePaginatedResult; + +/** + * This hold stats data record + */ +public class EventRecords extends BasePaginatedResult { + + private List records = new ArrayList<>(); + + @ApiModelProperty(value = "List of records returned") + @JsonProperty("records") + public List getRecord() { + return records; + } + + public void setList(List records) { + this.records = records; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("{\n"); + + sb.append(" count: ").append(getCount()).append(",\n"); + sb.append(" records: [").append(records).append("\n"); + sb.append("]}\n"); + return sb.toString(); + } + +} + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/analytics/TransportType.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/analytics/TransportType.java new file mode 100644 index 0000000000..58eae4e616 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/analytics/TransportType.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.beans.analytics; + +/** + * This hold the default transport types support by the server. + */ +public enum TransportType { + HTTP, MQTT; +} + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/android/AppStoreApplication.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/android/AppStoreApplication.java new file mode 100644 index 0000000000..951ab365e2 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/android/AppStoreApplication.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.beans.android; + +import com.google.gson.Gson; + +import java.io.Serializable; + +/** + * This class represents the Appstore AuthenticationImpl information. + */ +public class AppStoreApplication implements Serializable { + + private String type; + private String appIdentifier; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getAppIdentifier() { + return appIdentifier; + } + + public void setAppIdentifier(String appIdentifier) { + this.appIdentifier = appIdentifier; + } + + public String toJSON() { + Gson gson = new Gson(); + return gson.toJson(this); + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/android/EnterpriseApplication.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/android/EnterpriseApplication.java new file mode 100644 index 0000000000..2bd8633d92 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/android/EnterpriseApplication.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.beans.android; + +import com.google.gson.Gson; + +import java.io.Serializable; + +/** + * This class represents the Enterprise AuthenticationImpl information. + */ +public class EnterpriseApplication implements Serializable { + + private String type; + private String url; + private String appIdentifier; + + public String getAppIdentifier() { + return appIdentifier; + } + + public void setAppIdentifier(String appIdentifier) { + this.appIdentifier = appIdentifier; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String toJSON() { + Gson gson = new Gson(); + return gson.toJson(this); + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/android/WebApplication.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/android/WebApplication.java new file mode 100644 index 0000000000..7cb7243753 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/android/WebApplication.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.beans.android; + +import com.google.gson.Gson; + +import java.io.Serializable; + +/** + * This class represents the Web AuthenticationImpl information. + */ +public class WebApplication implements Serializable { + + private String name; + private String url; + private String type; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String toJSON() { + Gson gson = new Gson(); + return gson.toJson(this); + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ios/AppStoreApplication.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ios/AppStoreApplication.java new file mode 100644 index 0000000000..1925d6db77 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ios/AppStoreApplication.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.beans.ios; + +import com.google.gson.Gson; + +import java.io.Serializable; + +public class AppStoreApplication implements Serializable { + + private String identifier; + private int iTunesStoreID; + private boolean removeAppUponMDMProfileRemoval; + private boolean preventBackupOfAppData; + private String bundleId; + private String UUID; + + public String getUUID() { + return UUID; + } + + public void setUUID(String UUID) { + this.UUID = UUID; + } + + public String getIdentifier() { + return identifier; + } + + public void setIdentifier(String identifier) { + this.identifier = identifier; + } + + public int getiTunesStoreID() { + return iTunesStoreID; + } + + public void setiTunesStoreID(int iTunesStoreID) { + this.iTunesStoreID = iTunesStoreID; + } + + public boolean isRemoveAppUponMDMProfileRemoval() { + return removeAppUponMDMProfileRemoval; + } + + public void setRemoveAppUponMDMProfileRemoval(boolean removeAppUponMDMProfileRemoval) { + this.removeAppUponMDMProfileRemoval = removeAppUponMDMProfileRemoval; + } + + public boolean isPreventBackupOfAppData() { + return preventBackupOfAppData; + } + + public void setPreventBackupOfAppData(boolean preventBackupOfAppData) { + this.preventBackupOfAppData = preventBackupOfAppData; + } + + public String getBundleId() { + return bundleId; + } + + public void setBundleId(String bundleId) { + this.bundleId = bundleId; + } + + public String toJSON() { + Gson gson = new Gson(); + return gson.toJson(this); + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ios/EnterpriseApplication.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ios/EnterpriseApplication.java new file mode 100644 index 0000000000..2ac2879b74 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ios/EnterpriseApplication.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.beans.ios; + +import com.google.gson.Gson; + +import java.io.Serializable; + +public class EnterpriseApplication implements Serializable { + + private String identifier; + private String manifestURL; + private boolean removeAppUponMDMProfileRemoval; + private boolean preventBackupOfAppData; + private String bundleId; + private String UUID; + + public void setUUID(String UUID) { + this.UUID = UUID; + } + + public String getIdentifier() { + return identifier; + } + + public void setIdentifier(String identifier) { + this.identifier = identifier; + } + + public String getManifestURL() { + return manifestURL; + } + + public void setManifestURL(String manifestURL) { + this.manifestURL = manifestURL; + } + + public boolean isRemoveAppUponMDMProfileRemoval() { + return removeAppUponMDMProfileRemoval; + } + + public void setRemoveAppUponMDMProfileRemoval(boolean removeAppUponMDMProfileRemoval) { + this.removeAppUponMDMProfileRemoval = removeAppUponMDMProfileRemoval; + } + + public boolean isPreventBackupOfAppData() { + return preventBackupOfAppData; + } + + public void setPreventBackupOfAppData(boolean preventBackupOfAppData) { + this.preventBackupOfAppData = preventBackupOfAppData; + } + + public String getBundleId() { + return bundleId; + } + + public void setBundleId(String bundleId) { + this.bundleId = bundleId; + } + + public String toJSON() { + Gson gson = new Gson(); + return gson.toJson(this); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ios/RemoveApplication.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ios/RemoveApplication.java new file mode 100644 index 0000000000..95f85984a0 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ios/RemoveApplication.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.beans.ios; + +import com.google.gson.Gson; + +import java.io.Serializable; + +public class RemoveApplication implements Serializable { + + private String bundleId; + + public String getBundleId() { + return bundleId; + } + + public void setBundleId(String bundleId) { + this.bundleId = bundleId; + } + + public String toJSON() { + Gson gson = new Gson(); + return gson.toJson(this); + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ios/WebClip.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ios/WebClip.java new file mode 100644 index 0000000000..3e73197d08 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ios/WebClip.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.beans.ios; + +import com.google.gson.Gson; + +public class WebClip { + + private String URL; + private String label; + private String icon; + private String isRemovable; + private String UUID; + + public String getUUID() { + return UUID; + } + + public void setUUID(String UUID) { + this.UUID = UUID; + } + + public String getURL() { + return URL; + } + + public void setURL(String URL) { + this.URL = URL; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public String getIcon() { + return icon; + } + + public void setIcon(String icon) { + this.icon = icon; + } + + public String getIsRemovable() { + return isRemovable; + } + + public void setIsRemovable(String isRemovable) { + this.isRemovable = isRemovable; + } + + public String toJSON() { + Gson gson = new Gson(); + return gson.toJson(this); + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/common/Application.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/common/Application.java new file mode 100644 index 0000000000..afbf6d87bd --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/common/Application.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.common; + +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; + +import java.util.List; + +public class Application { + + private String applicationName; + private String appId; + private String locationUrl; + private String imageUrl; + private String platform; + private String version; + private List userNameList; + private List roleNameList; + + public List getDeviceIdentifiers() { + return deviceIdentifiers; + } + + public void setDeviceIdentifiers(List deviceIdentifiers) { + this.deviceIdentifiers = deviceIdentifiers; + } + + private List deviceIdentifiers; + + + public String getApplicationName() { + return applicationName; + } + + public void setApplicationName(String applicationName) { + this.applicationName = applicationName; + } + + + public String getAppId() { + return appId; + } + + public void setAppId(String appId) { + this.appId = appId; + } + + + public String getLocationUrl() { + return locationUrl; + } + + public void setLocationUrl(String locationUrl) { + this.locationUrl = locationUrl; + } + + + public String getImageUrl() { + return imageUrl; + } + + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } + + + public String getPlatform() { + return platform; + } + + public void setPlatform(String platform) { + this.platform = platform; + } + + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + + public List getUserNameList() { + return userNameList; + } + + public void setUserNameList(List userNameList) { + this.userNameList = userNameList; + } + + + public List getRoleNameList() { + return roleNameList; + } + + public void setRoleNameList(List roleNameList) { + this.roleNameList = roleNameList; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/common/ErrorHandler.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/common/ErrorHandler.java new file mode 100644 index 0000000000..1300b639d9 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/common/ErrorHandler.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.common; + +import javax.ws.rs.Produces; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.ExceptionMapper; + +@Produces({ "application/json" }) +public class ErrorHandler implements ExceptionMapper { + + public Response toResponse(Throwable e) { + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build(); + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/common/ErrorMessage.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/common/ErrorMessage.java new file mode 100644 index 0000000000..67654b4450 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/common/ErrorMessage.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.common; + + +public class ErrorMessage { + + private String errorMessage; + private String errorCode; + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + public String getErrorCode() { + return errorCode; + } + + public void setErrorCode(String errorCode) { + this.errorCode = errorCode; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/common/GsonMessageBodyHandler.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/common/GsonMessageBodyHandler.java new file mode 100644 index 0000000000..a25fb84833 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/common/GsonMessageBodyHandler.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.common; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import javax.ws.rs.Consumes; +import javax.ws.rs.Produces; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.ext.MessageBodyReader; +import javax.ws.rs.ext.MessageBodyWriter; +import javax.ws.rs.ext.Provider; +import java.io.*; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +import static javax.ws.rs.core.MediaType.APPLICATION_JSON; + +@Provider +@Produces(APPLICATION_JSON) +@Consumes(APPLICATION_JSON) +public class GsonMessageBodyHandler implements MessageBodyWriter, MessageBodyReader { + + public static final String DATE_FORMAT = "EEE, d MMM yyyy HH:mm:ss Z"; + private Gson gson; + private static final String UTF_8 = "UTF-8"; + + public boolean isReadable(Class aClass, Type type, Annotation[] annotations, MediaType mediaType) { + return true; + } + + private Gson getGson() { + if (gson == null) { + final GsonBuilder gsonBuilder = new GsonBuilder(); + gson = gsonBuilder.setDateFormat(DATE_FORMAT).create(); + } + return gson; + } + + public Object readFrom(Class objectClass, Type type, Annotation[] annotations, MediaType mediaType, + MultivaluedMap stringStringMultivaluedMap, InputStream entityStream) + throws IOException, WebApplicationException { + + InputStreamReader reader = new InputStreamReader(entityStream, "UTF-8"); + + try { + return getGson().fromJson(reader, type); + } finally { + reader.close(); + } + } + + public boolean isWriteable(Class aClass, Type type, Annotation[] annotations, MediaType mediaType) { + return true; + } + + public long getSize(Object o, Class aClass, Type type, Annotation[] annotations, MediaType mediaType) { + return -1; + } + + public void writeTo(Object object, Class aClass, Type type, Annotation[] annotations, MediaType mediaType, + MultivaluedMap stringObjectMultivaluedMap, OutputStream entityStream) + throws IOException, WebApplicationException { + + OutputStreamWriter writer = new OutputStreamWriter(entityStream, UTF_8); + try { + getGson().toJson(object, type, writer); + } finally { + writer.close(); + } + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/context/DeviceOperationContext.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/context/DeviceOperationContext.java new file mode 100644 index 0000000000..461ce5f83d --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/context/DeviceOperationContext.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.context; + +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + +/** + * Model object of DeviceOperation. + */ +@XmlRootElement +public class DeviceOperationContext { + + private List devices; + private Operation operation; + + @XmlElement + public List getDevices() { + return devices; + } + + public void setDevices(List devices) { + this.devices = devices; + } + + @XmlElement + public Operation getOperation() { + return operation; + } + + public void setOperation(Operation operation) { + this.operation = operation; + } +} \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/BadRequestException.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/BadRequestException.java new file mode 100644 index 0000000000..d97b78b6dd --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/BadRequestException.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.exception; + +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; + +/** + * Custom exception class for wrapping BadRequest related exceptions. + */ +public class BadRequestException extends WebApplicationException { + + public BadRequestException(ErrorResponse error) { + super(Response.status(Response.Status.BAD_REQUEST).entity(error).build()); + } +} \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/ConstraintViolationException.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/ConstraintViolationException.java new file mode 100644 index 0000000000..9664057f61 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/ConstraintViolationException.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.exception; + +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtUtil; + +import javax.validation.ConstraintViolation; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; +import java.util.Set; + +public class ConstraintViolationException extends WebApplicationException { + private String message; + + public ConstraintViolationException(Set> violations) { + super(Response.status(Response.Status.BAD_REQUEST) + .entity(DeviceMgtUtil.getConstraintViolationErrorDTO(violations)) + .header(Constants.DeviceConstants.HEADER_CONTENT_TYPE, Constants.DeviceConstants.APPLICATION_JSON) + .build()); + + //Set the error message + StringBuilder stringBuilder = new StringBuilder(); + for (ConstraintViolation violation : violations) { + stringBuilder.append(violation.getRootBeanClass().getSimpleName()); + stringBuilder.append("."); + stringBuilder.append(violation.getPropertyPath()); + stringBuilder.append(": "); + stringBuilder.append(violation.getMessage()); + stringBuilder.append(", "); + } + message = stringBuilder.toString(); + } + + @Override + public String getMessage() { + return message; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/ErrorDTO.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/ErrorDTO.java new file mode 100644 index 0000000000..ff4e0be32a --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/ErrorDTO.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.exception; + +import java.util.ArrayList; +import java.util.List; + +public class ErrorDTO { + + private Long code = null; + private String message = null; + private String description = null; + + public void setMoreInfo(String moreInfo) { + this.moreInfo = moreInfo; + } + + public void setCode(Long code) { + this.code = code; + } + + public void setMessage(String message) { + this.message = message; + } + + public void setDescription(String description) { + this.description = description; + } + + public void setError(List error) { + this.error = error; + } + + private String moreInfo = null; + + public String getMessage() { + return message; + } + + public Long getCode() { + return code; + } + + public String getDescription() { + return description; + } + + public String getMoreInfo() { + return moreInfo; + } + + public List getError() { + return error; + } + + public String toString() { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("class ErrorDTO {\n"); + stringBuilder.append(" code: ").append(code).append("\n"); + stringBuilder.append(" message: ").append(message).append("\n"); + stringBuilder.append(" description: ").append(description).append("\n"); + stringBuilder.append(" moreInfo: ").append(moreInfo).append("\n"); + stringBuilder.append(" error: ").append(error).append("\n"); + stringBuilder.append("}\n"); + return stringBuilder.toString(); + } + + private List error = new ArrayList<>(); + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/ForbiddenException.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/ForbiddenException.java new file mode 100644 index 0000000000..912f624632 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/ForbiddenException.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.exception; + +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; + +/** + * Exception class that is corresponding to 401 Forbidden response + */ + +public class ForbiddenException extends WebApplicationException { + + private String message; + + public ForbiddenException() { + super(Response.status(Response.Status.FORBIDDEN) + .build()); + } + + public ForbiddenException(ErrorDTO errorDTO) { + super(Response.status(Response.Status.FORBIDDEN) + .entity(errorDTO) + .header(Constants.DeviceConstants.HEADER_CONTENT_TYPE, Constants.DeviceConstants.APPLICATION_JSON) + .build()); + message = errorDTO.getDescription(); + } + + @Override + public String getMessage() { + return message; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/GlobalThrowableMapper.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/GlobalThrowableMapper.java new file mode 100644 index 0000000000..be3d037a8d --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/GlobalThrowableMapper.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.exception; + +import com.google.gson.JsonParseException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtUtil; + +import javax.naming.AuthenticationException; +import javax.ws.rs.ClientErrorException; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.ExceptionMapper; + +/** + * Handle the cxf level exceptions. + */ +public class GlobalThrowableMapper implements ExceptionMapper { + private static final Log log = LogFactory.getLog(GlobalThrowableMapper.class); + + private ErrorDTO e500 = new ErrorDTO(); + + GlobalThrowableMapper() { + e500.setCode((long) 500); + e500.setMessage("Internal server error."); + e500.setMoreInfo(""); + e500.setDescription("The server encountered an internal error. Please contact administrator."); + + } + + @Override + public Response toResponse(Throwable e) { + + if (e instanceof JsonParseException) { + String errorMessage = "Malformed request body."; + if (log.isDebugEnabled()) { + log.error(errorMessage, e); + } + return DeviceMgtUtil.buildBadRequestException(errorMessage).getResponse(); + } + if (e instanceof NotFoundException) { + return ((NotFoundException) e).getResponse(); + } + if (e instanceof UnexpectedServerErrorException) { + if (log.isDebugEnabled()) { + log.error("Unexpected server error.", e); + } + return ((UnexpectedServerErrorException) e).getResponse(); + } + if (e instanceof ConstraintViolationException) { + if (log.isDebugEnabled()) { + log.error("Constraint violation.", e); + } + return ((ConstraintViolationException) e).getResponse(); + } + if (e instanceof IllegalArgumentException) { + ErrorDTO errorDetail = new ErrorDTO(); + errorDetail.setCode((long) 400); + errorDetail.setMoreInfo(""); + errorDetail.setMessage(""); + errorDetail.setDescription(e.getMessage()); + return Response + .status(Response.Status.BAD_REQUEST) + .entity(errorDetail) + .build(); + } + if (e instanceof ClientErrorException) { + if (log.isDebugEnabled()) { + log.error("Client error.", e); + } + return ((ClientErrorException) e).getResponse(); + } + if (e instanceof AuthenticationException) { + ErrorDTO errorDetail = new ErrorDTO(); + errorDetail.setCode((long) 401); + errorDetail.setMoreInfo(""); + errorDetail.setMessage(""); + errorDetail.setDescription(e.getMessage()); + return Response + .status(Response.Status.UNAUTHORIZED) + .entity(errorDetail) + .build(); + } + if (e instanceof ForbiddenException) { + if (log.isDebugEnabled()) { + log.error("Resource forbidden.", e); + } + return ((ForbiddenException) e).getResponse(); + } + //unknown exception log and return + if (log.isDebugEnabled()) { + log.error("An Unknown exception has been captured by global exception mapper.", e); + } + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).header("Content-Type", "application/json") + .entity(e500).build(); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/Message.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/Message.java new file mode 100644 index 0000000000..e02151f3e0 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/Message.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.exception; + +public class Message { + + private String errorMessage; + private String discription; + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + public String getDiscription() { + return discription; + } + + public void setDiscription(String discription) { + this.discription = discription; + } +} \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/NotFoundException.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/NotFoundException.java new file mode 100644 index 0000000000..ac9fc5c568 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/NotFoundException.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.exception; + + +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; + +public class NotFoundException extends WebApplicationException { + private String message; + private static final long serialVersionUID = 147943572342342340L; + + public NotFoundException(ErrorResponse error) { + super(Response.status(Response.Status.NOT_FOUND).entity(error).build()); + } + public NotFoundException(ErrorDTO errorDTO) { + super(Response.status(Response.Status.NOT_FOUND) + .entity(errorDTO) + .header(Constants.DeviceConstants.HEADER_CONTENT_TYPE, Constants.DeviceConstants.APPLICATION_JSON) + .build()); + message = errorDTO.getDescription(); + } + + @Override + public String getMessage() { + return message; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/UnexpectedServerErrorException.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/UnexpectedServerErrorException.java new file mode 100644 index 0000000000..40d5d74e68 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/UnexpectedServerErrorException.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.exception; + + +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; + +public class UnexpectedServerErrorException extends WebApplicationException { + private String message; + private static final long serialVersionUID = 147943579458906890L; + + public UnexpectedServerErrorException(ErrorResponse error) { + super(Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build()); + } + public UnexpectedServerErrorException(ErrorDTO errorDTO) { + super(Response.status(Response.Status.INTERNAL_SERVER_ERROR) + .entity(errorDTO) + .header(Constants.DeviceConstants.HEADER_CONTENT_TYPE, Constants.DeviceConstants.APPLICATION_JSON) + .build()); + message = errorDTO.getDescription(); + } + + @Override + public String getMessage() { + return message; + } + + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/UnknownApplicationTypeException.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/UnknownApplicationTypeException.java new file mode 100644 index 0000000000..459335abd8 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/UnknownApplicationTypeException.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.exception; + +public class UnknownApplicationTypeException extends Exception { + + private static final long serialVersionUID = -3151279311929080299L; + + public UnknownApplicationTypeException(String msg, Exception nestedEx) { + super(msg, nestedEx); + } + + public UnknownApplicationTypeException(String message, Throwable cause) { + super(message, cause); + } + + public UnknownApplicationTypeException(String msg) { + super(msg); + } + + public UnknownApplicationTypeException() { + super(); + } + + public UnknownApplicationTypeException(Throwable cause) { + super(cause); + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/ValidationInterceptor.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/ValidationInterceptor.java new file mode 100644 index 0000000000..480911b39b --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/exception/ValidationInterceptor.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.exception; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.cxf.interceptor.Fault; +import org.apache.cxf.jaxrs.lifecycle.ResourceProvider; +import org.apache.cxf.jaxrs.model.ClassResourceInfo; +import org.apache.cxf.jaxrs.model.OperationResourceInfo; +import org.apache.cxf.message.Message; +import org.apache.cxf.message.MessageContentsList; +import org.apache.cxf.phase.AbstractPhaseInterceptor; +import org.apache.cxf.phase.Phase; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; +import javax.validation.executable.ExecutableValidator; +import java.lang.reflect.Method; +import java.util.List; +import java.util.Set; + +public class ValidationInterceptor extends AbstractPhaseInterceptor { + private Log log = LogFactory.getLog(getClass()); + private Validator validator = null; //validator interface is thread-safe + + public ValidationInterceptor() { + super(Phase.PRE_INVOKE); + ValidatorFactory defaultFactory = Validation.buildDefaultValidatorFactory(); + validator = defaultFactory.getValidator(); + if (validator == null) { + log.warn("Bean Validation provider could not be found, no validation will be performed"); + } else { + log.debug("Validation In-Interceptor initialized successfully"); + } + } + + @Override + public void handleMessage(Message message) throws Fault { + final OperationResourceInfo operationResource = message.getExchange().get(OperationResourceInfo.class); + if (operationResource == null) { + log.info("OperationResourceInfo is not available, skipping validation"); + return; + } + + final ClassResourceInfo classResource = operationResource.getClassResourceInfo(); + if (classResource == null) { + log.info("ClassResourceInfo is not available, skipping validation"); + return; + } + + final ResourceProvider resourceProvider = classResource.getResourceProvider(); + if (resourceProvider == null) { + log.info("ResourceProvider is not available, skipping validation"); + return; + } + + final List arguments = MessageContentsList.getContentsList(message); + final Method method = operationResource.getAnnotatedMethod(); + final Object instance = resourceProvider.getInstance(message); + if (method != null && arguments != null) { + //validate the parameters(arguments) over the invoked method + validate(method, arguments.toArray(), instance); + + //validate the fields of each argument + for (Object arg : arguments) { + if (arg != null) + validate(arg); + } + } + + } + + public void validate(final Method method, final Object[] arguments, final T instance) { + if (validator == null) { + log.warn("Bean Validation provider could not be found, no validation will be performed"); + return; + } + + ExecutableValidator methodValidator = validator.forExecutables(); + Set> violations = methodValidator.validateParameters(instance, + method, arguments); + + if (!violations.isEmpty()) { + throw new ConstraintViolationException(violations); + } + } + + public void validate(final T object) { + if (validator == null) { + log.warn("Bean Validation provider could be found, no validation will be performed"); + return; + } + + Set> violations = validator.validate(object); + + if (!violations.isEmpty()) { + throw new ConstraintViolationException(violations); + } + } + + public void handleFault(org.apache.cxf.message.Message messageParam) { + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/ActivityInfoProviderService.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/ActivityInfoProviderService.java new file mode 100644 index 0000000000..519c58cfd6 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/ActivityInfoProviderService.java @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.api; + +import io.swagger.annotations.*; +import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; +import org.wso2.carbon.device.mgt.jaxrs.beans.ActivityList; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; + +import javax.validation.constraints.Size; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +/** + * Activity related REST-API implementation. + */ +@SwaggerDefinition( + info = @Info( + version = "0.9.0", + title = "", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "ActivityInfoProvider"), + @ExtensionProperty(name = "context", value = "/api/device-mgt/v0.9/activities"), + }) + } + ), + tags = { + @Tag(name = "device_management", description = "") + } +) +@Path("/activities") +@Api(value = "Activity Info Provider", description = "Activity related information manipulation. For example" + + " operation details and responses from devices.") +@Scopes( + scopes = { + @Scope( + name = "Get activities", + description = "Get activities", + key = "perm:get-activity", + permissions = {"/device-mgt/devices/owning-device/view"} + ) + } +) +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public interface ActivityInfoProviderService { + + @GET + @Path("/{id}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting Details of an Activity", + notes = "Retrieve the details of a specific activity/operation, such as the meta information of " + + "an operation, including the responses from the devices.", + tags = "Activity Info Provider", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:get-activity") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the activity details.", + response = Activity.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client already has the latest version of " + + "the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 401, + message = "Unauthorized. \n Unauthorized request."), + @ApiResponse( + code = 404, + message = "Not Found. \n No activity found with the given ID.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the activity data.", + response = ErrorResponse.class) + }) + Response getActivity( + @ApiParam( + name = "id", + value = "Activity id of the operation/activity.", + required = true, + defaultValue = "ACTIVITY_1") + @PathParam("id") + @Size(max = 45) + String id, + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time\n." + + "Provide the value in the Java Date Format: EEE, d MMM yyyy HH:mm:ss Z\n." + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") String ifModifiedSince); + + + @GET + @Path("/{id}/{devicetype}/{deviceid}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting Details of an Activity for a specific device", + notes = "Retrieve the details of a specific activity/operation, such as the meta information of " + + "an operation, including the responses from a given device", + tags = "Activity Info Provider", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:get-activity") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the activity details.", + response = Activity.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client already has the latest version of " + + "the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 401, + message = "Unauthorized. \n Unauthorized request."), + @ApiResponse( + code = 404, + message = "Not Found. \n No activity found with the given ID.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the activity data.", + response = ErrorResponse.class) + }) + Response getActivityByDevice( + @ApiParam( + name = "id", + value = "Activity id of the operation/activity.", + required = true, + defaultValue = "ACTIVITY_1") + @PathParam("id") + @Size(max = 45) + String id, + @ApiParam( + name = "devicetype", + value = "The device type name, such as ios, android, windows or fire-alarm.", + required = true) + @PathParam("devicetype") + @Size(max = 45) + String type, + @ApiParam( + name = "deviceid", + value = "The device identifier of the device you want ot get details.", + required = true) + @PathParam("deviceid") + @Size(max = 45) + String deviceid, + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time\n." + + "Provide the value in the Java Date Format: EEE, d MMM yyyy HH:mm:ss Z\n." + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") String ifModifiedSince); + + @GET + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting Activity Details", + notes = "Get the details of the operations/activities executed by the server on the devices registered" + + " with WSO2 EMM, during a defined time period.", + tags = "Activity Info Provider", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:get-activity") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the activity details.", + response = ActivityList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client already has the latest version of the" + + " requested resource.\n"), + @ApiResponse( + code = 401, + message = "Unauthorized. \n Unauthorized request."), + @ApiResponse( + code = 404, + message = "Not Found. \n No activities found.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the activity data.", + response = ErrorResponse.class) + }) + Response getActivities( + @ApiParam( + name = "since", + value = "Checks if the requested variant was created since the specified date-time.\n" + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @QueryParam("since") String since, + @ApiParam( + name = "offset", + value = "The starting pagination index for the complete list of qualified items.", + required = false, + defaultValue = "0") + @QueryParam("offset") int offset, + @ApiParam( + name = "limit", + value = "Provide how many activity details you require from the starting pagination index/offset.", + required = false, + defaultValue = "5") + @QueryParam("limit") int limit, + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time\n." + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z\n." + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") String ifModifiedSince); + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/ConfigurationManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/ConfigurationManagementService.java new file mode 100644 index 0000000000..8c3ee04429 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/ConfigurationManagementService.java @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.api; + +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Info; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.Extension; +import io.swagger.annotations.Tag; +import io.swagger.annotations.Api; +import io.swagger.annotations.AuthorizationScope; +import io.swagger.annotations.Authorization; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.ResponseHeader; +import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; + +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +/** + * General Tenant Configuration REST-API. + */ +@SwaggerDefinition( + info = @Info( + version = "0.9.0", + title = "", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "ConfigurationManagement"), + @ExtensionProperty(name = "context", value = "/api/device-mgt/v0.9/configuration"), + }) + } + ), + tags = { + @Tag(name = "device_management", description = "") + } +) +@Path("/configuration") +@Api(value = "Configuration Management", description = "The general platform configuration management capabilities are exposed " + + "through this API.") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@Scopes(scopes = { + @Scope( + name = "View configurations", + description = "", + key = "perm:view-configuration", + permissions = {"/device-mgt/platform-configurations/view"} + ), + @Scope( + name = "Manage configurations", + description = "", + key = "perm:manage-configuration", + permissions = {"/device-mgt/platform-configurations/manage"} + ) +} +) +public interface ConfigurationManagementService { + + @GET + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting General Platform Configurations", + notes = "WSO2 EMM monitors policies to verify that the devices comply with the policies enforced on them. " + + "General platform configurations include the settings on how often the device need to be monitored. " + + "Using this REST API you can get the general platform level configurations.", + tags = "Configuration Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:view-configuration") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the general platform configurations.", + response = PlatformConfiguration.class, + responseContainer = "List", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + } + ), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client already has the latest version of the requested resource."), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the general " + + "platform configurations.", + response = ErrorResponse.class) + }) + Response getConfiguration( + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time.\n" + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z." + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") + String ifModifiedSince); + + @PUT + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "PUT", + value = "Updating General Platform Configurations", + notes = "WSO2 EMM monitors policies to verify that the devices comply with the policies enforced on them." + + "General platform configurations include the settings on how often the the device need to be monitored." + + "Using this REST API you can update the general platform level configurations.", + tags = "Configuration Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:manage-configuration") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully updated the general platform configurations.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests.")}), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error."), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The format of the requested entity was not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while modifying the general platform configurations.", + response = ErrorResponse.class) + }) + Response updateConfiguration( + @ApiParam( + name = "configuration", + value = "The properties required to update the platform configurations.", + required = true) + PlatformConfiguration configuration); + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceAgentService.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceAgentService.java new file mode 100644 index 0000000000..369041daf5 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceAgentService.java @@ -0,0 +1,666 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.api; + +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.Extension; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.Info; +import io.swagger.annotations.ResponseHeader; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.beans.OperationList; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; + +import javax.validation.Valid; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.util.List; +import java.util.Map; + +@SwaggerDefinition( + info = @Info( + version = "0.9.0", + title = "", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "DeviceAgent Service"), + @ExtensionProperty(name = "context", value = "/api/device-mgt/v0.9/device/agent"), + }) + } + ), + tags = { + @Tag(name = "device_agent, device_management", description = "") + } +) +@Api(value = "Device Agent", description = "Device Agent Service") +@Path("/device/agent") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@Scopes( + scopes = { + @Scope( + name = "Enroll Device", + description = "Register a device", + key = "perm:device:enroll", + permissions = {"/device-mgt/devices/owning-device/add"} + ), + @Scope( + name = "Modify Device", + description = "Modify a device", + key = "perm:device:modify", + permissions = {"/device-mgt/devices/owning-device/modify"} + ), + @Scope( + name = "Disenroll Device", + description = "Disenroll a device", + key = "perm:device:disenroll", + permissions = {"/device-mgt/devices/owning-device/remove"} + ), + @Scope( + name = "Publish Event", + description = "publish device event", + key = "perm:device:publish-event", + permissions = {"/device-mgt/devices/owning-device/event"} + ), + @Scope( + name = "Getting Device Operation Details", + description = "Getting Device Operation Details", + key = "perm:device:operations", + permissions = {"/device-mgt/devices/owning-device/view"} + ) + } +) +public interface DeviceAgentService { + + @POST + @Path("/enroll") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Create a device instance", + notes = "Create a device Instance", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:device:enroll") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully created a device instance.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest version" + + " of the requested resource.\n"), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n A deviceType with the specified device type was not found.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving the device details.", + response = ErrorResponse.class) + }) + Response enrollDevice(@ApiParam(name = "device", value = "Device object with data.", required = true) + @Valid Device device); + + @DELETE + @Path("/enroll/{type}/{id}") + @ApiOperation( + httpMethod = "DELETE", + value = "Unregistering a Device", + notes = "Use this REST API to unregister a device.", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:device:disenroll") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully disenrolled the device."), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified resource does not exist."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while dis-enrolling the device.") + }) + Response disEnrollDevice( + @ApiParam(name = "type", value = "The unique device identifier.") @PathParam("type") String type, + @ApiParam(name = "id", value = "The unique device identifier.") @PathParam("id") String id); + + @PUT + @Path("/enroll/{type}/{id}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "PUT", + value = "modify device", + notes = "modify device", + tags = "Device Agent Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:device:modify") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully updated device instance.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest version" + + " of the requested resource.\n"), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n A deviceType with the specified device type was not found.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving the device details.", + response = ErrorResponse.class) + }) + Response updateDevice(@ApiParam(name = "type", value = "The device type, such as ios, android or windows....etc", required = true) + @PathParam("type") String type, + @ApiParam(name = "id", value = "The device id.", required = true) + @PathParam("id") String deviceId, + @ApiParam(name = "device", value = "Device object with data.", required = true) + @Valid Device updateDevice); + + @POST + @Path("/events/publish/{type}/{deviceId}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + consumes = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Publishing Events", + notes = "Publish events received by the device client to the WSO2 Data Analytics Server (DAS) using this API.", + tags = "Device Agent Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:device:publish-event") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse(code = 200, message = "OK. \n Successfully published the event", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests.") + }), + @ApiResponse( + code = 303, + message = "See Other. \n The source can be retrieved from the URL specified in the location header.", + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "The Source URL of the document.")}), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error."), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The format of the requested entity was not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while publishing events.") + }) + Response publishEvents( + @ApiParam( + name = "payloadData", + value = "Information of the agent event to be published on DAS.") + @Valid + Map payloadData, + @ApiParam( + name = "type", + value = "name of the device type") + @PathParam("type") String type, + @ApiParam( + name = "deviceId", + value = "deviceId of the device") + @PathParam("deviceId") String deviceId); + + @POST + @Path("/events/publish/data/{type}/{deviceId}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + consumes = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Publishing Events data only", + notes = "Publish events received by the device client to the WSO2 Data Analytics Server (DAS) using this API.", + tags = "Device Agent Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:device:publish-event") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse(code = 200, message = "OK. \n Successfully published the event", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests.") + }), + @ApiResponse( + code = 303, + message = "See Other. \n The source can be retrieved from the URL specified in the location header.", + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "The Source URL of the document.")}), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error."), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The format of the requested entity was not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while publishing events.") + }) + Response publishEvents( + @ApiParam( + name = "payloadData", + value = "Information of the agent event to be published on DAS.") + @Valid + List payloadData, + @ApiParam( + name = "type", + value = "name of the device type") + @PathParam("type") String type, + @ApiParam( + name = "deviceId", + value = "deviceId of the device") + @PathParam("deviceId") String deviceId); + + @GET + @Path("/pending/operations/{type}/{id}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + consumes = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Get pending operation of the given device", + notes = "Returns the Operations.", + tags = "Device Agent Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:device:operations") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully retrieved the operations.", + response = OperationList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest " + + "version of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n No device is found under the provided type and id.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving information requested device.", + response = ErrorResponse.class) + }) + Response getPendingOperations(@ApiParam(name = "type", value = "The device type, such as ios, android or windows.", required = true) + @PathParam("type") String type, + @ApiParam(name = "id", value = "The device id.", required = true) + @PathParam("id") String deviceId); + + @GET + @Path("/next-pending/operation/{type}/{id}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + consumes = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Get pending operation of the given device", + notes = "Returns the Operation.", + tags = "Device Agent Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:device:operations") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully retrieved the operation.", + response = Operation.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest " + + "version of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n No device is found under the provided type and id.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving information requested device.", + response = ErrorResponse.class) + }) + Response getNextPendingOperation(@ApiParam(name = "type", value = "The device type, such as ios, android or windows.", required = true) + @PathParam("type") String type, + @ApiParam(name = "id", value = "The device id.", required = true) + @PathParam("id") String deviceId); + + @PUT + @Path("/operations/{type}/{id}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + consumes = MediaType.APPLICATION_JSON, + httpMethod = "PUT", + value = "Update Operation", + notes = "Update the Operations.", + tags = "Device Agent Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:device:operations") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully updated the operations.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest " + + "version of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n No device is found under the provided type and id.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving information requested device.", + response = ErrorResponse.class) + }) + Response updateOperation(@ApiParam(name = "type", value = "The device type, such as ios, android or windows.", required = true) + @PathParam("type") String type, + @ApiParam(name = "id", value = "The device id.", required = true) + @PathParam("id") String deviceId, + @ApiParam(name = "operation", value = "Operation object with data.", required = true) + @Valid Operation operation); + + @PUT + @Path("/properties/{type}/{id}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + consumes = MediaType.APPLICATION_JSON, + httpMethod = "PUT", + value = "Update Properties", + notes = "Update device properties.", + tags = "Device Agent Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:device:modify") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully updated the operations.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest " + + "version of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n No device is found under the provided type and id.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving information requested device.", + response = ErrorResponse.class) + }) + Response updateDeviceProperties(@ApiParam(name = "type", value = "The device type, such as ios, android or windows.", required = true) + @PathParam("type") String type, + @ApiParam(name = "id", value = "The device id.", required = true) + @PathParam("id") String deviceId, + @ApiParam(name = "properties", value = "device properties list.", required = true) + @Valid List properties); + + @GET + @Path("/status/operations/{type}/{id}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + consumes = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Get pending operation of the given device", + notes = "Returns the Operations.", + tags = "Device Agent Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:device:operations") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully retrieved the operations.", + response = OperationList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest " + + "version of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n No device is found under the provided type and id.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving information requested device.", + response = ErrorResponse.class) + }) + Response getOperationsByDeviceAndStatus(@ApiParam(name = "type", value = "The device type, such as ios, android or windows.", required = true) + @PathParam("type") String type, + @ApiParam(name = "id", value = "The device id.", required = true) + @PathParam("id") String deviceId, + @ApiParam(name = "status", value = "status of the operation.", required = true) + @QueryParam("status")Operation.Status status); + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceEventManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceEventManagementService.java new file mode 100644 index 0000000000..e161a1acbc --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceEventManagementService.java @@ -0,0 +1,347 @@ +package org.wso2.carbon.device.mgt.jaxrs.service.api; + +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.Extension; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.Info; +import io.swagger.annotations.ResponseHeader; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceTypeList; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.DeviceTypeEvent; +import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.EventAttributeList; +import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.EventRecords; +import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.TransportType; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; + +import javax.validation.Valid; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +@SwaggerDefinition( + info = @Info( + version = "0.9.0", + title = "", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "DeviceEventManagement"), + @ExtensionProperty(name = "context", value = "/api/device-mgt/v0.9/events"), + }) + } + ), + tags = { + @Tag(name = "device_management", description = "") + } +) +@Scopes( + scopes = { + @Scope( + name = "Add or Delete Event Definition for device type", + description = "Add or Delete Event Definition for device type", + key = "perm:device-types:events", + permissions = {"/device-mgt/device-type/add"} + ), + @Scope( + name = "Get Events Details of a Device Type", + description = "Get Events Details of a Device Type", + key = "perm:device-types:events:view", + permissions = {"/device-mgt/devices/owning-device/view"} + ) + } +) +@Path("/events") +@Api(value = "Device Event Management", description = "This API corresponds to all tasks related to device " + + "event management") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public interface DeviceEventManagementService { + + @POST + @Path("/{type}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Add Event Type Defnition", + notes = "Add the event definition for the device.", + tags = "Device Event Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:device-types:events") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully added the event defintion.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = + "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + } + ), + @ApiResponse( + code = 400, + message = + "Bad Request. \n"), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the " + + "list of supported device types.", + response = ErrorResponse.class) + } + ) + Response deployDeviceTypeEventDefinition(@ApiParam(name = "type", value = "name of the device type", required = false) + @PathParam("type")String deviceType, + @ApiParam(name = "deviceTypeEvent", value = "DeviceTypeEvent object with data.", required = true) + @Valid DeviceTypeEvent deviceTypeEvent); + + @DELETE + @Path("/{type}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "DELETE", + value = "Delete Event Type Defnition", + notes = "Delete the event definition for the device.", + tags = "Device Event Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:device-types:events") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully deleted the event definition.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = + "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + } + ), + @ApiResponse( + code = 400, + message = + "Bad Request. \n"), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the " + + "list of supported device types.", + response = ErrorResponse.class) + } + ) + Response deleteDeviceTypeEventDefinitions(@ApiParam(name = "type", value = "name of the device type", required = false) + @PathParam("type")String deviceType); + + @GET + @Path("/{type}/{deviceId}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting Device Events", + notes = "Get the events for the device.", + tags = "Device Event Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:device-types:events:view") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the event definition.", + response = EventRecords.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = + "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + } + ), + @ApiResponse( + code = 400, + message = + "Bad Request. \n"), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the " + + "list of supported device types.", + response = ErrorResponse.class) + } + ) + Response getData(@ApiParam(name = "deviceId", value = "id of the device ", required = false) + @PathParam("deviceId") String deviceId, + @ApiParam(name = "from", value = "unix timestamp to retrieve", required = false) + @QueryParam("from") long from, + @ApiParam(name = "to", value = "unix time to retrieve", required = false) + @QueryParam("to") long to, + @ApiParam(name = "type", value = "name of the device type", required = false) + @PathParam("type") String deviceType, + @ApiParam(name = "offset", value = "offset of the records that needs to be picked up", required = false) + @QueryParam("offset") int offset, + @ApiParam(name = "limit", value = "limit of the records that needs to be picked up", required = false) + @QueryParam("limit") int limit); + + @GET + @Path("last-known/{type}/{deviceId}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting Last Known Device Events", + notes = "Get the Last Known events for the device.", + tags = "Device Event Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:device-types:events:view") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the event.", + response = EventRecords.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = + "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + } + ), + @ApiResponse( + code = 400, + message = + "Bad Request. \n"), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the " + + "list of supported device types.", + response = ErrorResponse.class) + } + ) + Response getLastKnownData(@ApiParam(name = "deviceId", value = "id of the device ", required = false) + @PathParam("deviceId") String deviceId, + @ApiParam(name = "type", value = "name of the device type", required = false) + @PathParam("type") String deviceType); + + @GET + @Path("/{type}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting Event Type Defnition", + notes = "Get the event definition for the device.", + tags = "Device Event Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:device-types:events:view") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the event defintion.", + response = DeviceTypeEvent.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = + "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + } + ), + @ApiResponse( + code = 400, + message = + "Bad Request. \n"), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the " + + "list of supported device types.", + response = ErrorResponse.class) + } + ) + Response getDeviceTypeEventDefinition(@ApiParam(name = "type", value = "name of the device type", required = false) + @PathParam("type")String deviceType) ; + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java new file mode 100644 index 0000000000..e2ee5aeb25 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java @@ -0,0 +1,1441 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.api; + +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.Extension; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.Info; +import io.swagger.annotations.ResponseHeader; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.EnrolmentInfo; +import org.wso2.carbon.device.mgt.common.Feature; +import org.wso2.carbon.device.mgt.common.app.mgt.Application; +import org.wso2.carbon.device.mgt.common.device.details.DeviceInfo; +import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; +import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; +import org.wso2.carbon.device.mgt.common.policy.mgt.Policy; +import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.NonComplianceData; +import org.wso2.carbon.device.mgt.common.search.SearchContext; +import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceList; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.beans.OperationRequest; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; + +import javax.validation.Valid; +import javax.validation.constraints.Size; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +/** + * Device related REST-API. This can be used to manipulated device related details. + */ +@SwaggerDefinition( + info = @Info( + version = "0.9.0", + title = "", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "DeviceManagement"), + @ExtensionProperty(name = "context", value = "/api/device-mgt/v0.9/devices"), + }) + } + ), + tags = { + @Tag(name = "device_management", description = "") + } +) +@Scopes( + scopes = { + @Scope( + name = "Getting Details of Registered Devices", + description = "Getting Details of Registered Devices", + key = "perm:devices:view", + permissions = {"/device-mgt/devices/owning-device/view"} + ), + @Scope( + name = "Getting Details of a Device", + description = "Getting Details of a Device", + key = "perm:devices:details", + permissions = {"/device-mgt/devices/owning-device/view"} + ), + @Scope( + name = "Update the device specified by device id", + description = "Update the device specified by device id", + key = "perm:devices:update", + permissions = {"/device-mgt/devices/owning-device/view"} + ), + @Scope( + name = "Delete the device specified by device id", + description = "Delete the device specified by device id", + key = "perm:devices:delete", + permissions = {"/device-mgt/devices/owning-device/view"} + ), + @Scope( + name = "Getting Feature Details of a Device", + description = "Getting Feature Details of a Device", + key = "perm:devices:features", + permissions = {"/device-mgt/devices/owning-device/view"} + ), + @Scope( + name = "Advanced Search for Devices", + description = "Advanced Search for Devices", + key = "perm:devices:search", + permissions = {"/device-mgt/devices/owning-device/view"} + ), + @Scope( + name = "Getting Installed Application Details of a Device", + description = "Getting Installed Application Details of a Device", + key = "perm:devices:applications", + permissions = {"/device-mgt/devices/owning-device/view"} + ), + @Scope( + name = "Getting Device Operation Details", + description = "Getting Device Operation Details", + key = "perm:devices:operations", + permissions = {"/device-mgt/devices/owning-device/view"} + ), + @Scope( + name = "Get the details of the policy that is enforced on a device.", + description = "Get the details of the policy that is enforced on a device.", + key = "perm:devices:effective-policy", + permissions = {"/device-mgt/devices/owning-device/view"} + ), + @Scope( + name = "Getting Policy Compliance Details of a Device", + description = "Getting Policy Compliance Details of a Device", + key = "perm:devices:compliance-data", + permissions = {"/device-mgt/devices/owning-device/view"} + ), + @Scope( + name = "Change device status.", + description = "Change device status.", + key = "perm:devices:change-status", + permissions = {"/device-mgt/devices/change-status"} + ), + } +) +@Path("/devices") +@Api(value = "Device Management", description = "This API carries all device management related operations " + + "such as get all the available devices, etc.") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public interface DeviceManagementService { + + @GET + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting Details of Registered Devices", + notes = "Provides details of all the devices enrolled with WSO2 IoT Server.", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:view") + }) + } + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. \n Successfully fetched the list of devices.", + response = DeviceList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client already has the latest version of " + + "the requested resource.\n"), + @ApiResponse( + code = 400, + message = "The incoming request has more than one selection criteria defined via the query parameters.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "The search criteria did not match any device registered with the server.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the device list.", + response = ErrorResponse.class) + }) + Response getDevices( + @ApiParam( + name = "name", + value = "The device name, such as shamu, bullhead or angler Nexus device names. ", + required = false) + @Size(max = 45) + String name, + @ApiParam( + name = "type", + value = "The device type, such as ios, android or windows.", + required = false) + @QueryParam("type") + @Size(max = 45) + String type, + @ApiParam( + name = "user", + value = "The username of the owner of the device.", + required = false) + @QueryParam("user") + String user, + @ApiParam( + name = "userPattern", + value = "The pattern of username of the owner of the device.", + required = false) + @QueryParam("userPattern") + String userPattern, + @ApiParam( + name = "role", + value = "A role of device owners. Ex : store-admin", + required = false) + @QueryParam("role") + @Size(max = 45) + String role, + @ApiParam( + name = "ownership", + allowableValues = "BYOD, COPE", + value = "Provide the ownership status of the device. The following values can be assigned:\n" + + "- BYOD: Bring Your Own Device\n" + + "- COPE: Corporate-Owned, Personally-Enabled", + required = false) + @QueryParam("ownership") + @Size(max = 45) + String ownership, + @ApiParam( + name = "status", + value = "Provide the device status details, such as active or inactive.", + required = false) + @QueryParam("status") + @Size(max = 45) + String status, + @ApiParam( + name = "groupId", + value = "Id of the group which device belongs", + required = false) + @QueryParam("groupId") + int groupId, + @ApiParam( + name = "since", + value = "Checks if the requested variant was created since the specified date-time.\n" + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @QueryParam("since") + String since, + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time.\n" + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z\n" + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") + String timestamp, + @ApiParam( + name = "offset", + value = "The starting pagination index for the complete list of qualified items.", + required = false, + defaultValue = "0") + @QueryParam("offset") + int offset, + @ApiParam( + name = "limit", + value = "Provide how many device details you require from the starting pagination index/offset.", + required = false, + defaultValue = "5") + @QueryParam("limit") + int limit); + + @GET + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting Details of Registered Devices owned by authenticated user", + notes = "Provides details of devices enrolled by authenticated user.", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:view") + }) + } + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. \n Successfully fetched the list of devices.", + response = DeviceList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client already has the latest version of " + + "the requested resource.\n"), + @ApiResponse( + code = 400, + message = "The incoming request has more than one selection criteria defined via the query parameters.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "The search criteria did not match any device registered with the server.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the device list.", + response = ErrorResponse.class) + }) + @Path("/user-devices") + Response getDeviceByUser( + @ApiParam( + name = "requireDeviceInfo", + value = "Boolean flag indicating whether to include device-info (location, application list etc) \n" + + " to the device object.", + required = false) + @QueryParam("requireDeviceInfo") + boolean requireDeviceInfo, + @ApiParam( + name = "offset", + value = "The starting pagination index for the complete list of qualified items.", + required = false, + defaultValue = "0") + @QueryParam("offset") + int offset, + @ApiParam( + name = "limit", + value = "Provide how many device details you require from the starting pagination index/offset.", + required = false, + defaultValue = "5") + @QueryParam("limit") + int limit); + + @GET + @Path("/{type}/{id}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting Details of a Device", + notes = "Get the details of a device by specifying the device type and device identifier and optionally " + + "the owner.", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:details") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the details of the device.", + response = Device.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest version" + + " of the requested resource.\n"), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n A device with the specified device type and id was not found.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving the device details.", + response = ErrorResponse.class) + }) + Response getDevice( + @ApiParam( + name = "type", + value = "The device type name, such as ios, android, windows or fire-alarm.", + required = true) + @PathParam("type") + @Size(max = 45) + String type, + @ApiParam( + name = "id", + value = "The device identifier of the device you want ot get details.", + required = true) + @PathParam("id") + @Size(max = 45) + String id, + @ApiParam( + name = "owner", + value = "The owner of the device you want ot get details.", + required = false) + @QueryParam("owner") + @Size(max = 100) + String owner, + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time. \n" + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z. \n" + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") + String ifModifiedSince); + + @PUT + @Path("/{type}/{id}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Get device enrollment status", + notes = "Get device enrollment status", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:view") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully created a device instance.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest version" + + " of the requested resource.\n"), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n A deviceType with the specified device type was not found.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving the device details.", + response = ErrorResponse.class) + }) + Response isEnrolled(@ApiParam(name = "type", value = "The device type, such as ios, android or windows.", required = true) + @PathParam("type") String type, + @ApiParam(name = "id", value = "The device id.", required = true) + @PathParam("id") String deviceId); + + @GET + @Path("/{type}/{id}/location") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting Location Details of a Device", + notes = "Get the location details of a device by specifying the device type and device identifier.", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:details") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the location details of the device.", + response = Device.class, //TODO, This should be DeviceLocation.class + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest version" + + " of the requested resource.\n"), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n Location data for the specified device was not found.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving the device details.", + response = ErrorResponse.class) + }) + Response getDeviceLocation( + @ApiParam( + name = "type", + value = "The device type name, such as ios, android, windows or fire-alarm.", + required = true) + @PathParam("type") + @Size(max = 45) + String type, + @ApiParam( + name = "id", + value = "The device identifier of the device you want ot get details.", + required = true) + @PathParam("id") + @Size(max = 45) + String id, + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time. \n" + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z. \n" + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") + String ifModifiedSince); + + + + @GET + @Path("/{type}/{id}/info") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting the information of a Device", + notes = "Get the information of a device by specifying the device type and device identifier.", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:details") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the information of the device.", + response = DeviceInfo.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest version" + + " of the requested resource.\n"), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n Location data for the specified device was not found.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving the device details.", + response = ErrorResponse.class) + }) + Response getDeviceInformation( + @ApiParam( + name = "type", + value = "The device type name, such as ios, android, windows or fire-alarm.", + required = true) + @PathParam("type") + @Size(max = 45) + String type, + @ApiParam( + name = "id", + value = "The device identifier of the device you want ot get details.", + required = true) + @PathParam("id") + @Size(max = 45) + String id, + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time. \n" + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z. \n" + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") + String ifModifiedSince); + + //device rename request would looks like follows + //POST devices/type/virtual_firealarm/id/us06ww93auzp/rename + @POST + @Path("/type/{device-type}/id/{device-id}/rename") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + consumes = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Update the device specified by device id", + notes = "Returns the status of the updated device operation.", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched information of the device.", + response = Device.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest " + + "version of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n No device is found under the provided type and id.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving information requested device.", + response = ErrorResponse.class) + }) + Response renameDevice( + @ApiParam( + name = "device", + value = "The payload containing new name for device with updated name.", + required = true) + Device device, + @ApiParam( + name = "device-type", + value = "The device type, such as ios, android or windows.", + required = true) + @PathParam("device-type") + @Size(max = 45) + String deviceType, + @ApiParam( + name = "device-id", + value = "The device identifier of the device.", + required = true) + @PathParam("device-id") + @Size(max = 45) + String deviceId); + + //device remove request would looks like follows + //DELETE devices/type/virtual_firealarm/id/us06ww93auzp + @DELETE + @Path("/type/{device-type}/id/{device-id}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + consumes = MediaType.APPLICATION_JSON, + httpMethod = "DELETE", + value = "Remove the device specified by device id", + notes = "Returns the status of the deleted device operation.", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:delete") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully deleted the device.", + response = Device.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest " + + "version of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n No device is found under the provided type and id.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving information requested device.", + response = ErrorResponse.class) + }) + Response deleteDevice( + @ApiParam( + name = "device-type", + value = "The device type, such as ios, android or windows.", + required = true) + @PathParam("device-type") + @Size(max = 45) + String deviceType, + @ApiParam( + name = "device-id", + value = "The device identifier of the device.", + required = true) + @PathParam("device-id") + @Size(max = 45) + String deviceId); + + @GET + @Path("/{type}/{id}/features") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting Feature Details of a Device", + notes = "WSO2 IoTS features enable you to carry out many operations based on the device platform. " + + "Using this REST API you can get the features that can be carried out on a preferred device type," + + " such as iOS, Android or Windows.", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:features") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the list of features.", + response = Feature.class, + responseContainer = "List", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests.")}), + @ApiResponse( + code = 303, + message = "See Other. \n " + + "The source can be retrieved from the URL specified in the location header.", + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "The Source URL of the document.")}), + @ApiResponse( + code = 304, + message = "Not Modified. \n " + + "Empty body because the client already has the latest version of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified device can not be found.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable. \n The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving the feature list for the device platform.", + response = ErrorResponse.class) + }) + Response getFeaturesOfDevice( + @ApiParam( + name = "type", + value = "The device type name, such as ios, android, windows or fire-alarm.", + required = true) + @PathParam("type") + @Size(max = 45) + String type, + @ApiParam( + name = "id", + value = "The device identifier of the device.\n" + + "INFO: Make sure to add the ID of a device that is already registered with WSO2 IoTS.", + required = true) + @PathParam("id") + @Size(max = 45) + String id, + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time. \n" + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z. \n" + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") + String ifModifiedSince); + + @POST + @Path("/search-devices") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + consumes = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Advanced Search for Devices", + notes = "Search for devices by filtering the search result through the specified search terms.", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:search") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully retrieved the device information.", + response = DeviceList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified. \n" + + "Used by caches, or in conditional requests.")}), + @ApiResponse( + code = 304, + message = "Not Modified. \n " + + "Empty body because the client already has the latest version of the requested resource.\n"), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Acceptable.\n The existing device did not match the values specified in the device search.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported"), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The format of the requested entity was not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while getting the device details.", + response = ErrorResponse.class) + }) + Response searchDevices( + @ApiParam( + name = "offset", + value = "The starting pagination index for the complete list of qualified items.", + required = false, + defaultValue = "0") + @QueryParam("offset") + int offset, + @ApiParam( + name = "limit", + value = "Provide how many activity details you require from the starting pagination index/offset.", + required = false, + defaultValue = "5") + @QueryParam("limit") + int limit, + @ApiParam( + name = "searchContext", + value = "The properties to advanced search devices.", + required = true) + SearchContext searchContext); + + @GET + @Path("/{type}/{id}/applications") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting Installed Application Details of a Device", + notes = "Get the list of applications subscribed to by a device.", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:applications") + }) + + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the list of applications.", + response = Application.class, + responseContainer = "List", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified\n" + + "Used by caches, or in conditional requests.")}), + @ApiResponse( + code = 303, + message = "See Other. \n " + + "The source can be retrieved from the URL specified in the location header.\n", + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "The Source URL of the document.")}), + @ApiResponse( + code = 304, + message = "Not Modified. \n " + + "Empty body because the client already has the latest version of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified device does not exist.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable. \n The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving the list of installed application on the device.", + response = ErrorResponse.class) + }) + Response getInstalledApplications( + @ApiParam( + name = "type", + value = "The device type name, such as ios, android, windows or fire-alarm.", + required = true) + @PathParam("type") + @Size(max = 45) + String type, + @ApiParam( + name = "id", + value = "The device identifier of the device.", + required = true) + @PathParam("id") + @Size(max = 45) + String id, + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time. \n" + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") + String ifModifiedSince, + @ApiParam( + name = "offset", + value = "The starting pagination index for the complete list of qualified items.", + required = false, + defaultValue = "0") + @QueryParam("offset") + int offset, + @ApiParam( + name = "limit", + value = "Provide how many application details you require from the starting pagination index/offset.", + required = false, + defaultValue = "5") + @QueryParam("limit") + int limit); + + @GET + @Path("/{type}/{id}/operations") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting Device Operation Details", + notes = "Get the details of operations carried out on a selected device.", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:operations") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the list of operations scheduled for the device.", + response = Operation.class, + responseContainer = "List", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified" + + "Used by caches, or in conditional requests.")}), + @ApiResponse( + code = 303, + message = "See Other. \n " + + "The source can be retrieved from the URL specified in the location header.\n", + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "The Source URL of the document.")}), + @ApiResponse( + code = 304, + message = "Not Modified. \n " + + "Empty body because the client already has the latest version of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified device does not exist.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable. \n The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving the operation list scheduled for the device.", + response = ErrorResponse.class) + }) + Response getDeviceOperations( + @ApiParam( + name = "type", + value = "The device type name, such as ios, android, windows or fire-alarm.", + required = true) + @PathParam("type") + @Size(max = 45) + String type, + @ApiParam( + name = "id", + value = "The device identifier of the device you wish to get details.\n" + + "INFO: Make sure to add the ID of a device that is already registered with WSO2 IoTS.", + required = true) + @PathParam("id") + @Size(max = 45) + String id, + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time. \n" + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") + String ifModifiedSince, + @ApiParam( + name = "offset", + value = "The starting pagination index for the complete list of qualified items.", + required = false, + defaultValue = "0") + @QueryParam("offset") + int offset, + @ApiParam( + name = "limit", + value = "Provide how many activity details you require from the starting pagination index/offset.", + required = false, + defaultValue = "5") + @QueryParam("limit") + int limit); + + @GET + @Path("/{type}/{id}/effective-policy") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Get the details of the policy that is enforced on a device.", + notes = "A policy is enforced on all the devices that register with WSO2 IoTS." + + "WSO2 IoTS filters the policies based on the device platform (device type)," + + "the device ownership type, the user role or name and finally, the policy that matches these filters will be enforced on the device.", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:effective-policy") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully returned the details of the policy enforced on the device.", + response = Policy.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests.")}), + @ApiResponse( + code = 303, + message = "See Other. \n " + + "The source can be retrieved from the URL specified in the location header.\n", + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "The Source URL of the document.")}), + @ApiResponse( + code = 304, + message = "Not Modified. \n " + + "Empty body because the client already has the latest version of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified device does not exist.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable. \n The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving the policy details that is enforced on the device.", + response = ErrorResponse.class) + } + ) + Response getEffectivePolicyOfDevice( + @ApiParam( + name = "type", + value = "The device type name, such as ios, android, windows or fire-alarm.", + required = true) + @PathParam("type") + @Size(max = 45) + String type, + @ApiParam( + name = "id", + value = "The device identifier.", + required = true) + @PathParam("id") + @Size(max = 45) + String id, + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time. \n" + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") + String ifModifiedSince); + + + @GET + @Path("{type}/{id}/compliance-data") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting Policy Compliance Details of a Device", + notes = "A policy is enforced on the devices that register with WSO2 IoTS. " + + "The server checks if the settings in the device comply with the policy that is enforced on the device using this REST API.", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:compliance-data") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK", + response = NonComplianceData.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Error occurred while getting the compliance data.", + response = ErrorResponse.class) + } + ) + Response getComplianceDataOfDevice( + @ApiParam( + name = "type", + value = "The device type, such as ios, android or windows.", + required = true) + @PathParam("type") + @Size(max = 45) + String type, + @ApiParam( + name = "id", + value = "Device Identifier", + required = true) + @PathParam("id") + @Size(max = 45) + String id); + + @PUT + @Path("/{type}/{id}/changestatus") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + consumes = MediaType.APPLICATION_JSON, + httpMethod = "PUT", + value = "Change device status by device id.", + notes = "Returns the status of the changed device operation.", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:change-status") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully changed the device status.", + response = Device.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest " + + "version of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n No device is found under the provided type and id.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving information requested device.", + response = ErrorResponse.class) + }) + Response changeDeviceStatus( + @ApiParam( + name = "type", + value = "The device type, such as ios, android or windows.", + required = true) + @PathParam("type") + @Size(max = 45) + String type, + @ApiParam( + name = "id", + value = "Device id", + required = true) + @PathParam("id") + @Size(max = 45) + String id, + @ApiParam( + name = "newStatus", + value = "New status of the device.", + required = true) + @QueryParam("newStatus") + EnrolmentInfo.Status newStatus); + + @POST + @Path("/{type}/operations") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + consumes = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Add operation to set of devices for a given device type", + notes = "Returns the Activity Related to the operation.", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:operations") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 201, + message = "OK. \n Successfully added the operation.", + response = Activity.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest " + + "version of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n No device is found under the provided type and id.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving information requested device.", + response = ErrorResponse.class) + }) + Response addOperation(@ApiParam(name = "type", value = "The device type, such as ios, android or windows... etc.", required = true) + @PathParam("type") String type, + @ApiParam(name = "deviceOperation", value = "Operation object with device ids.", required = true) + @Valid OperationRequest operationRequest); + + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceTypeManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceTypeManagementService.java new file mode 100644 index 0000000000..97c8efc067 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceTypeManagementService.java @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.api; + +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Info; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.Extension; +import io.swagger.annotations.Tag; +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.ResponseHeader; +import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.device.mgt.core.dto.DeviceType; +import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceTypeList; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; + +import javax.validation.constraints.Size; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +@SwaggerDefinition( + info = @Info( + version = "0.9.0", + title = "", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "DeviceTypeManagement"), + @ExtensionProperty(name = "context", value = "/api/device-mgt/v0.9/device-types"), + }) + } + ), + tags = { + @Tag(name = "device_management", description = "") + } +) +@Scopes( + scopes = { + @Scope( + name = "Getting the Supported Device Platforms", + description = "Getting the Supported Device Platforms", + key = "perm:device-types:types", + permissions = {"/device-mgt/devices/owning-device/view"} + ), + @Scope( + name = "Get Feature Details of a Device Type", + description = "Get Feature Details of a Device Type", + key = "perm:device-types:features", + permissions = {"/device-mgt/devices/owning-device/view"} + ) + } +) +@Path("/device-types") +@Api(value = "Device Type Management", description = "This API corresponds to all tasks related to device " + + "type management") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public interface DeviceTypeManagementService { + + @GET + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting the Supported Device Platforms", + notes = "Get the list of device platforms supported by WSO2 EMM.", + tags = "Device Type Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:device-types:types") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the list of supported device types.", + response = DeviceTypeList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = + "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + } + ), + @ApiResponse( + code = 304, + message = + "Not Modified. \n Empty body because the client already has the latest version " + + "of the requested resource.\n"), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the " + + "list of supported device types.", + response = ErrorResponse.class) + } + ) + Response getDeviceTypes( + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time.\n" + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") + String ifModifiedSince); + + @GET + @Path("/{type}/features") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Get Feature Details of a Device Type", + notes = "The features in WSO2 EMM enables you to carry out many operations on a given device platform. " + + "Using this REST API you can get the features that can be carried out on a preferred device type," + + " such as iOS, Android or Windows.", + tags = "Device Type Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:device-types:features") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the list of supported features.", + response = DeviceTypeList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = + "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + } + ), + @ApiResponse( + code = 304, + message = + "Not Modified. \n Empty body because the client already has the latest version " + + "of the requested resource.\n"), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the " + + "list of supported device types.", + response = ErrorResponse.class) + } + ) + Response getFeatures( + @ApiParam( + name = "type", + value = "The device type name, such as ios, android, windows or fire-alarm.", + required = true) + @PathParam("type") + @Size(max = 45) + String type, + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time.\n" + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") + String ifModifiedSince); + + @GET + @Path("/all/{type}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting Details of a Device Type", + notes = "Get the details of a device by searching via the device type and the tenant domain.", + response = DeviceType.class, + tags = "Device Type Management Administrative Service", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:device-types:types") + }) + } + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. \n Successfully fetched the device type.", + response = DeviceType.class, + responseContainer = "List", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body") + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest version of the " + + "requested resource.\n"), + @ApiResponse( + code = 401, + message = "Unauthorized.\n The unauthorized access to the requested resource.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found.\n The specified device does not exist", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the device list.", + response = ErrorResponse.class) + }) + Response getDeviceTypeByName( + @ApiParam( + name = "type", + value = "The device type name, such as ios, android, windows or fire-alarm.", + required = true) + @PathParam("type") + @Size(min = 2, max = 45) + String type); + + @GET + @Path("/all") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Retrieve device types information", + notes = "Retrieve device types information.", + response = DeviceType.class, + tags = "Device Type Management Administrative Service", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:device-types:types") + }) + } + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. \n Successfully fetched the device type.", + response = DeviceType.class, + responseContainer = "List", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body") + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest version of the " + + "requested resource.\n"), + @ApiResponse( + code = 401, + message = "Unauthorized.\n The unauthorized access to the requested resource.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found.\n The specified device does not exist", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the device list.", + response = ErrorResponse.class) + }) + Response getDeviceTypes(); + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GeoLocationBasedService.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GeoLocationBasedService.java new file mode 100644 index 0000000000..b2fbeb4c87 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GeoLocationBasedService.java @@ -0,0 +1,551 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + + +package org.wso2.carbon.device.mgt.jaxrs.service.api; + +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.Extension; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.Info; +import io.swagger.annotations.ResponseHeader; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.device.mgt.common.geo.service.Alert; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; + +import javax.validation.Valid; +import javax.validation.constraints.Size; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Response; + +@SwaggerDefinition( + info = @Info( + version = "0.9.0", + title = "", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "geo_services"), + @ExtensionProperty(name = "context", value = "/api/device-mgt/v0.9/geo-services"), + }) + } + ), + tags = { + @Tag(name = "device_management", description = "") + } +) +@Scopes( + scopes = { + @Scope( + name = "View Analytics", + description = "", + key = "perm:geo-service:analytics-view", + permissions = {"/device-mgt/devices/owning-device/view-analytics"} + ), + @Scope( + name = "Manage Alerts", + description = "", + key = "perm:geo-service:alerts-manage", + permissions = {"/device-mgt/devices/owning-device/manage-alerts"} + ) + } +) +@Path("/geo-services") +@Api(value = "Geo Service", + description = "This carries all the resources related to the geo service functionalities.") +public interface GeoLocationBasedService { + /** + * Retrieve Analytics for the device type + */ + @GET + @Path("stats/{deviceType}/{deviceId}") + @ApiOperation( + consumes = "application/json", + produces = "application/json", + httpMethod = "GET", + value = "Retrieve Analytics for the device type", + notes = "", + response = Response.class, + tags = "Geo Service Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:geo-service:analytics-view") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK.", + response = Response.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid Device Identifiers found.", + response = Response.class), + @ApiResponse( + code = 401, + message = "Unauthorized. \n Unauthorized request."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error on retrieving stats", + response = Response.class) + }) + Response getGeoDeviceStats( + @ApiParam( + name = "deviceId", + value = "The registered device Id.", + required = true) + @PathParam("deviceId") String deviceId, + @ApiParam( + name = "device-type", + value = "The device type, such as ios, android or windows.", + required = true) + @PathParam("deviceType") + @Size(max = 45) + String deviceType, + @ApiParam( + name = "from", + value = "Get stats from what time", + required = true) + @QueryParam("from") long from, + @ApiParam( + name = "to", + value = "Get stats up to what time", + required = true) + @QueryParam("to") long to); + + /** + * Get data to show device locations in a map + */ + @GET + @Path("stats/deviceLocations") + @ApiOperation( + consumes = "application/json", + produces = "application/json", + httpMethod = "GET", + value = "Retrieve locations of devices", + notes = "", + response = Response.class, + tags = "Geo Service Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:geo-service:analytics-view") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK.", + response = Response.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid parameters found.", + response = Response.class), + @ApiResponse( + code = 401, + message = "Unauthorized. \n Unauthorized request."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error on retrieving stats", + response = Response.class) + }) + Response getGeoDeviceLocations( + @ApiParam( + name = "minLat", + value = "minimum latitude", + required = true) + @QueryParam("minLat") double minLat, + @ApiParam( + name = "maxLat", + value = "maxmimum latitude", + required = true) + @QueryParam("maxLat") double maxLat, + @ApiParam( + name = "minLong", + value = "minimum longitude", + required = true) + @QueryParam("minLong") double minLong, + @ApiParam( + name = "maxLong", + value = "maximum longitudeude", + required = true) + @QueryParam("maxLong") double maxLong, + @ApiParam( + name = "zoom", + value = "zoom level", + required = true) + @QueryParam("zoom") int zoom); + + + /** + * Create Geo alerts + */ + @POST + @Path("alerts/{alertType}/{deviceType}/{deviceId}") + @ApiOperation( + consumes = "application/json", + produces = "application/json", + httpMethod = "GET", + value = "Create Geo alerts for the device", + notes = "", + response = Response.class, + tags = "Geo Service Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:geo-service:alerts-manage") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK.", + response = Response.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body") + }), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid Device Identifiers found.", + response = Response.class), + @ApiResponse( + code = 401, + message = "Unauthorized. \n Unauthorized request."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error on retrieving stats", + response = Response.class) + }) + Response createGeoAlerts( + @ApiParam( + name = "alert", + value = "The alert object", + required = true) + @Valid Alert alert, + @ApiParam( + name = "deviceId", + value = "The registered device Id.", + required = true) + @PathParam("deviceId") String deviceId, + @ApiParam( + name = "device-type", + value = "The device type, such as ios, android or windows.", + required = true) + @PathParam("deviceType") + @Size(max = 45) + String deviceType, + @ApiParam( + name = "alertType", + value = "The alert type, such as Within, Speed, Stationary", + required = true) + @PathParam("alertType") String alertType); + + /** + * Update Geo alerts + */ + @PUT + @Path("alerts/{alertType}/{deviceType}/{deviceId}") + @ApiOperation( + consumes = "application/json", + produces = "application/json", + httpMethod = "GET", + value = "Update Geo alerts for the device", + notes = "", + response = Response.class, + tags = "Geo Service Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:geo-service:alerts-manage") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK.", + response = Response.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body") + }), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid Device Identifiers found.", + response = Response.class), + @ApiResponse( + code = 401, + message = "Unauthorized. \n Unauthorized request."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error on retrieving stats", + response = Response.class) + }) + Response updateGeoAlerts( + @ApiParam( + name = "alert", + value = "The alert object", + required = true) + @Valid Alert alert, + @ApiParam( + name = "deviceId", + value = "The registered device Id.", + required = true) + @PathParam("deviceId") String deviceId, + @ApiParam( + name = "device-type", + value = "The device type, such as ios, android or windows.", + required = true) + @PathParam("deviceType") + @Size(max = 45) + String deviceType, + @ApiParam( + name = "alertType", + value = "The alert type, such as Within, Speed, Stationary", + required = true) + @PathParam("alertType") String alertType); + + /** + * Retrieve Geo alerts + */ + @GET + @Path("alerts/{alertType}/{deviceType}/{deviceId}") + @ApiOperation( + consumes = "application/json", + produces = "application/json", + httpMethod = "GET", + value = "Retrieve Geo alerts for the device", + notes = "", + response = Response.class, + tags = "Geo Service Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:geo-service:alerts-manage") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK.", + response = Response.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests.") + }), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid Device Identifiers found.", + response = Response.class), + @ApiResponse( + code = 401, + message = "Unauthorized. \n Unauthorized request."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error on retrieving stats", + response = Response.class) + }) + Response getGeoAlerts( + @ApiParam( + name = "deviceId", + value = "The registered device Id.", + required = true) + @PathParam("deviceId") String deviceId, + @ApiParam( + name = "device-type", + value = "The device type, such as ios, android or windows.", + required = true) + @PathParam("deviceType") + @Size(max = 45) + String deviceType, + @ApiParam( + name = "alertType", + value = "The alert type, such as Within, Speed, Stationary", + required = true) + @PathParam("alertType") String alertType); + + /** + * Retrieve Geo alerts history + */ + @GET + @Path("alerts/history/{deviceType}/{deviceId}") + @ApiOperation( + consumes = "application/json", + produces = "application/json", + httpMethod = "GET", + value = "Retrieve Geo alerts history for the device", + notes = "", + response = Response.class, + tags = "Geo Service Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:geo-service:alerts-manage") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK.", + response = Response.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests.") + }), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid Device Identifiers found.", + response = Response.class), + @ApiResponse( + code = 401, + message = "Unauthorized. \n Unauthorized request."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error on retrieving stats", + response = Response.class) + }) + Response getGeoAlertsHistory( + @ApiParam( + name = "deviceId", + value = "The registered device Id.", + required = true) + @PathParam("deviceId") String deviceId, + @ApiParam( + name = "device-type", + value = "The device type, such as ios, android or windows.", + required = true) + @PathParam("deviceType") + @Size(max = 45) + String deviceType, + @ApiParam( + name = "from", + value = "Get stats from what time", + required = true) + @QueryParam("from") long from, + @ApiParam( + name = "to", + value = "Get stats up to what time", + required = true) + @QueryParam("to") long to); + + @DELETE + @Path("alerts/{alertType}/{deviceType}/{deviceId}") + @ApiOperation( + consumes = "application/json", + produces = "application/json", + httpMethod = "DELETE", + value = "Deletes Geo alerts for the device", + notes = "", + response = Response.class, + tags = "Geo Service Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:geo-service:alerts-manage") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK.", + response = Response.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body") + }), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid Device Identifiers found.", + response = Response.class), + @ApiResponse( + code = 401, + message = "Unauthorized. \n Unauthorized request."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error on retrieving stats", + response = Response.class) + }) + Response removeGeoAlerts( + @ApiParam( + name = "deviceId", + value = "The registered device Id.", + required = true) + @PathParam("deviceId") String deviceId, + @ApiParam( + name = "deviceType", + value = "The device type, such as ios, android or windows.", + required = true) + @PathParam("deviceType") String deviceType, + @ApiParam( + name = "alertType", + value = "The alert type, such as Within, Speed, Stationary", + required = true) + @PathParam("alertType") String alertType, + @ApiParam( + name = "queryName", + value = "The query name.", + required = true) + @QueryParam("queryName") String queryName); +} + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GroupManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GroupManagementService.java new file mode 100644 index 0000000000..b05da2c565 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GroupManagementService.java @@ -0,0 +1,954 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ + +package org.wso2.carbon.device.mgt.jaxrs.service.api; + +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.Extension; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.Info; +import io.swagger.annotations.ResponseHeader; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import org.apache.axis2.transport.http.HTTPConstants; +import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup; +import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceGroupList; +import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceList; +import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceToGroupsAssignment; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.beans.RoleList; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; + +import javax.validation.Valid; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.util.List; + +/** + * Device group related REST-API. This can be used to manipulated device group related details. + */ +@SwaggerDefinition( + info = @Info( + version = "0.9.0", + title = "", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "GroupManagement"), + @ExtensionProperty(name = "context", value = "/api/device-mgt/v0.9/groups"), + }) + } + ), + tags = { + @Tag(name = "device_management", description = "Device group related REST-API. " + + "This can be used to manipulated device group related " + + "details.") + } +) +@Scopes( + scopes = { + @Scope( + name = "Get the list of groups belongs to current user.", + description = "Get the list of groups belongs to current user.", + key = "perm:groups:groups", + permissions = {"/device-mgt/groups/view"} + ), + @Scope( + name = "Get the count of groups belongs to current user.", + description = "Get the count of groups belongs to current user.", + key = "perm:groups:count", + permissions = {"/device-mgt/groups/view"} + ), + @Scope( + name = "Add new device group to the system.", + description = "Add new device group to the system.", + key = "perm:groups:add", + permissions = {"/device-mgt/groups/add"} + ), + @Scope( + name = "View group specified", + description = "View group specified", + key = "perm:groups:groups-view", + permissions = {"/device-mgt/groups/view"} + ), + @Scope( + name = "Update a group", + description = "Update a group", + key = "perm:groups:update", + permissions = {"/device-mgt/groups/update"} + ), + @Scope( + name = "Delete a group", + description = "Delete a group", + key = "perm:groups:remove", + permissions = {"/device-mgt/groups/remove"} + ), + @Scope( + name = "Manage group sharing with a user", + description = "Manage group sharing with a user", + key = "perm:groups:share", + permissions = {"/device-mgt/groups/share"} + ), + @Scope( + name = "View list of roles of a device group", + description = "View list of roles of a device group", + key = "perm:groups:roles", + permissions = {"/device-mgt/groups/roles/view"} + ), + @Scope( + name = "View list of devices in the device group", + description = "View list of devices in the device group", + key = "perm:groups:devices", + permissions = {"/device-mgt/groups/devices/view"} + ), + @Scope( + name = "View list of device count in the device group", + description = "View list of device count in the device group", + key = "perm:groups:devices-count", + permissions = {"/device-mgt/groups/devices/view"} + ), + @Scope( + name = "Add devices to group", + description = "Add devices to group", + key = "perm:groups:devices-add", + permissions = {"/device-mgt/groups/devices/add"} + ), + @Scope( + name = "Remove devices from group", + description = "Remove devices from group", + key = "perm:groups:devices-remove", + permissions = {"/device-mgt/groups/devices/remove"} + ), + @Scope( + name = "Assign devices to groups", + description = "Assign devices to groups", + key = "perm:groups:assign", + permissions = {"/device-mgt/groups/devices/add"} + ), + @Scope( + name = "List of groups that have the device", + description = "List of groups that have the device", + key = "perm:groups:device", + permissions = {"/device-mgt/groups/devices/view"} + ) + } +) +@Path("/groups") +@Api(value = "Device Group Management", description = "This API carries all device group management related " + + "operations such as get all the available groups, etc.") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public interface GroupManagementService { + + @GET + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HTTPConstants.HEADER_GET, + value = "Get the list of groups belongs to current user.", + notes = "Returns all permitted groups enrolled with the system.", + tags = "Device Group Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:groups:groups") + }) + } + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. \n Successfully fetched the list of device groups.", + response = DeviceGroupList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client has already the latest version of " + + "the requested resource."), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the groups list.", + response = ErrorResponse.class) + }) + Response getGroups(@ApiParam( + name = "name", + value = "Name of the group.") + @QueryParam("name") + String name, + @ApiParam( + name = "owner", + value = "Owner of the group.") + @QueryParam("owner") + String owner, + @ApiParam( + name = "offset", + value = "The starting pagination index for the complete list of qualified items.", + defaultValue = "0") + @QueryParam("offset") + int offset, + @ApiParam( + name = "limit", + value = "Provide how many device details you require from the starting pagination index/offset.", + defaultValue = "5") + @QueryParam("limit") + int limit); + + @Path("/count") + @GET + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HTTPConstants.HEADER_GET, + value = "Get the count of groups belongs to current user.", + notes = "Returns count of all permitted groups enrolled with the system.", + tags = "Device Group Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:groups:count") + }) + } + + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. \n Successfully fetched the device group count.", + response = DeviceGroupList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client has already the latest version of " + + "the requested resource."), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the group count.", + response = ErrorResponse.class) + }) + Response getGroupCount(); + + @POST + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + httpMethod = HTTPConstants.HEADER_POST, + value = "Add new device group to the system.", + notes = "Add device group with current user as the owner.", + tags = "Device Group Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:groups:add") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 201, + message = "Created. \n Device group has successfully been created", + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "The URL of the added group."), + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests.") + } + ), + @ApiResponse( + code = 303, + message = "See Other. \n Source can be retrieved from the URL specified at the Location header.", + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "The Source URL of the document.")}), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 401, + message = "Unauthorized. \n Current logged in user is not authorized to add device groups.", + response = ErrorResponse.class), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The entity of the request was in a not supported format."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while adding a new device group.", + response = ErrorResponse.class) + }) + Response createGroup(@ApiParam( + name = "group", + value = "Group object with data.", + required = true) + @Valid DeviceGroup group); + + @Path("/id/{groupId}") + @GET + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HTTPConstants.HEADER_GET, + value = "View group specified.", + notes = "Returns details of group enrolled with the system.", + tags = "Device Group Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:groups:groups-view") + }) + } + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. \n Successfully fetched the device group.", + response = DeviceGroup.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client has already the latest version of " + + "the requested resource."), + @ApiResponse( + code = 404, + message = "Group found.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the group details.", + response = ErrorResponse.class) + }) + Response getGroup(@ApiParam( + name = "groupId", + value = "ID of the group to view.", + required = true) + @PathParam("groupId") int groupId); + + @Path("/id/{groupId}") + @PUT + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HTTPConstants.HEADER_PUT, + value = "Update a group.", + notes = "If you wish to make changes to an existing group, that can be done by updating the group using " + + "this resource.", + tags = "Device Group Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:groups:update") + }) + } + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. \n Group has been updated successfully.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body."), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client has already the latest version of " + + "the requested resource."), + @ApiResponse( + code = 404, + message = "Group not found.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while updating the group.", + response = ErrorResponse.class) + }) + Response updateGroup(@ApiParam( + name = "groupId", + value = "ID of the group to be updated.", + required = true) + @PathParam("groupId") int groupId, + @ApiParam( + name = "group", + value = "Group object with data.", + required = true) + @Valid DeviceGroup deviceGroup); + + @Path("/id/{groupId}") + @DELETE + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HTTPConstants.HEADER_DELETE, + value = "Delete a group.", + notes = "If you wish to remove an existing group, that can be done by updating the group using " + + "this resource.", + tags = "Device Group Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:groups:remove") + }) + } + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. \n Group has been deleted successfully.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body."), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client has already the latest version of " + + "the requested resource."), + @ApiResponse( + code = 404, + message = "Group not found.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while removing the group.", + response = ErrorResponse.class) + }) + Response deleteGroup(@ApiParam( + name = "groupId", + value = "ID of the group to be deleted.", + required = true) + @PathParam("groupId") int groupId); + + @Path("/id/{groupId}/share") + @POST + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HTTPConstants.HEADER_POST, + value = "Manage group sharing with a user.", + notes = "If you wish to share /un share an existing group with a user under defined sharing roles, " + + "that can be done using this resource.", + tags = "Device Group Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:groups:share") + }) + } + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. \n Sharing has been updated successfully.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body."), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client has already the latest version of " + + "the requested resource."), + @ApiResponse( + code = 404, + message = "Group not found.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while sharing the group.", + response = ErrorResponse.class) + }) + Response manageGroupSharing(@ApiParam( + name = "groupName", + value = "Name of the group to be shared or unshared.", + required = true) + @PathParam("groupId") int groupId, + @ApiParam( + name = "userRoles", + value = "User roles to share group with.", + required = true) + @Valid List userRoles); + + @Path("/id/{groupId}/roles") + @GET + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HTTPConstants.HEADER_GET, + value = "View list of roles of a device group.", + notes = "Returns details of roles which particular group has been shared with.", + tags = "Device Group Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:groups:roles") + }) + } + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. \n Successfully fetched the users.", + response = RoleList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client has already the latest version of " + + "the requested resource."), + @ApiResponse( + code = 404, + message = "Group not found.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the roles.", + response = ErrorResponse.class) + }) + Response getRolesOfGroup(@ApiParam( + name = "groupId", + value = "ID of the group.", + required = true) + @PathParam("groupId") int groupId); + + @Path("/id/{groupId}/devices") + @GET + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HTTPConstants.HEADER_GET, + value = "View list of devices in the device group.", + notes = "Returns list of devices in the device group.", + tags = "Device Group Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:groups:devices") + }) + } + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. \n Successfully fetched the devices.", + response = DeviceList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client has already the latest version of " + + "the requested resource."), + @ApiResponse( + code = 404, + message = "Group not found.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the devices.", + response = ErrorResponse.class) + }) + Response getDevicesOfGroup(@ApiParam( + name = "groupId", + value = "ID of the group.", + required = true) + @PathParam("groupId") + int groupId, + @ApiParam( + name = "offset", + value = "The starting pagination index for the complete list of qualified items.", + defaultValue = "0") + @QueryParam("offset") + int offset, + @ApiParam( + name = "limit", + value = "Provide how many device details you require from the starting pagination index/offset.", + defaultValue = "5") + @QueryParam("limit") + int limit); + + @Path("/id/{groupId}/devices/count") + @GET + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HTTPConstants.HEADER_GET, + value = "View list of device count in the device group.", + notes = "Returns device count in the device group.", + tags = "Device Group Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:groups:devices-count") + }) + } + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. \n Successfully fetched the device count.", + response = DeviceList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client has already the latest version of " + + "the requested resource."), + @ApiResponse( + code = 404, + message = "No groups found.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching device count.", + response = ErrorResponse.class) + }) + Response getDeviceCountOfGroup(@ApiParam( + name = "groupId", + value = "ID of the group.", + required = true) + @PathParam("groupId") int groupId); + + @Path("/id/{groupId}/devices/add") + @POST + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HTTPConstants.HEADER_POST, + value = "Add devices to group.", + notes = "Add existing devices to the device group.", + tags = "Device Group Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:groups:devices-add") + }) + } + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. \n Successfully add devices to the group.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client has already the latest version of " + + "the requested resource."), + @ApiResponse( + code = 404, + message = "No groups found.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while adding devices to the group.", + response = ErrorResponse.class) + }) + Response addDevicesToGroup(@ApiParam( + name = "groupId", + value = "ID of the group.", + required = true) + @PathParam("groupId") int groupId, + @ApiParam( + name = "deviceIdentifiers", + value = "Device identifiers of the devices which needed be added.", + required = true) + @Valid List deviceIdentifiers); + + @Path("/id/{groupId}/devices/remove") + @POST + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HTTPConstants.HEADER_DELETE, + value = "Remove devices from group.", + notes = "Remove existing devices from the device group.", + tags = "Device Group Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:groups:devices-remove") + }) + } + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. \n Successfully removed devices from the group.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client has already the latest version of " + + "the requested resource."), + @ApiResponse( + code = 404, + message = "No groups found.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while removing devices from the group.", + response = ErrorResponse.class) + }) + Response removeDevicesFromGroup(@ApiParam( + name = "groupId", + value = "ID of the group.", + required = true) + @PathParam("groupId") int groupId, + @ApiParam( + name = "deviceIdentifiers", + value = "Device identifiers of the devices which needed to be removed.", + required = true) + @Valid List deviceIdentifiers); + + @Path("/device/assign") + @POST + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HTTPConstants.HEADER_POST, + value = "Assign devices to groups", + notes = "Add existing device to device groups.", + tags = "Device Group Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:groups:assign") + }) + } + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. \n Successfully assign the device to groups.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client has already the latest version of " + + "the requested resource."), + @ApiResponse( + code = 404, + message = "No groups found.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while adding devices to the group.", + response = ErrorResponse.class) + }) + Response updateDeviceAssigningToGroups( + @ApiParam( + name = "deviceToGroupsAssignment", + value = "Device to groups assignment", + required = true) + @Valid DeviceToGroupsAssignment deviceToGroupsAssignment); + + @Path("/device") + @GET + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HTTPConstants.HEADER_GET, + value = "List of groups that have the device", + notes = "List of groups that have the device.", + tags = "Device Group Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:groups:device") + }) + } + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client has already the latest version of " + + "the requested resource."), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred.", + response = ErrorResponse.class) + }) + Response getGroups( + @ApiParam( + name = "deviceId", + value = "Id of the device.", + required = true) + @QueryParam("deviceId") + String deviceId, + @ApiParam( + name = "deviceType", + value = "Type of the device.", + required = true) + @QueryParam("deviceType") + String deviceType); + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/NotificationManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/NotificationManagementService.java new file mode 100644 index 0000000000..e2a6e960af --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/NotificationManagementService.java @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.api; + +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Info; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.Extension; +import io.swagger.annotations.Tag; +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.ResponseHeader; +import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.device.mgt.common.notification.mgt.Notification; +import org.wso2.carbon.device.mgt.jaxrs.NotificationList; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Size; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +/** + * Notifications related REST-API. + */ + +@SwaggerDefinition( + info = @Info( + version = "0.9.0", + title = "", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "DeviceNotificationManagement"), + @ExtensionProperty(name = "context", value = "/api/device-mgt/v0.9/notifications"), + }) + } + ), + tags = { + @Tag(name = "device_management", description = "") + } +) +@Scopes( + scopes = { + @Scope( + name = "Getting All Device Notification Details", + description = "Getting All Device Notification Details", + key = "perm:notifications:view", + permissions = {"/device-mgt/notifications/view"} + ), + @Scope( + name = "Updating the Device Notification Status", + description = "Updating the Device Notification Status", + key = "perm:notifications:mark-checked", + permissions = {"/device-mgt/notifications/view"} + ) + } +) +@Api(value = "Device Notification Management", description = "Device notification related operations can be found here.") +@Path("/notifications") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public interface NotificationManagementService { + + @GET + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting All Device Notification Details", + notes = "Get the details of all the notifications that were pushed to the devices registered with WSO2 EMM using this REST API.", + tags = "Device Notification Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:notifications:view") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the list of notifications.", + response = NotificationList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client already has the latest version " + + "of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid notification status type received. \n" + + "Valid status types are NEW | CHECKED", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n There are no notification.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported"), + @ApiResponse( + code = 500, + message = "Internal Server Error. " + + "\n Server error occurred while fetching the notification list.", + response = ErrorResponse.class) + }) + Response getNotifications( + @ApiParam( + name = "status", + value = "The status of the notification. Provide any of the following values: \n" + + " - NEW: Will keep the message in the unread state.\n" + + " - CHECKED: Will keep the message in the read state.", + allowableValues = "NEW, CHECKED", + required = false) + @QueryParam("status") @Size(max = 45) + String status, + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time. \n" + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") + String ifModifiedSince, + @ApiParam( + name = "offset", + value = "The starting pagination index for the complete list of qualified items.", + required = false, + defaultValue = "0") + @QueryParam("offset") + int offset, + @ApiParam( + name = "limit", + value = "Provide how many notification details you require from the starting pagination index/offset.", + required = false, + defaultValue = "5") + @QueryParam("limit") + int limit); + + @PUT + @Path("/{id}/mark-checked") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "PUT", + value = "Updating the Device Notification Status", + notes = "When a user has read the the device notification the device notification status must " + + "change from NEW to CHECKED. This API is used to update device notification status.", + tags = "Device Notification Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:notifications:mark-checked") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK", + response = Notification.class), + @ApiResponse( + code = 200, + message = "Notification updated successfully. But the retrial of the updated " + + "notification failed.", + response = Notification.class), + @ApiResponse( + code = 500, + message = "Error occurred while updating notification status.") + } + ) + Response updateNotificationStatus( + @ApiParam( + name = "id", + value = "The notification ID.", + required = true, + defaultValue = "1") + @PathParam("id") @Max(45) + int id); +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/PolicyManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/PolicyManagementService.java new file mode 100644 index 0000000000..26edaccfad --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/PolicyManagementService.java @@ -0,0 +1,687 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.api; + +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.Extension; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.Info; +import io.swagger.annotations.ResponseHeader; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.device.mgt.common.policy.mgt.Policy; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.beans.PolicyWrapper; +import org.wso2.carbon.device.mgt.jaxrs.beans.PriorityUpdatedPolicyWrapper; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; + +import javax.validation.Valid; +import javax.validation.constraints.Size; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.util.List; + +/** + * Policy related REST-API. This can be used to manipulated policies and associate them with devices, users, roles, + * groups. + */ + +@SwaggerDefinition( + info = @Info( + version = "0.9.0", + title = "", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "DevicePolicyManagement"), + @ExtensionProperty(name = "context", value = "/api/device-mgt/v0.9/policies"), + }) + } + ), + tags = { + @Tag(name = "device_management", description = "") + } +) +@Scopes( + scopes = { + @Scope( + name = "Adding a Policy", + description = "Adding a Policy", + key = "perm:policies:manage", + permissions = {"/device-mgt/policies/manage"} + ), + @Scope( + name = "Getting Details of Policies", + description = "Getting Details of Policies", + key = "perm:policies:get-details", + permissions = {"/device-mgt/policies/view"} + ), + @Scope( + name = "Getting Details of a Policy", + description = "Getting Details of a Policy", + key = "perm:policies:get-policy-details", + permissions = {"/device-mgt/policies/view"} + ), + @Scope( + name = "Updating a Policy", + description = "Updating a Policy", + key = "perm:policies:update", + permissions = {"/device-mgt/policies/manage"} + ), + @Scope( + name = "Removing Multiple Policies", + description = "Removing Multiple Policies", + key = "perm:policies:remove", + permissions = {"/device-mgt/policies/manage"} + ), + @Scope( + name = "Activating Policies", + description = "Activating Policies", + key = "perm:policies:activate", + permissions = {"/device-mgt/policies/manage"} + ), + @Scope( + name = "Deactivating Policies", + description = "Deactivating Policies", + key = "perm:policies:deactivate", + permissions = {"/device-mgt/policies/manage"} + ), + @Scope( + name = "Applying Changes on Policies", + description = "Applying Changes on Policies", + key = "perm:policies:changes", + permissions = {"/device-mgt/policies/manage"} + ), + @Scope( + name = "Updating the Policy Priorities", + description = "Updating the Policy Priorities", + key = "perm:policies:priorities", + permissions = {"/device-mgt/policies/manage"} + ), + @Scope( + name = "Fetching the Effective Policy", + description = "Fetching the Effective Policy", + key = "perm:policies:effective-policy", + permissions = {"/device-mgt/policies/view"} + ) + } +) +@Api(value = "Device Policy Management", description = "This API includes the functionality around device policy management") +@Path("/policies") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public interface PolicyManagementService { + + @POST + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Adding a Policy", + notes = "Add a policy using this REST API command. When adding a policy you will have the option of saving the policy or saving and publishing the policy." + + "Using this REST API you are able to save a created Policy and this policy will be in the inactive state.", + tags = "Device Policy Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:policies:manage") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 201, + message = "Created. \n Successfully created the policy.", + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "The URL of the added policy."), + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests.") + } + ), + @ApiResponse( + code = 303, + message = "See Other. \n The source can be retrieved from the URL specified in the location header", + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "The Source URL of the document.")}), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 401, + message = "Not Found. \n The user that is currently logged in is not authorized to add policies.", + response = ErrorResponse.class), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The format of the requested entity was not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while adding a new policy.", + response = ErrorResponse.class) + }) + Response addPolicy( + @ApiParam( + name = "policy", + value = "The properties required to add a new policy.", + required = true) + @Valid PolicyWrapper policy); + + @GET + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting Details of Policies", + responseContainer = "List", + notes = "Retrieve the details of all the policies in WSO2 EMM.", + response = Policy.class, + tags = "Device Policy Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:policies:get-details") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched policies.", + response = Policy.class, + responseContainer = "List", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + } + ), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client already has the latest version of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported"), + @ApiResponse( + code = 500, + message = ("Internal Server Error. \n Server error occurred while fetching the policies."), + response = ErrorResponse.class) + }) + Response getPolicies( + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time. \n" + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") + String ifModifiedSince, + @ApiParam( + name = "offset", + value = "The starting pagination index for the complete list of qualified items", + required = false, + defaultValue = "0") + @QueryParam("offset") + int offset, + @ApiParam( + name = "limit", + value = "Provide how many policy details you require from the starting pagination index/offset.", + required = false, + defaultValue = "5") + @QueryParam("limit") + int limit); + + @GET + @Path("/{id}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting Details of a Policy", + notes = "Retrieve the details of a policy that is in WSO2 EMM.", + response = Policy.class, + tags = "Device Policy Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:policies:get-policy-details") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the policy.", + response = Policy.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + } + ), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client already has the latest version of the requested resource.\n"), + @ApiResponse( + code = 404, + message = "Not Found. \n A specified policy was not found.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the " + + "policy.", + response = ErrorResponse.class) + }) + Response getPolicy( + @ApiParam( + name = "id", + value = "The policy identifier.", + required = true, + defaultValue = "") + @PathParam("id") + int id, + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time. \n" + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") + String ifModifiedSince); + + @PUT + @Path("/{id}") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "PUT", + value = "Updating a Policy", + notes = "Make changes to an existing policy by updating the policy using this resource.", + tags = "Device Policy Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:policies:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully updated the policy.", + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "The URL of the updated device."), + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests.") + } + ), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified resource does not exist.", + response = ErrorResponse.class), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The format of the requested entity was not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while updating the policy.", + response = ErrorResponse.class) + }) + Response updatePolicy( + @ApiParam( + name = "id", + value = "The policy ID.", + required = true, + defaultValue = "1") + @PathParam("id") + int id, + @ApiParam( + name = "policy", + value = "Update the required property details.", + required = true) + @Valid PolicyWrapper policy); + + @POST + @Path("/remove-policy") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Removing Multiple Policies", + notes = "Delete one or more than one policy using this API.", + tags = "Device Policy Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:policies:remove") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully removed the policy."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified resource does not exist.", + response = ErrorResponse.class), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The format of the requested entity was not supported.\n " + + "supported format."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred whilst bulk removing policies.", + response = ErrorResponse.class) + }) + Response removePolicies( + @ApiParam( + name = "policyIds", + value = "The list of policy IDs to be removed.", + required = true, + defaultValue = "[1]") + List policyIds); + + @POST + @Path("/activate-policy") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Activating Policies", + notes = "Publish a policy using this API to bring a policy that is in the inactive state to the active state.", + tags = "Device Policy Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:policies:activate") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "Successfully activated the policy."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified resource/s does not exist.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Sever error whilst activating the policies.", + response = ErrorResponse.class) + }) + Response activatePolicies( + @ApiParam( + name = "policyIds", + value = "The list of the policy IDs to be activated", + required = true, + defaultValue = "[1]") + List policyIds); + + @POST + @Path("/deactivate-policy") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Deactivating Policies", + notes = "Unpublish a policy using this API to bring a policy that is in the active state to the inactive state.", + tags = "Device Policy Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:policies:deactivate") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "Successfully deactivated the policy."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified resource does not exist.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "ErrorResponse in deactivating policies.", + response = ErrorResponse.class) + }) + Response deactivatePolicies( + @ApiParam( + name = "policyIds", + value = "The list of Policy IDs that needs to be deactivated.", + required = true, + defaultValue = "[1]") + List policyIds); + + @PUT + @Produces("application/json") + @Path("apply-changes") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "PUT", + value = "Applying Changes on Policies", + notes = "Policies in the active state will be applied to new devices that register with WSO2 EMM based on" + + " the policy enforcement criteria . In a situation where you need to make changes to existing" + + " policies (removing, activating, deactivating and updating) or add new policies, the existing" + + " devices will not receive these changes immediately. Once all the required changes are made" + + " you need to apply the changes to push the policy changes to the existing devices.", + tags = "Device Policy Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:policies:changes") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "Successfully updated the EMM server with the policy changes."), + @ApiResponse( + code = 500, + message = "ErrorResponse in deactivating policies.", + response = ErrorResponse.class) + }) + Response applyChanges(); + + + @PUT + @Path("/priorities") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "PUT", + value = "Updating the Policy Priorities", + notes = "Make changes to the existing policy priority order by updating the priority order using this API.", + tags = "Device Policy Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:policies:priorities") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "Successfully updated the policy priority order."), + @ApiResponse( + code = 400, + message = "Bad Request. Did not update the policy priority order.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Exception in updating the policy priorities.", + response = ErrorResponse.class) + }) + Response updatePolicyPriorities( + @ApiParam( + name = "priorityUpdatedPolicies", + value = "List of policies with priorities", + required = true) + List priorityUpdatedPolicies); + + @GET + @Path("/effective-policy/{deviceType}/{deviceId}") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting the Effective Policy", + notes = "Retrieve the effective policy of a device using this API.", + tags = "Device Policy Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:policies:effective-policy") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the policy.", + response = Policy.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + } + ), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client already has the latest version of the requested resource.\n"), + @ApiResponse( + code = 404, + message = "Not Found. \n A specified policy was not found.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the " + + "policy.", + response = ErrorResponse.class) + }) + Response getEffectivePolicy( + @ApiParam( + name = "deviceType", + value = "The device type name, such as ios, android, windows or fire-alarm.", + required = true) + @PathParam("deviceType") + @Size(max = 45) + String deviceType, + @ApiParam( + name = "deviceId", + value = "The device identifier of the device you want ot get details.", + required = true) + @PathParam("deviceId") + @Size(max = 45) + String deviceId); +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/RemoteSessionService.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/RemoteSessionService.java new file mode 100644 index 0000000000..9f4faf0211 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/RemoteSessionService.java @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + + +package org.wso2.carbon.device.mgt.jaxrs.service.api; + +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.Extension; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.Info; +import io.swagger.annotations.ResponseHeader; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; + +import javax.validation.constraints.Size; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.core.Response; + +@SwaggerDefinition( + info = @Info( + version = "0.9.0", + title = "", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "remote_session_services"), + @ExtensionProperty(name = "context", value = "/api/device-mgt/v0.9/remote-session-services"), + }) + } + ), + tags = { + @Tag(name = "device_management", description = "") + } +) +@Scopes( + scopes = { + @Scope( + name = "Remote Session Connection", + description = "", + key = "perm:remote-session-service:connect", + permissions = {"/device-mgt/devices/owning-device/remote-session"} + ) + } +) +@Path("/remote-session-services") +@Api(value = "Remote Session Service", + description = "This carries all the resources related to the remote session service functionality.") +public interface RemoteSessionService { + /** + * Retrieve Analytics for the device type + */ + @GET + @Path("connection/{deviceType}/{deviceId}") + @ApiOperation( + consumes = "application/json", + produces = "application/json", + httpMethod = "GET", + value = "Retrieve Connection Information for the device type", + notes = "", + response = Response.class, + tags = "Remote Session Service Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:remote-session-service:connect") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK.", + response = Response.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid Device Identifiers found.", + response = Response.class), + @ApiResponse( + code = 401, + message = "Unauthorized. \n Unauthorized request."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error on retrieving stats", + response = Response.class) + }) + Response getRemoteSessionDeviceConnect( + @ApiParam( + name = "deviceId", + value = "The registered device Id.", + required = true) + @PathParam("deviceId") String deviceId, + @ApiParam( + name = "device-type", + value = "The device type, such as ios, android or windows.", + required = true) + @PathParam("deviceType") + @Size(max = 45) + String deviceType); +} \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/RoleManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/RoleManagementService.java new file mode 100644 index 0000000000..02e4929218 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/RoleManagementService.java @@ -0,0 +1,728 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.api; + +import io.swagger.annotations.*; +import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.beans.RoleInfo; +import org.wso2.carbon.device.mgt.jaxrs.beans.RoleList; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; +import org.wso2.carbon.user.mgt.common.UIPermissionNode; + +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.util.List; + +@SwaggerDefinition( + info = @Info( + version = "0.9.0", + title = "", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "RoleManagement"), + @ExtensionProperty(name = "context", value = "/api/device-mgt/v0.9/roles"), + }) + } + ), + tags = { + @Tag(name = "device_management", description = "") + } +) +@Scopes( + scopes = { + @Scope( + name = "Getting the List of Roles", + description = "Getting the List of Roles", + key = "perm:roles:view", + permissions = {"/device-mgt/roles/view"} + ), + @Scope( + name = "Getting Permission Details of a Role", + description = "Getting Permission Details of a Role", + key = "perm:roles:permissions", + permissions = {"/device-mgt/roles/view"} + ), + @Scope( + name = "Getting the List of Roles", + description = "Getting the List of Roles", + key = "perm:roles:details", + permissions = {"/device-mgt/roles/view"} + ), + @Scope( + name = "Adding a Role", + description = "Adding a Role", + key = "perm:roles:add", + permissions = {"/device-mgt/roles/manage"} + ), + @Scope( + name = "Adding a combined Role", + description = "Adding a combined Role", + key = "perm:roles:create-combined-role", + permissions = {"/device-mgt/roles/manage"} + ), + @Scope( + name = "Updating Role Details", + description = "Updating Role Details", + key = "perm:roles:update", + permissions = {"/device-mgt/roles/manage"} + ), + @Scope( + name = "Deleting a Role", + description = "Deleting a Role", + key = "perm:roles:delete", + permissions = {"/device-mgt/roles/manage"} + ), + @Scope( + name = "Adding Users to a Role", + description = "Adding Users to a Role", + key = "perm:roles:add-users", + permissions = {"/device-mgt/roles/manage"} + ) + } +) +@Path("/roles") +@Api(value = "Role Management", description = "Role management related operations can be found here.") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public interface RoleManagementService { + + @GET + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting the List of Roles", + notes = "WSO2 IoTS supports role-based access control (RBAC) and role management. Using this API you can the list of roles that are in WSO2 IoTS.\n" + + "Note: Internal roles, roles created for service-providers, and application related roles will not be given in the output.", + tags = "Role Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:roles:view") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the list of roles in WSO2 IoTS.", + response = RoleList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client already has the latest version of the requested resource."), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching list of roles.", + response = ErrorResponse.class) + }) + Response getRoles( + @ApiParam( + name = "filter", + value = "Provide a character or a few characters in the role name.", + required = false) + @QueryParam("filter") String filter, + @ApiParam( + name = "user-store", + value = "The name of the UserStore you wish to get the list of roles.", + required = false) + @QueryParam("user-store") String userStoreName, + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time." + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") String ifModifiedSince, + @ApiParam( + name = "offset", + value = "The starting pagination index for the complete list of qualified items.", + required = false, + defaultValue = "0") + @QueryParam("offset") int offset, + @ApiParam( + name = "limit", + value = "Provide how many role details you require from the starting pagination index/offset.", + required = false, + defaultValue = "5") + @QueryParam("limit") int limit); + + @GET + @Path("/filter/{prefix}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting the List of Roles filtered by the given prefix", + notes = "WSO2 IoTS supports role-based access control (RBAC) and role management. Using this API you can the list of roles that are in WSO2 IoTS.\n" + + "Note: Internal roles, roles created for service-providers, and application related roles will not be given in the output.", + tags = "Role Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:roles:view") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the list of roles in WSO2 IoTS.", + response = RoleList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client already has the latest version of the requested resource."), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching list of roles.", + response = ErrorResponse.class) + }) + Response getFilteredRoles( + @ApiParam( + name = "prefix", + value = "Filtering prefix of the role.", + required = true, + defaultValue = "") + @PathParam("prefix") String prefix, + @ApiParam( + name = "filter", + value = "Provide a character or a few characters in the role name.", + required = false) + @QueryParam("filter") String filter, + @ApiParam( + name = "user-store", + value = "The name of the UserStore you wish to get the list of roles.", + required = false) + @QueryParam("user-store") String userStoreName, + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time." + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") String ifModifiedSince, + @ApiParam( + name = "offset", + value = "The starting pagination index for the complete list of qualified items.", + required = false, + defaultValue = "0") + @QueryParam("offset") int offset, + @ApiParam( + name = "limit", + value = "Provide how many role details you require from the starting pagination index/offset.", + required = false, + defaultValue = "5") + @QueryParam("limit") int limit); + + @GET + @Path("/{roleName}/permissions") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting Permission Details of a Role", + notes = "An individual is associated a with set of responsibilities based on their " + + "role. In WSO2 IoTS you are able to configure permissions based on the responsibilities carried " + + "out by various roles. Therefore, if you wish to retrieve the permission details of a role, you can do " + + "so using this REST API.", + response = UIPermissionNode.class, + responseContainer = "List", + tags = "Role Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:roles:permissions") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the permissions details for the specified role.", + response = UIPermissionNode.class, + responseContainer = "List", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client already has the latest version of the requested resource.\n"), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified role does not exist.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server ErrorResponse. \n Server error occurred while fetching the permission list for the requested role.", + response = ErrorResponse.class) + }) + Response getPermissionsOfRole( + @ApiParam( + name = "roleName", + value = "The name of the role.", + required = true, + defaultValue = "Engineer") + @PathParam("roleName") String roleName, + @ApiParam( + name = "user-store", + value = "The name of the user store from which you wish to get the permission of role.", + required = false) + @QueryParam("user-store") String userStoreName, + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time." + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") String ifModifiedSince); + + @GET + @Path("/{roleName}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting Details of a Role", + notes = "Get the permissions associated with a role and role specific details using this REST API.", + response = RoleInfo.class, + tags = "Role Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:roles:details") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the details of the role.", + response = RoleInfo.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client already has the latest version of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified role does not exist.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the details of" + + "requested role.", + response = ErrorResponse.class) + }) + Response getRole( + @ApiParam( + name = "roleName", + value = "The name of the role.", + required = true, + defaultValue = "admin") + @PathParam("roleName") String roleName, + @ApiParam( + name = "user-store", + value = "The name of the user store which the particular of role resides in", + required = false) + @QueryParam("user-store") String userStoreName, + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time." + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") String ifModifiedSince); + + @POST + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Adding a Role", + notes = "WSO2 IoTS supports role-based access control (RBAC) and role management. Add a new role to WSO2 IoTS using this REST API.", + tags = "Role Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:roles:add") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 201, + message = "Created. \n Successfully created the role.", + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "The URL to the newly added role."), + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests.")}), + @ApiResponse( + code = 303, + message = "See Other. \n The source can be retrieved from the URL specified in the location header.", + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "The Source URL of the document.")}), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The format of the requested entity was not supported.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while adding a new role.", + response = ErrorResponse.class) + }) + Response addRole( + @ApiParam( + name = "role", + value = "The properties required to add a new role.", + required = true) RoleInfo role); + + @POST + @Path("/create-combined-role/{roleName}") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Adding a combined Role", + notes = "WSO2 IoTS supports role-based access control (RBAC) and role management. Add a new combined role to WSO2 IoTS using this REST API.", + tags = "Role Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:roles:create-combined-role") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 201, + message = "Created. \n Successfully created the role.", + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "The URL to the newly added role."), + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests.")}), + @ApiResponse( + code = 303, + message = "See Other. \n The source can be retrieved from the URL specified in the location header.", + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "The Source URL of the document.")}), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The format of the requested entity was not supported.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while adding a new role.", + response = ErrorResponse.class) + }) + Response addCombinedRole( + @ApiParam( + name = "roles", + value = "List of roles names required to add a new combined role.", + required = true) List roles, + @PathParam("roleName") String roleName, + @QueryParam("user-store") String userStoreName); + + @PUT + @Path("/{roleName}") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "PUT", + value = "Updating Role Details", + notes = "There will be situations where you need to update the role details, such as the permissions" + + " or the role name. Update the role details using this REST API.", + tags = "Role Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:roles:update") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully updated the specified role.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "Content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests.")}), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified role does not exist.", + response = ErrorResponse.class), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The format of the requested entity was not supported.\n", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while updating the role.", + response = ErrorResponse.class) + }) + Response updateRole( + @ApiParam( + name = "roleName", + value = "The name of the role.", + required = true, + defaultValue = "admin") + @PathParam("roleName") String roleName, + @ApiParam( + name = "role", + value = "The properties required to update a role.\n" + + "NOTE: Don't change the role and the permissions of the admin user. " + + "If you want to try out this API by updating all the properties, create a new role and update the properties accordingly.", + required = true) RoleInfo role, + @ApiParam( + name = "user-store", + value = "The name of the user store which the particular role resides in.", + required = false) + @QueryParam("user-store") String userStoreName); + + @DELETE + @Path("/{roleName}") + @ApiOperation( + httpMethod = "DELETE", + value = "Deleting a Role", + notes = "Roles become obsolete over time due to various reasons. In a situation where your Organization identifies that a specific role is no longer required, you " + + "can delete a role using this REST API.", + tags = "Role Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:roles:delete") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully removed the specified role."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified role does not exist.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while removing the role.", + response = ErrorResponse.class) + }) + Response deleteRole( + @ApiParam( + name = "roleName", + value = "The name of the role that needs to de deleted.\n" + + "NOTE: Don't delete the admin role", + required = true) + @PathParam("roleName") String roleName, + @ApiParam( + name = "user-store", + value = "The name of the user store which the particular role resides in.", + required = false) + @QueryParam("user-store") String userStoreName); + + @PUT + @Path("/{roleName}/users") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "PUT", + value = "Adding Users to a Role", + notes = "Defining users to a role at the point of creating a new role is optional. " + + "You can update the users that belong to a given role after you have created " + + "a role using this REST API.\n" + + "Example: Your Organization hires 30 new engineers. Updating the role details for each user can " + + "be cumbersome. Therefore, you can define all the new employees that belong to the engineering " + + "role using this API.", + tags = "Role Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:roles:add-users") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully added the users to the specified role.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "Content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests.")}), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified role does not exist.", + response = ErrorResponse.class), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The format of the requested entity was not supported.\n" + + "supported format.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while adding the user to the specified role.", + response = ErrorResponse.class) + }) + Response updateUsersOfRole( + @ApiParam( + name = "roleName", + value = "The name of the role.", + required = true, + defaultValue = "admin") + @PathParam("roleName") String roleName, + @ApiParam( + name = "user-store", + value = "The name of the user store which the particular role resides in.", + required = false) + @QueryParam("user-store") String userStoreName, + @ApiParam( + name = "users", + value = "Define the users that belong to the role.\n" + + "Multiple users can be added to a role by using comma separated values. ", + required = true, + defaultValue = "[admin]" + ) List users); + + } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java new file mode 100644 index 0000000000..c59e21e724 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java @@ -0,0 +1,808 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.api; + +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Info; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.Extension; +import io.swagger.annotations.Tag; +import io.swagger.annotations.Api; +import io.swagger.annotations.AuthorizationScope; +import io.swagger.annotations.Authorization; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.ResponseHeader; +import org.apache.axis2.transport.http.HTTPConstants; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.device.mgt.jaxrs.beans.BasicUserInfo; +import org.wso2.carbon.device.mgt.jaxrs.beans.BasicUserInfoList; +import org.wso2.carbon.device.mgt.jaxrs.beans.EnrollmentInvitation; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.beans.OldPasswordResetWrapper; +import org.wso2.carbon.device.mgt.jaxrs.beans.RoleList; +import org.wso2.carbon.device.mgt.jaxrs.beans.UserInfo; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; + +import javax.validation.Valid; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.util.List; + +@SwaggerDefinition( + info = @Info( + version = "0.9.0", + title = "", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "UserManagement"), + @ExtensionProperty(name = "context", value = "/api/device-mgt/v0.9/users"), + }) + } + ), + tags = { + @Tag(name = "device_management", description = "") + } +) +@Scopes( + scopes = { + @Scope( + name = "Adding a User", + description = "Adding a User", + key = "perm:users:add", + permissions = {"/device-mgt/users/manage"} + ), + @Scope( + name = "Getting Details of a User", + description = "Getting Details of a User", + key = "perm:users:details", + permissions = {"/device-mgt/users/view"} + ), + @Scope( + name = "Updating Details of a User", + description = "Updating Details of a User", + key = "perm:users:update", + permissions = {"/device-mgt/users/manage"} + ), + @Scope( + name = "Deleting a User", + description = "Deleting a User", + key = "perm:users:delete", + permissions = {"/device-mgt/users/manage"} + ), + @Scope( + name = "Getting the Role Details of a User", + description = "Getting the Role Details of a User", + key = "perm:users:roles", + permissions = {"/device-mgt/users/view"} + ), + @Scope( + name = "Getting Details of Users", + description = "Getting Details of Users", + key = "perm:users:user-details", + permissions = {"/device-mgt/users/view"} + ), + @Scope( + name = "Getting the User Count", + description = "Getting the User Count", + key = "perm:users:count", + permissions = {"/device-mgt/users/view"} + ), + @Scope( + name = "Getting the User existence status", + description = "Getting the User existence status", + key = "perm:users:is-exist", + permissions = {"/device-mgt/users/view"} + ), + @Scope( + name = "Searching for a User Name", + description = "Searching for a User Name", + key = "perm:users:search", + permissions = {"/device-mgt/users/view"} + ), + @Scope( + name = "Changing the User Password", + description = "Adding a User", + key = "perm:users:credentials", + permissions = {"/login"} + ), + @Scope( + name = "Sending Enrollment Invitations to Users", + description = "Sending Enrollment Invitations to Users", + key = "perm:users:send-invitation", + permissions = {"/device-mgt/users/manage"} + ) + } +) +@Path("/users") +@Api(value = "User Management", description = "User management related operations can be found here.") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public interface UserManagementService { + + @POST + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Adding a User", + notes = "WSO2 IoTS supports user management. Add a new user to the WSO2 IoTS user management system via this REST API", + tags = "User Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:users:add") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 201, + message = "Created. \n Successfully created the user.", + responseHeaders = { + @ResponseHeader( + name = "Content-Location", + description = "The URL of the role added."), + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests.")}), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 409, + message = "Conflict. \n User already exists.", + response = ErrorResponse.class), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The entity of the request was in a not " + + "supported format.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while adding a new user.", + response = ErrorResponse.class) + }) + Response addUser( + @ApiParam( + name = "user", + value = "Provide the property details to add a new user.\n" + + "Double click the example value and click try out. ", + required = true) UserInfo user); + + @GET + @Path("/{username}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting Details of a User", + notes = "Get the details of a user registered with WSO2 IoTS using the REST API.", + response = BasicUserInfo.class, + tags = "User Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:users:details") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the details of the specified user.", + response = BasicUserInfo.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client already has the latest version of the requested resource."), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified resource does not exist.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server ErrorResponse. \n Server error occurred while" + + " fetching the ruser details.", + response = ErrorResponse.class) + }) + Response getUser( + @ApiParam( + name = "username", + value = "Provide the username of the user.", + required = true, + defaultValue = "admin") + @PathParam("username") String username, + @ApiParam( + name = "domain", + value = "The domain name of the user store.", + required = false) + @QueryParam("domain") String domain, + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time.\n" + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") String ifModifiedSince); + + @PUT + @Path("/{username}") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "PUT", + value = "Updating Details of a User", + notes = "There will be situations where you will want to update the user details. In such " + + "situation you can update the user details using this REST API.", + tags = "User Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:users:update") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully updated the details of the specified user.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "Content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests.")}), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified resource does not exist.", + response = ErrorResponse.class), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The format of the requested entity was not supported.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while updating the user.", + response = ErrorResponse.class) + }) + Response updateUser( + @ApiParam( + name = "username", + value = "The username of the user.", + required = true, + defaultValue = "admin") + @PathParam("username") String username, + @ApiParam( + name = "domain", + value = "The domain name of the user store.", + required = false) + @QueryParam("domain") String domain, + @ApiParam( + name = "userData", + value = "Update the user details.\n" + + "NOTE: Do not change the admin username, password and roles when trying out this API.", + required = true) UserInfo userData); + + @DELETE + @Path("/{username}") + @ApiOperation( + httpMethod = "DELETE", + value = "Deleting a User", + notes = "When an employee leaves the organization, you can remove the user details from WSO2 IoTS using this REST API.", + tags = "User Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:users:delete") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully removed the user from WSO2 IoTS."), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified resource does not exist.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while removing the user.", + response = ErrorResponse.class + ) + }) + Response removeUser( + @ApiParam( + name = "username", + value = "Username of the user to be deleted.\n" + + "INFO: If you want to try out this API, make sure to create a new user and then remove that user. Do not remove the admin user.", + required = true, + defaultValue = "[Create a new user named Jim, and then try out this API.]") + @PathParam("username") String username, + @ApiParam( + name = "domain", + value = "The domain name of the user store.", + required = false) + @QueryParam("domain") String domain); + + @GET + @Path("/{username}/roles") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting the Role Details of a User", + notes = "A user can be assigned to one or more role in IoTS. Using this REST API you can get the role/roles a user is assigned to.", + tags = "User Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:users:roles") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the list of roles the specified user is assigned to.", + response = RoleList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client already has the latest version of the requested resource."), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified resource does not exist.\n", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the list of roles" + + " assigned to the specified user.", + response = ErrorResponse.class) + }) + Response getRolesOfUser( + @ApiParam( + name = "username", + value = "The username of the user.", + required = true, + defaultValue = "admin") + @PathParam("username") String username, + @ApiParam( + name = "domain", + value = "The domain name of the user store.", + required = false) + @QueryParam("domain") String domain); + + @GET + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting Details of Users", + notes = "You are able to manage users in WSO2 IoTS by adding, updating and removing users. If you wish to get the list of users registered with WSO2 IoTS, you can do so " + + "using this REST API", + tags = "User Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:users:user-details") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the list of users registered with WSO2 IoTS.", + response = BasicUserInfoList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client already has the latest version of " + + "the requested resource.\n"), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the list of WSO2 IoTS users.", + response = ErrorResponse.class) + }) + Response getUsers( + @ApiParam( + name = "filter", + value = "The username of the user.", + required = false) + @QueryParam("filter") String filter, + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time\n." + + "Provide the value in the Java Date Format: EEE, d MMM yyyy HH:mm:ss Z.\n" + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") String timestamp, + @ApiParam( + name = "offset", + value = "The starting pagination index for the complete list of qualified items.", + required = false, + defaultValue = "0") + @QueryParam("offset") int offset, + @ApiParam( + name = "limit", + value = "Provide how many user details you require from the starting pagination index/offset.", + required = false, + defaultValue = "5") + @QueryParam("limit") int limit); + + @GET + @Path("/count") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting the User Count", + notes = "Get the number of users in WSO2 IoTS via this REST API.", + tags = "User Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:users:count") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the user count.", + response = BasicUserInfoList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body") + }), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the total number of users in WSO2 IoTS.", + response = ErrorResponse.class) + }) + Response getUserCount(); + + @GET + @Path("/checkUser") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting the User existence status", + notes = "Check if the user exists in the user store.", + tags = "User Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:users:is-exist") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched user exist status.", + response = BasicUserInfoList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body") + }), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the " + + "total user exist status.", + response = ErrorResponse.class) + }) + Response isUserExists(@ApiParam( + name = "username", + value = "The username of the user.", + required = true) + @QueryParam("username") String userName); + + @GET + @Path("/search/usernames") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Searching for a User Name", + notes = "If you are unsure of the user name of a user and need to retrieve the details of a specific user, you can " + + "search for that user by giving a character or a few characters in the username. " + + "You will be given a list of users having the user name in the exact order of the " + + "characters you provided.", + tags = "User Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:users:search") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the list of users that matched the given filter.", + response = String.class, + responseContainer = "List", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client already has the latest version of the requested resource."), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the list of users that matched the given filter.", + response = ErrorResponse.class) + }) + Response getUserNames( + @ApiParam( + name = "filter", + value = "Provide a character or a few character in the user name", + required = true) + @QueryParam("filter") String filter, + @ApiParam( + name = "domain", + value = "The user store domain which the user names should be fetched from", + required = false) + @QueryParam("domain") String domain, + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time\n." + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z\n. " + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") String timestamp, + @ApiParam( + name = "offset", + value = "The starting pagination index for the complete list of qualified items.", + required = false, + defaultValue = "0") + @QueryParam("offset") int offset, + @ApiParam( + name = "limit", + value = "Provide how many user details you require from the starting pagination index/offset.", + required = false, + defaultValue = "5") + @QueryParam("limit") int limit); + + @PUT + @Path("/credentials") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "PUT", + value = "Changing the User Password", + notes = "A user is able to change the password to secure their WSO2 IoTS profile via this REST API.", + tags = "User Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:users:credentials") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully updated the user credentials."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified resource does not exist.", + response = ErrorResponse.class), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The format of the requested entity was not supported.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while updating the user credentials.", + response = ErrorResponse.class) + }) + Response resetPassword( + @ApiParam( + name = "credentials", + value = "The property to change the password.\n" + + "The password should be within 5 to 30 characters", + required = true) OldPasswordResetWrapper credentials); + + @POST + @Path("/send-invitation") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Sending Enrollment Invitations to Users", + notes = "Send the users a mail inviting them to enroll their devices using the REST API given below.\n" + + "Before running the REST API command to send the enrollment invitations to users make sure to configure WSO2 IoTS as explained in step 4, under the WSO2 IoTS general server configurations documentation.", + tags = "User Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:users:send-invitation") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully sent the invitation mail."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified resource does not exist.\n", + response = ErrorResponse.class), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The format of the requested entity was not supported.\n", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while updating the user credentials.", + response = ErrorResponse.class) + }) + Response inviteExistingUsersToEnrollDevice( + @ApiParam( + name = "users", + value = "List of users", + required = true) List usernames); + + @POST + @Path("/enrollment-invite") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HTTPConstants.HEADER_POST, + value = "Sending Enrollment Invitations to email address", + notes = "Send the a mail inviting recipients to enroll devices.", + tags = "User Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:users:send-invitation") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully sent the invitation mail."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified resource does not exist.\n", + response = ErrorResponse.class), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The format of the requested entity was not supported.\n", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while updating the user credentials.", + response = ErrorResponse.class) + }) + Response inviteToEnrollDevice( + @ApiParam( + name = "enrollmentInvitation", + value = "List of email address of recipients", + required = true) + @Valid EnrollmentInvitation enrollmentInvitation); +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/ApplicationManagementAdminService.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/ApplicationManagementAdminService.java new file mode 100644 index 0000000000..e9a5ff3dc2 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/ApplicationManagementAdminService.java @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.api.admin; + +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Info; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.Extension; +import io.swagger.annotations.Tag; +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 org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; +import org.wso2.carbon.device.mgt.jaxrs.beans.ApplicationWrapper; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; + +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +@SwaggerDefinition( + info = @Info( + version = "0.9.0", + title = "", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "ApplicationManagementAdmin"), + @ExtensionProperty(name = "context", value = "/api/device-mgt/v0.9/admin/applications"), + }) + } + ), + tags = { + @Tag(name = "device_management", description = "") + } +) +@Path("/admin/applications") +@Api(value = "Application Management Administrative Service", description = "This an API intended to be used by " + + "'internal' components to log in as an admin user and do a selected number of operations. " + + "Further, this is strictly restricted to admin users only ") +@Scopes( + scopes = { + @Scope( + name = "Installing an Application (Internal API)", + description = "Installing an Application (Internal API)", + key = "perm:applications:install", + permissions = {"/device-mgt/applications/manage"} + ), + @Scope( + name = "Uninstalling an Application (Internal API)", + description = "Uninstalling an Application (Internal API)", + key = "perm:applications:uninstall", + permissions = {"/device-mgt/applications/manage"} + ) + } +) +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public interface ApplicationManagementAdminService { + + @POST + @Path("/install-application") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Installing an Application (Internal API)", + notes = "This is an internal API that can be used to install an application on a device.", + response = Activity.class, + tags = "Application Management Administrative Service", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:applications:install") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 202, + message = "Accepted. \n The install application operation will be delivered to the specified devices", + response = Activity.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified resource does not exist."), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The format of the requested entity was not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while executing the application install operation in bulk" + + " for a specified set of devices.", + response = ErrorResponse.class) + }) + Response installApplication( + @ApiParam( + name = "applicationWrapper", + value = "Application details of the application to be installed.", + required = true) ApplicationWrapper applicationWrapper); + + @POST + @Path("/uninstall-application") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Uninstalling an Application (Internal API)\n", + notes = "This is an internal API that can be used to uninstall an application.", + response = Activity.class, + tags = "Application Management Administrative Service", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:applications:uninstall") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 202, + message = "Accepted. \n The uninstall application operation will be delivered to the provided devices", + response = Activity.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified resource does not exist."), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The entity of the request was in a not supported format."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while executing the application install" + + " operation in bulk for a specified set of devices.", + response = ErrorResponse.class) + }) + Response uninstallApplication( + @ApiParam( + name = "applicationWrapper", + value = "Application details of the application to be uninstalled.", + required = true) ApplicationWrapper applicationWrapper); + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceAccessAuthorizationAdminService.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceAccessAuthorizationAdminService.java new file mode 100644 index 0000000000..32dc4feba2 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceAccessAuthorizationAdminService.java @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.api.admin; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.Extension; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.Info; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.device.mgt.common.authorization.DeviceAuthorizationResult; +import org.wso2.carbon.device.mgt.jaxrs.beans.AuthorizationRequest; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; + +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +@Path("/admin/authorization") +@Api(value = "Device Authorization Administrative Service", description = "This an API intended to be used by " + + "'internal' components to log in as an admin user and validate whether the user/device are trusted entity." + + "Further, this is strictly restricted to admin users only ") + +@SwaggerDefinition( + info = @Info( + version = "0.9.0", + title = "", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "DeviceAccessAuthorizationAdminService"), + @ExtensionProperty(name = "context", value = "/api/device-mgt/v0.9/admin/authorization"), + }) + } + ), + tags = { + @Tag(name = "device_management", description = "") + } +) +@Scopes( + scopes = { + @Scope( + name = "Verify device authorization", + description = "Verify device authorization", + key = "perm:authorization:verify", + permissions = {"/device-mgt/authorization/verify"} + ) + } +) +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +/** + * This interface provided the definition of the device - user access verification service. + */ +public interface DeviceAccessAuthorizationAdminService { + + @POST + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Check for device access authorization\n", + notes = "This is an internal API that can be used to check for authorization.", + response = DeviceAuthorizationResult.class, + tags = "Authorization Administrative Service", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:authorization:verify") + }) + }) + + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK. \n Authorized device list will be delivered to the requested services", + response = DeviceAuthorizationResult.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified resource does not exist."), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The entity of the request was in a not supported format."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while checking the authorization" + + " for a specified set of devices.", + response = ErrorResponse.class) + }) + Response isAuthorized(AuthorizationRequest authorizationRequest); + + @POST + @Path("/stat") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Check for device access authorization for stat\n", + notes = "This is an internal API that can be used to check for authorization.", + response = DeviceAuthorizationResult.class, + tags = "Authorization Administrative Service", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:authorization:verify") + }) + }) + + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK. \n Authorized device list will be delivered to the requested services", + response = DeviceAuthorizationResult.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified resource does not exist."), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The entity of the request was in a not supported format."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while checking the authorization" + + " for a specified set of devices.", + response = ErrorResponse.class) + }) + Response isAuthorizedForStat(AuthorizationRequest authorizationRequest); +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceAnalyticsArtifactUploaderAdminService.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceAnalyticsArtifactUploaderAdminService.java new file mode 100644 index 0000000000..e3848ee405 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceAnalyticsArtifactUploaderAdminService.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.api.admin; + + +import io.swagger.annotations.*; +import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; + +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Response; + +@SwaggerDefinition( + info = @Info( + version = "0.9.0", + title = "", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "DeviceAnalyticsArtifactUploaderAdminService"), + @ExtensionProperty(name = "context", value = "/api/device-mgt/v0.9/admin/publish-artifact"), + }) + } + ), + tags = { + @Tag(name = "device_management", description = "") + } +) +@Path("/admin/publish-artifact") +@Api(value = "Devicetype deployment Administrative Service", description = "This an API intended to be used to " + + "deploy device type components" + + "Further, this is strictly restricted to admin users only ") +@Scopes( + scopes = { + @Scope( + name = "Devicetype deployment", + description = "Deploy devicetype", + key = "perm:devicetype:deployment", + permissions = {"/device-mgt/devicetype/deploy"} + ) + } +) + +public interface DeviceAnalyticsArtifactUploaderAdminService { + + @POST + @Path("/deploy/{type}") + @ApiOperation( + httpMethod = "POST", + value = "Deploy device type\n", + notes = "This is an API that can be used to deploy existing device type artifact for tenant", + response = Response.class, + tags = "Devicetype Deployment Service", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devicetype:deployment") + }) + }) + + @ApiResponses(value = { + @ApiResponse( + code = 201, + message = "OK. \n Successfully deployed the artifacts.", + response = Response.class), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n The specified resource does not exist."), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The entity of the request was in a not supported format."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while checking the authorization" + + " for a specified set of devices.", + response = ErrorResponse.class) + }) + + Response doPublish( + @ApiParam(name = "type", + value = "The type of deployment." + + "INFO: Deploy artifact with given type.", + required = true) + @PathParam("type") String type); + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceManagementAdminService.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceManagementAdminService.java new file mode 100644 index 0000000000..5048ec775e --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceManagementAdminService.java @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.api.admin; + +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Info; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.Extension; +import io.swagger.annotations.Tag; +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.ResponseHeader; +import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; + +import javax.validation.constraints.Size; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +@SwaggerDefinition( + info = @Info( + version = "0.9.0", + title = "", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "DeviceManagementAdmin"), + @ExtensionProperty(name = "context", value = "/api/device-mgt/v0.9/admin/devices"), + }) + } + ), + tags = { + @Tag(name = "device_management", description = "") + } +) +@Path("/admin/devices") +@Api(value = "Device Management Administrative Service", description = "This an API intended to be used by " + + "'internal' components to log in as an admin user and do a selected number of operations. " + + "Further, this is strictly restricted to admin users only ") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@Scopes( + scopes = { + @Scope( + name = "Getting Details of a Device", + description = "Getting Details of a Device", + key = "perm:admin:devices:view", + permissions = {"/device-mgt/devices/owning-device/view"} + ) + } +) +public interface DeviceManagementAdminService { + + @GET + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting Details of a Device", + notes = "Get the details of a device by searching via the device name, device type and the tenant domain.", + response = Device.class, + responseContainer = "List", + tags = "Device Management Administrative Service", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:admin:devices:view") + }) + } + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. \n Successfully fetched the list of devices.", + response = Device.class, + responseContainer = "List", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest version of the " + + "requested resource.\n"), + @ApiResponse( + code = 401, + message = "Unauthorized.\n The unauthorized access to the requested resource.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found.\n The specified device does not exist", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the device list.", + response = ErrorResponse.class) + }) + Response getDevicesByName( + @ApiParam( + name = "name", + value = "The name of the device.If you are unsure of the name of the device, run the GET /devices" + + " API that is under Device Management.", + required = true) + @QueryParam("name") + @Size(max = 45) + String name, + @ApiParam( + name = "type", + value = "The device type name, such as ios, android, windows or fire-alarm.", + required = true) + @QueryParam("type") + @Size(min = 2, max = 45) + String type, + @ApiParam( + name = "tenant-domain", + value = "The name of the tenant.\n" + + "The default tenant domain of WSO2 EMM is carbon.super", + required = true, + defaultValue = "carbon.super") + @QueryParam("tenant-domain") String tenantDomain, + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time. \n" + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z. \n" + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") String ifModifiedSince, + @ApiParam( + name = "offset", + value = "The starting pagination index for the complete list of qualified items.", + required = false, + defaultValue = "0") + @QueryParam("offset") int offset, + @ApiParam( + name = "limit", + value = "Provide how many activity details you require from the starting pagination index/offset.", + required = false, + defaultValue = "5") + @QueryParam("limit") int limit); +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceTypeManagementAdminService.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceTypeManagementAdminService.java new file mode 100644 index 0000000000..dc271c037e --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceTypeManagementAdminService.java @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.api.admin; + +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.Extension; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.Info; +import io.swagger.annotations.ResponseHeader; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.core.dto.DeviceType; +import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceTypeList; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; + +import javax.validation.constraints.Size; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +@SwaggerDefinition( + info = @Info( + version = "0.9.0", + title = "", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "DeviceTypeManagementAdminService"), + @ExtensionProperty(name = "context", value = "/api/device-mgt/v0.9/admin/device-types"), + }) + } + ), + tags = { + @Tag(name = "device_management", description = "") + } +) +@Path("/admin/device-types") +@Api(value = "Device Type Management Administrative Service", description = "This an API intended to be used by " + + "'internal' components to log in as an admin user and do a selected number of operations. " + + "Further, this is strictly restricted to admin users only ") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@Scopes( + scopes = { + @Scope( + name = "Getting Details of a Device", + description = "Getting Details of a Device", + key = "perm:admin:device-type", + permissions = {"/device-mgt/admin/device-type"} + ) + } +) +public interface DeviceTypeManagementAdminService { + + @GET + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting the Supported Device Type with Meta Definition", + notes = "Get the list of device types supported by WSO2 IoT.", + tags = "Device Type Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:admin:device-type") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the list of supported device types.", + response = DeviceTypeList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = + "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + } + ), + @ApiResponse( + code = 304, + message = + "Not Modified. \n Empty body because the client already has the latest version " + + "of the requested resource.\n"), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the " + + "list of supported device types.", + response = ErrorResponse.class) + } + ) + Response getDeviceTypes(); + + @POST + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Add a Device Type", + notes = "Add the details of a device type.", + tags = "Device Type Management Administrative Service", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:admin:device-type") + }) + } + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. \n Successfully added the device type.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body") + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest version of the " + + "requested resource.\n"), + @ApiResponse( + code = 401, + message = "Unauthorized.\n The unauthorized access to the requested resource.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found.\n The specified device does not exist", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the device list.", + response = ErrorResponse.class) + }) + Response addDeviceType(@ApiParam( + name = "type", + value = "The device type such as ios, android, windows or fire-alarm.", + required = true)DeviceType deviceType); + + @PUT + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "PUT", + value = "Update Device Type", + notes = "Update the details of a device type.", + response = DeviceType.class, + tags = "Device Type Management Administrative Service", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:admin:device-type") + }) + } + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. \n Successfully updated the device type.", + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body") + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest version of the " + + "requested resource.\n"), + @ApiResponse( + code = 401, + message = "Unauthorized.\n The unauthorized access to the requested resource.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found.\n The specified device does not exist", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the device list.", + response = ErrorResponse.class) + }) + Response updateDeviceType(@ApiParam( + name = "type", + value = "The device type such as ios, android, windows or fire-alarm.", + required = true) DeviceType deviceType); + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/GroupManagementAdminService.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/GroupManagementAdminService.java new file mode 100644 index 0000000000..1a0e351cd5 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/GroupManagementAdminService.java @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ + +package org.wso2.carbon.device.mgt.jaxrs.service.api.admin; + +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Info; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.Extension; +import io.swagger.annotations.Tag; +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.ResponseHeader; +import org.apache.axis2.transport.http.HTTPConstants; +import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceGroupList; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; + +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +@SwaggerDefinition( + info = @Info( + version = "0.9.0", + title = "", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "GroupManagementAdmin"), + @ExtensionProperty(name = "context", value = "/api/device-mgt/v0.9/admin/groups"), + }) + } + ), + tags = { + @Tag(name = "device_management", description = "") + } +) +@Path("/admin/groups") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@Api(value = "Group Management Administrative Service", description = "This an API intended to be used by " + + "'internal' components to log in as an admin user and do a selected number of operations. " + + "Further, this is strictly restricted to admin users only ") +@Scopes( + scopes = { + @Scope( + name = "View groups", + description = "", + key = "perm:admin-groups:view", + permissions = {"/device-mgt/admin/groups/view"} + ), + @Scope( + name = "Count groups", + description = "", + key = "perm:admin-groups:count", + permissions = {"/device-mgt/admin/groups/view"} + ) + } +) +public interface GroupManagementAdminService { + + @GET + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HTTPConstants.HEADER_GET, + value = "Get the list of groups.", + notes = "Returns all groups enrolled with the system.", + tags = "Device Group Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:admin-groups:view") + }) + } + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. \n Successfully fetched the list of device groups.", + response = DeviceGroupList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client has already the latest version of " + + "the requested resource."), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the groups list.", + response = ErrorResponse.class) + }) + Response getGroups(@ApiParam( + name = "name", + value = "Name of the group.") + @QueryParam("name") + String name, + @ApiParam( + name = "owner", + value = "Owner of the group.") + @QueryParam("owner") + String owner, + @ApiParam( + name = "offset", + value = "The starting pagination index for the complete list of qualified items.", + defaultValue = "0") + @QueryParam("offset") + int offset, + @ApiParam( + name = "limit", + value = "Provide how many device details you require from the starting pagination index/offset.", + defaultValue = "5") + @QueryParam("limit") + int limit); + + @Path("/count") + @GET + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HTTPConstants.HEADER_GET, + value = "Get the count of groups belongs to current user.", + notes = "Returns count of all permitted groups enrolled with the system.", + tags = "Device Group Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:admin-groups:count") + }) + } + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. \n Successfully fetched the device group count.", + response = DeviceGroupList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. \n Empty body because the client has already the latest version of " + + "the requested resource."), + @ApiResponse( + code = 404, + message = "No groups found.", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the group count.", + response = ErrorResponse.class) + }) + Response getGroupCount(); + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/UserManagementAdminService.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/UserManagementAdminService.java new file mode 100644 index 0000000000..9685dba009 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/UserManagementAdminService.java @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.api.admin; + +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Info; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.Extension; +import io.swagger.annotations.Tag; +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 org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.beans.PasswordResetWrapper; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; + +import javax.validation.constraints.Size; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +@SwaggerDefinition( + info = @Info( + version = "0.9.0", + title = "", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "UserManagementAdmin"), + @ExtensionProperty(name = "context", value = "/api/device-mgt/v0.9/admin/users"), + }) + } + ), + tags = { + @Tag(name = "device_management", description = "") + } +) +@Scopes( + scopes = { + @Scope( + name = "View Users", + description = "View Users", + key = "perm:admin-users:view", + permissions = {"/device-mgt/users/manage"} + ) + } +) +@Path("/admin/users") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@Api(value = "User Management Administrative Service", description = "This an API intended to be used by " + + "'internal' components to log in as an admin user and do a selected number of operations. " + + "Further, this is strictly restricted to admin users only ") +public interface UserManagementAdminService { + + @POST + @Path("/{username}/credentials") + @ApiOperation( + consumes = MediaType.APPLICATION_JSON, + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Changing the User Password.", + notes = "The EMM administrator is able to change the password of the users in " + + "the system and block them from logging into their EMM profile using this REST API.", + tags = "User Management Administrative Service", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:admin-users:view") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully updated the credentials of the user."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n The resource to be deleted does not exist."), + @ApiResponse( + code = 415, + message = "Unsupported media type. \n The format of the requested entity was not supported."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while updating credentials of the user.", + response = ErrorResponse.class) + }) + Response resetUserPassword( + @ApiParam( + name = "username", + value = "The username of the user." + + "INFO: Add a new user using the POST /users API that is under User Management.", + required = true) + @PathParam("username") + @Size(max = 45) + String username, + @ApiParam( + name = "domain", + value = "The domain name of the user store.", + required = false) + @QueryParam("domain") String domain, + @ApiParam( + name = "credentials", + value = "Credential.", + required = true) PasswordResetWrapper credentials); + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/ActivityProviderServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/ActivityProviderServiceImpl.java new file mode 100644 index 0000000000..a6751024e0 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/ActivityProviderServiceImpl.java @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; +import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.device.mgt.jaxrs.beans.ActivityList; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.service.api.ActivityInfoProviderService; +import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; +import org.wso2.carbon.user.api.UserStoreException; + +import javax.validation.constraints.Size; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +@Path("/activities") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class ActivityProviderServiceImpl implements ActivityInfoProviderService { + + private static final Log log = LogFactory.getLog(ActivityProviderServiceImpl.class); + + @GET + @Override + @Path("/{id}") + public Response getActivity(@PathParam("id") + @Size(max = 45) String id, + @HeaderParam("If-Modified-Since") String ifModifiedSince) { + Activity activity; + DeviceManagementProviderService dmService; + Response response = validateAdminUser(); + if (response == null) { + try { + RequestValidationUtil.validateActivityId(id); + + dmService = DeviceMgtAPIUtils.getDeviceManagementService(); + activity = dmService.getOperationByActivityId(id); + if (activity == null) { + return Response.status(404).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage("No activity can be " + + "found upon the provided activity id '" + id + "'").build()).build(); + } + return Response.status(Response.Status.OK).entity(activity).build(); + } catch (OperationManagementException e) { + String msg = "ErrorResponse occurred while fetching the activity for the supplied id."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } else { + return response; + } + } + + + @GET + @Override + @Path("/{id}/{devicetype}/{deviceid}") + public Response getActivityByDevice(@PathParam("id") + @Size(max = 45) String id, + @PathParam("devicetype") + @Size(max = 45) String devicetype, + @PathParam("deviceid") + @Size(max = 45) String deviceid, + @HeaderParam("If-Modified-Since") String ifModifiedSince) { + Activity activity; + DeviceManagementProviderService dmService; + try { + RequestValidationUtil.validateActivityId(id); + + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); + deviceIdentifier.setId(deviceid); + deviceIdentifier.setType(devicetype); + + dmService = DeviceMgtAPIUtils.getDeviceManagementService(); + activity = dmService.getOperationByActivityIdAndDevice(id, deviceIdentifier); + if (activity == null) { + return Response.status(404).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage("No activity can be " + + "found upon the provided activity id '" + id + "'").build()).build(); + } + return Response.status(Response.Status.OK).entity(activity).build(); + } catch (OperationManagementException e) { + String msg = "ErrorResponse occurred while fetching the activity for the supplied id."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + + @GET + @Override + public Response getActivities(@QueryParam("since") String since, @QueryParam("offset") int offset, + @QueryParam("limit") int limit, + @HeaderParam("If-Modified-Since") String ifModifiedSince) { + + long ifModifiedSinceTimestamp; + long sinceTimestamp; + long timestamp = 0; + boolean isIfModifiedSinceSet = false; + if (log.isDebugEnabled()) { + log.debug("getActivities since: " + since + " , offset: " + offset + " ,limit: " + limit + " ," + + "ifModifiedSince: " + ifModifiedSince); + } + RequestValidationUtil.validatePaginationParameters(offset, limit); + if (ifModifiedSince != null && !ifModifiedSince.isEmpty()) { + Date ifSinceDate; + SimpleDateFormat format = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z"); + try { + ifSinceDate = format.parse(ifModifiedSince); + } catch (ParseException e) { + return Response.status(400).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage( + "Invalid date string is provided in 'If-Modified-Since' header").build()).build(); + } + ifModifiedSinceTimestamp = ifSinceDate.getTime(); + isIfModifiedSinceSet = true; + timestamp = ifModifiedSinceTimestamp / 1000; + } else if (since != null && !since.isEmpty()) { + Date sinceDate; + SimpleDateFormat format = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z"); + try { + sinceDate = format.parse(since); + } catch (ParseException e) { + return Response.status(400).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage( + "Invalid date string is provided in 'since' filter").build()).build(); + } + sinceTimestamp = sinceDate.getTime(); + timestamp = sinceTimestamp / 1000; + } + + if (timestamp == 0) { + //If timestamp is not sent by the user, a default value is set, that is equal to current time-12 hours. + long time = System.currentTimeMillis() / 1000; + timestamp = time - 42300; + } + if (log.isDebugEnabled()) { + log.debug("getActivities final timestamp " + timestamp); + } + Response response = validateAdminUser(); + if (response == null) { + List activities; + ActivityList activityList = new ActivityList(); + DeviceManagementProviderService dmService; + try { + if (log.isDebugEnabled()) { + log.debug("Calling database to get activities."); + } + dmService = DeviceMgtAPIUtils.getDeviceManagementService(); + activities = dmService.getActivitiesUpdatedAfter(timestamp, limit, offset); + activityList.setList(activities); + if (log.isDebugEnabled()) { + log.debug("Calling database to get activity count."); + } + int count = dmService.getActivityCountUpdatedAfter(timestamp); + if (log.isDebugEnabled()) { + log.debug("Activity count: " + count); + } + activityList.setCount(count); + if (activities == null || activities.size() == 0) { + if (isIfModifiedSinceSet) { + return Response.notModified().build(); + } + } + return Response.ok().entity(activityList).build(); + } catch (OperationManagementException e) { + String msg + = "ErrorResponse occurred while fetching the activities updated after given time stamp."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } else { + return response; + } + } + + private Response validateAdminUser(){ + try { + if (!DeviceMgtAPIUtils.isAdmin()) { + return Response.status(Response.Status.UNAUTHORIZED).entity("Unauthorized operation! Only admin role can perform " + + "this operation.").build(); + } + return null; + } catch (UserStoreException e) { + String msg + = "Error occurred while validating the user have admin role!"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/ConfigurationServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/ConfigurationServiceImpl.java new file mode 100644 index 0000000000..064984f19d --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/ConfigurationServiceImpl.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry; +import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException; +import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.service.api.ConfigurationManagementService; +import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; +import org.wso2.carbon.device.mgt.jaxrs.util.MDMAppConstants; +import org.wso2.carbon.policy.mgt.common.PolicyManagementException; +import org.wso2.carbon.policy.mgt.core.util.PolicyManagerUtil; + +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.core.Response; +import java.util.ArrayList; +import java.util.List; + +@Path("/configuration") +public class ConfigurationServiceImpl implements ConfigurationManagementService { + + private static final Log log = LogFactory.getLog(ConfigurationServiceImpl.class); + + @GET + @Override + public Response getConfiguration(@HeaderParam("If-Modified-Since") String ifModifiedSince) { + String msg; + try { + PlatformConfiguration config = DeviceMgtAPIUtils.getPlatformConfigurationManagementService(). + getConfiguration(MDMAppConstants.RegistryConstants.GENERAL_CONFIG_RESOURCE_PATH); + ConfigurationEntry configurationEntry = new ConfigurationEntry(); + configurationEntry.setContentType("text"); + configurationEntry.setName("notifierFrequency"); + configurationEntry.setValue(PolicyManagerUtil.getMonitoringFrequency()); + List configList = config.getConfiguration(); + if (configList == null) { + configList = new ArrayList<>(); + configList.add(configurationEntry); + } + config.setConfiguration(configList); + return Response.ok().entity(config).build(); + } catch (ConfigurationManagementException | PolicyManagementException e) { + msg = "Error occurred while retrieving the general platform configuration"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + @PUT + @Override + public Response updateConfiguration(PlatformConfiguration config) { + try { + RequestValidationUtil.validateUpdateConfiguration(config); + DeviceMgtAPIUtils.getPlatformConfigurationManagementService().saveConfiguration(config, + MDMAppConstants.RegistryConstants.GENERAL_CONFIG_RESOURCE_PATH); + //Schedule the task service + DeviceMgtAPIUtils.scheduleTaskService(DeviceMgtAPIUtils.getNotifierFrequency(config)); + + PlatformConfiguration updatedConfig = DeviceMgtAPIUtils.getPlatformConfigurationManagementService(). + getConfiguration(MDMAppConstants.RegistryConstants.GENERAL_CONFIG_RESOURCE_PATH); + return Response.ok().entity(updatedConfig).build(); + } catch (ConfigurationManagementException e) { + String msg = "Error occurred while updating the general platform configuration"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceImpl.java new file mode 100644 index 0000000000..e7417363cc --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceImpl.java @@ -0,0 +1,604 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.impl; + +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import org.apache.axis2.AxisFault; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.EnrolmentInfo; +import org.wso2.carbon.device.mgt.common.InvalidConfigurationException; +import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException; +import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService; +import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; +import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException; +import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.ComplianceFeature; +import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.PolicyComplianceException; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.device.mgt.jaxrs.beans.OperationList; +import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.Attribute; +import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.AttributeType; +import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.EventAttributeList; +import org.wso2.carbon.device.mgt.jaxrs.service.api.DeviceAgentService; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; +import org.wso2.carbon.event.stream.stub.EventStreamAdminServiceStub; +import org.wso2.carbon.event.stream.stub.types.EventStreamAttributeDto; +import org.wso2.carbon.event.stream.stub.types.EventStreamDefinitionDto; +import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; +import org.wso2.carbon.user.api.UserStoreException; + +import javax.validation.Valid; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Response; +import java.rmi.RemoteException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +@Path("/device/agent") +public class DeviceAgentServiceImpl implements DeviceAgentService { + private static final Log log = LogFactory.getLog(DeviceAgentServiceImpl.class); + private static final String POLICY_MONITOR = "POLICY_MONITOR"; + @POST + @Path("/enroll") + @Override + public Response enrollDevice(@Valid Device device) { + if (device == null) { + String errorMessage = "The payload of the device enrollment is incorrect."; + return Response.status(Response.Status.BAD_REQUEST).entity(errorMessage).build(); + } + try { + DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService(); + if (device.getType() == null || device.getDeviceIdentifier() == null) { + String errorMessage = "The payload of the device enrollment is incorrect."; + return Response.status(Response.Status.BAD_REQUEST).entity(errorMessage).build(); + } + Device existingDevice = dms.getDevice(new DeviceIdentifier(device.getDeviceIdentifier(), device.getType())); + if (existingDevice != null && existingDevice.getEnrolmentInfo() != null && existingDevice + .getEnrolmentInfo().getStatus().equals(EnrolmentInfo.Status.ACTIVE)) { + String errorMessage = "An active enrolment exists"; + return Response.status(Response.Status.BAD_REQUEST).entity(errorMessage).build(); + } + device.getEnrolmentInfo().setOwner(DeviceMgtAPIUtils.getAuthenticatedUser()); + device.getEnrolmentInfo().setDateOfEnrolment(System.currentTimeMillis()); + device.getEnrolmentInfo().setDateOfLastUpdate(System.currentTimeMillis()); + boolean status = dms.enrollDevice(device); + return Response.status(Response.Status.OK).entity(status).build(); + } catch (DeviceManagementException e) { + String msg = "Error occurred while enrolling the device, which carries the id '" + + device.getDeviceIdentifier() + "'"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (InvalidConfigurationException e) { + log.error("failed to add operation", e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } + } + + @DELETE + @Path("/enroll/{type}/{id}") + @Override + public Response disEnrollDevice(@PathParam("type") String type, @PathParam("id") String id) { + boolean result; + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(id, type); + try { + result = DeviceMgtAPIUtils.getDeviceManagementService().disenrollDevice(deviceIdentifier); + if (result) { + return Response.status(Response.Status.OK).build(); + } else { + return Response.status(Response.Status.NO_CONTENT).entity(type + " device that carries id '" + id + + "' has not been dis-enrolled").build(); + } + } catch (DeviceManagementException e) { + String msg = "Error occurred while enrolling the device, which carries the id '" + id + "'"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @PUT + @Path("/enroll/{type}/{id}") + @Override + public Response updateDevice(@PathParam("type") String type, @PathParam("id") String id, @Valid Device updateDevice) { + Device device; + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); + deviceIdentifier.setId(id); + deviceIdentifier.setType(type); + try { + device = DeviceMgtAPIUtils.getDeviceManagementService().getDevice(deviceIdentifier); + } catch (DeviceManagementException e) { + String msg = "Error occurred while getting enrollment details of the device that carries the id '" + + id + "'"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + + if (updateDevice == null) { + String errorMessage = "The payload of the device enrollment is incorrect."; + log.error(errorMessage); + return Response.status(Response.Status.BAD_REQUEST).entity(errorMessage).build(); + } + if (device == null) { + String errorMessage = "The device to be modified doesn't exist."; + log.error(errorMessage); + return Response.status(Response.Status.NOT_FOUND).entity(errorMessage).build(); + } + if (device.getEnrolmentInfo().getStatus() == EnrolmentInfo.Status.ACTIVE ) { + DeviceAccessAuthorizationService deviceAccessAuthorizationService = + DeviceMgtAPIUtils.getDeviceAccessAuthorizationService(); + boolean status; + try { + status = deviceAccessAuthorizationService.isUserAuthorized(new DeviceIdentifier(id, type)); + } catch (DeviceAccessAuthorizationException e) { + String msg = "Error occurred while modifying enrollment of the Android device that carries the id '" + + id + "'"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + if (!status) { + return Response.status(Response.Status.UNAUTHORIZED).build(); + } + } + if(updateDevice.getEnrolmentInfo() != null) { + device.getEnrolmentInfo().setDateOfLastUpdate(System.currentTimeMillis()); + device.setEnrolmentInfo(device.getEnrolmentInfo()); + } + device.getEnrolmentInfo().setOwner(DeviceMgtAPIUtils.getAuthenticatedUser()); + if(updateDevice.getDeviceInfo() != null) { + device.setDeviceInfo(updateDevice.getDeviceInfo()); + } + device.setDeviceIdentifier(id); + if(updateDevice.getDescription() != null) { + device.setDescription(updateDevice.getDescription()); + } + if(updateDevice.getName() != null) { + device.setName(updateDevice.getName()); + } + if(updateDevice.getFeatures() != null) { + device.setFeatures(updateDevice.getFeatures()); + } + if(updateDevice.getProperties() != null) { + device.setProperties(updateDevice.getProperties()); + } + boolean result; + try { + device.setType(type); + result = DeviceMgtAPIUtils.getDeviceManagementService().modifyEnrollment(device); + if (result) { + return Response.status(Response.Status.ACCEPTED).build(); + } else { + return Response.status(Response.Status.NOT_MODIFIED).build(); + } + } catch (DeviceManagementException e) { + String msg = "Error occurred while modifying enrollment of the Android device that carries the id '" + + id + "'"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @POST + @Path("/events/publish/{type}/{deviceId}") + @Override + public Response publishEvents(@Valid Map payload, @PathParam("type") String type + , @PathParam("deviceId") String deviceId) { + + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + EventStreamAdminServiceStub eventStreamAdminServiceStub = null; + try { + if (payload == null) { + String msg = "invalid payload structure"; + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } else { + boolean authorized = DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized + (new DeviceIdentifier(type, deviceId)); + if (!authorized) { + String msg = "Does not have permission to access the device."; + return Response.status(Response.Status.UNAUTHORIZED).entity(msg).build(); + } + } + Object metaData[] = new Object[1]; + metaData[0] = deviceId; + EventAttributeList eventAttributeList = DeviceMgtAPIUtils.getDynamicEventCache().get(type); + if (eventAttributeList == null) { + String streamName = DeviceMgtAPIUtils.getStreamDefinition(type, tenantDomain); + eventStreamAdminServiceStub = DeviceMgtAPIUtils.getEventStreamAdminServiceStub(); + EventStreamDefinitionDto eventStreamDefinitionDto = eventStreamAdminServiceStub.getStreamDefinitionDto( + streamName + ":" + Constants.DEFAULT_STREAM_VERSION); + if (eventStreamDefinitionDto == null) { + return Response.status(Response.Status.BAD_REQUEST).build(); + } else { + EventStreamAttributeDto[] eventStreamAttributeDtos = eventStreamDefinitionDto.getPayloadData(); + List attributes = new ArrayList<>(); + for (EventStreamAttributeDto eventStreamAttributeDto : eventStreamAttributeDtos) { + attributes.add(new Attribute(eventStreamAttributeDto.getAttributeName() + , AttributeType.valueOf(eventStreamAttributeDto.getAttributeType().toUpperCase()))); + + } + if (payload.size() != attributes.size()) { + String msg = "Payload does not match with the stream definition"; + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } + eventAttributeList = new EventAttributeList(); + eventAttributeList.setList(attributes); + DeviceMgtAPIUtils.getDynamicEventCache().put(type, eventAttributeList); + } + } + int i = 0; + Object[] payloadData = new Object[eventAttributeList.getList().size()]; + for (Attribute attribute : eventAttributeList.getList()) { + if (attribute.getType() == AttributeType.INT) { + payloadData[i] = ((Double) payload.get(attribute.getName())).intValue(); + } else if (attribute.getType() == AttributeType.LONG) { + payloadData[i] = ((Double) payload.get(attribute.getName())).longValue(); + } else { + payloadData[i] = payload.get(attribute.getName()); + } + i++; + } + + if (DeviceMgtAPIUtils.getEventPublisherService().publishEvent(DeviceMgtAPIUtils.getStreamDefinition(type + , PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain()) + , Constants.DEFAULT_STREAM_VERSION, metaData + , null, payloadData)) { + return Response.status(Response.Status.OK).build(); + } else { + String msg = "Error occurred while publishing the event."; + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } catch (DataPublisherConfigurationException e) { + String msg = "Error occurred while publishing the event."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (DeviceAccessAuthorizationException e) { + String msg = "Error occurred when checking for authorization"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (AxisFault e) { + log.error("Failed to retrieve event definitions for tenantDomain:" + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (RemoteException e) { + log.error("Failed to connect with the remote services:" + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (JWTClientException e) { + log.error("Failed to generate jwt token for tenantDomain:" + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (UserStoreException e) { + log.error("Failed to connect with the user store, tenantDomain: " + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } finally { + if (eventStreamAdminServiceStub != null) { + try { + eventStreamAdminServiceStub.cleanup(); + } catch (AxisFault axisFault) { + log.warn("Failed to clean eventStreamAdminServiceStub"); + } + } + } + } + + @POST + @Path("/events/publish/data/{type}/{deviceId}") + @Override + public Response publishEvents(@Valid List payload, @PathParam("type") String type + , @PathParam("deviceId") String deviceId) { + + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + EventStreamAdminServiceStub eventStreamAdminServiceStub = null; + try { + if (payload == null) { + String msg = "Invalid payload structure"; + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } else { + boolean authorized = DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized + (new DeviceIdentifier(type, deviceId)); + if (!authorized) { + String msg = "Does not have permission to access the device."; + return Response.status(Response.Status.UNAUTHORIZED).entity(msg).build(); + } + } + Object metaData[] = new Object[1]; + metaData[0] = deviceId; + EventAttributeList eventAttributeList = DeviceMgtAPIUtils.getDynamicEventCache().get(type); + if (eventAttributeList == null) { + String streamName = DeviceMgtAPIUtils.getStreamDefinition(type, tenantDomain); + eventStreamAdminServiceStub = DeviceMgtAPIUtils.getEventStreamAdminServiceStub(); + EventStreamDefinitionDto eventStreamDefinitionDto = eventStreamAdminServiceStub.getStreamDefinitionDto( + streamName + ":" + Constants.DEFAULT_STREAM_VERSION); + if (eventStreamDefinitionDto == null) { + return Response.status(Response.Status.BAD_REQUEST).build(); + } else { + EventStreamAttributeDto[] eventStreamAttributeDtos = eventStreamDefinitionDto.getPayloadData(); + List attributes = new ArrayList<>(); + for (EventStreamAttributeDto eventStreamAttributeDto : eventStreamAttributeDtos) { + attributes.add(new Attribute(eventStreamAttributeDto.getAttributeName() + , AttributeType.valueOf(eventStreamAttributeDto.getAttributeType().toUpperCase()))); + + } + if (payload.size() != attributes.size()) { + String msg = "Payload does not match with the stream definition"; + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } + eventAttributeList = new EventAttributeList(); + eventAttributeList.setList(attributes); + DeviceMgtAPIUtils.getDynamicEventCache().put(type, eventAttributeList); + } + } + int i = 0; + Object[] payloadData = new Object[eventAttributeList.getList().size()]; + for (Attribute attribute : eventAttributeList.getList()) { + if (attribute.getType() == AttributeType.INT) { + payloadData[i] = ((Double) payload.get(i)).intValue(); + } else if (attribute.getType() == AttributeType.LONG) { + payloadData[i] = ((Double) payload.get(i)).longValue(); + } else { + payloadData[i] = payload.get(i); + } + i++; + } + + if (DeviceMgtAPIUtils.getEventPublisherService().publishEvent(DeviceMgtAPIUtils.getStreamDefinition(type + , PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain()) + , Constants.DEFAULT_STREAM_VERSION, metaData + , null, payloadData)) { + return Response.status(Response.Status.OK).build(); + } else { + String msg = "Error occurred while publishing the event."; + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } catch (DataPublisherConfigurationException e) { + String msg = "Error occurred while publishing the event."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (DeviceAccessAuthorizationException e) { + String msg = "Error occurred when checking for authorization"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (AxisFault e) { + log.error("Failed to retrieve event definitions for tenantDomain:" + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (RemoteException e) { + log.error("Failed to connect with the remote services:" + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (JWTClientException e) { + log.error("Failed to generate jwt token for tenantDomain:" + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (UserStoreException e) { + log.error("Failed to connect with the user store, tenantDomain: " + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } finally { + if (eventStreamAdminServiceStub != null) { + try { + eventStreamAdminServiceStub.cleanup(); + } catch (AxisFault axisFault) { + log.warn("Failed to clean eventStreamAdminServiceStub"); + } + } + } + } + + @GET + @Path("/pending/operations/{type}/{id}") + public Response getPendingOperations(@PathParam("type") String type, @PathParam("id") String deviceId) { + try { + if (!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) { + String errorMessage = "Device identifier list is empty"; + log.error(errorMessage); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(deviceId, type); + if (!DeviceMgtAPIUtils.isValidDeviceIdentifier(deviceIdentifier)) { + String msg = "Device not found for identifier '" + deviceId + "'"; + log.error(msg); + return Response.status(Response.Status.NO_CONTENT).entity(msg).build(); + } + List operations = DeviceMgtAPIUtils.getDeviceManagementService().getPendingOperations( + deviceIdentifier); + OperationList operationsList = new OperationList(); + operationsList.setList(operations); + operationsList.setCount(operations.size()); + return Response.status(Response.Status.OK).entity(operationsList).build(); + } catch (OperationManagementException e) { + String errorMessage = "Issue in retrieving operation management service instance"; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build(); + } catch (DeviceManagementException e) { + String errorMessage = "Issue in retrieving deivce management service instance"; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build(); + } + } + + @GET + @Path("/next-pending/operation/{type}/{id}") + public Response getNextPendingOperation(@PathParam("type") String type, @PathParam("id") String deviceId) { + try { + if (!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) { + String errorMessage = "Device type is invalid"; + log.error(errorMessage); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(deviceId, type); + if (!DeviceMgtAPIUtils.isValidDeviceIdentifier(deviceIdentifier)) { + String msg = "Device not found for identifier '" + deviceId + "'"; + log.error(msg); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } + Operation operation = DeviceMgtAPIUtils.getDeviceManagementService().getNextPendingOperation( + deviceIdentifier); + return Response.status(Response.Status.OK).entity(operation).build(); + } catch (OperationManagementException e) { + String errorMessage = "Issue in retrieving operation management service instance"; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build(); + } catch (DeviceManagementException e) { + String errorMessage = "Issue in retrieving deivce management service instance"; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build(); + } + } + + @PUT + @Path("/operations/{type}/{id}") + public Response updateOperation(@PathParam("type") String type, @PathParam("id") String deviceId, @Valid Operation operation) { + try { + if (!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) { + String errorMessage = "Device type is invalid"; + log.error(errorMessage); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + if (operation == null) { + String errorMessage = "Operation cannot empty"; + log.error(errorMessage); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(deviceId, type); + if (!DeviceMgtAPIUtils.isValidDeviceIdentifier(deviceIdentifier)) { + String msg = "Device not found for identifier '" + deviceId + "'"; + log.error(msg); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } + if (!Operation.Status.ERROR.equals(operation.getStatus()) && operation.getCode() != null && + POLICY_MONITOR.equals(operation.getCode())) { + if (log.isDebugEnabled()) { + log.info("Received compliance status from POLICY_MONITOR operation ID: " + operation.getId()); + } + List features = getComplianceFeatures(operation.getPayLoad()); + DeviceMgtAPIUtils.getPolicyManagementService().checkCompliance(deviceIdentifier, features); + + } else { + DeviceMgtAPIUtils.getDeviceManagementService().updateOperation(deviceIdentifier, operation); + } + return Response.status(Response.Status.OK).build(); + } catch (OperationManagementException e) { + String errorMessage = "Issue in retrieving operation management service instance"; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build(); + } catch (DeviceManagementException e) { + String errorMessage = "Issue in retrieving deivce management service instance"; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build(); + } catch (PolicyComplianceException e) { + String errorMessage = "Issue in retrieving deivce management service instance"; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build(); + } + } + + @Override + @PUT + @Path("/operations/{type}/{id}") + public Response updateDeviceProperties(@PathParam("type") String type, @PathParam("id") String deviceId, + @Valid List properties) { + try { + if (!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) { + String errorMessage = "Device type is invalid"; + log.error(errorMessage); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + if(properties == null) { + String errorMessage = "Properties cannot be empty"; + log.error(errorMessage); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(deviceId, type); + if (!DeviceMgtAPIUtils.isValidDeviceIdentifier(deviceIdentifier)) { + String msg = "Device not found for identifier '" + deviceId + "'"; + log.error(msg); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } + + DeviceMgtAPIUtils.getDeviceManagementService().updateProperties(deviceIdentifier, properties); + } catch (DeviceManagementException e) { + String errorMessage = "Issue in retrieving device management service instance"; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build(); + } + return null; + } + + @GET + @Path("/status/operations/{type}/{id}") + public Response getOperationsByDeviceAndStatus(@PathParam("type") String type, @PathParam("id") String deviceId, + @QueryParam("status") Operation.Status status) { + if (status == null) { + String errorMessage = "Status is empty"; + log.error(errorMessage); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + + try { + if (!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) { + String errorMessage = "Invalid Device Type"; + log.error(errorMessage); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + List operations = DeviceMgtAPIUtils.getDeviceManagementService() + .getOperationsByDeviceAndStatus(new DeviceIdentifier(deviceId, type), status); + OperationList operationsList = new OperationList(); + operationsList.setList(operations); + operationsList.setCount(operations.size()); + return Response.status(Response.Status.OK).entity(operationsList).build(); + } catch (OperationManagementException e) { + String errorMessage = "Issue in retrieving operation management service instance"; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build(); + } catch (DeviceManagementException e) { + String errorMessage = "Issue in retrieving device management service"; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage).build(); + } + } + + private static List getComplianceFeatures(Object compliancePayload) throws + PolicyComplianceException { + String compliancePayloadString = new Gson().toJson(compliancePayload); + if (compliancePayload == null) { + return null; + } + // Parsing json string to get compliance features. + JsonElement jsonElement = new JsonParser().parse(compliancePayloadString); + + JsonArray jsonArray = jsonElement.getAsJsonArray(); + Gson gson = new Gson(); + ComplianceFeature complianceFeature; + List complianceFeatures = new ArrayList(jsonArray.size()); + + for (JsonElement element : jsonArray) { + complianceFeature = gson.fromJson(element, ComplianceFeature.class); + complianceFeatures.add(complianceFeature); + } + return complianceFeatures; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceEventManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceEventManagementServiceImpl.java new file mode 100644 index 0000000000..5a16fbccdb --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceEventManagementServiceImpl.java @@ -0,0 +1,590 @@ +package org.wso2.carbon.device.mgt.jaxrs.service.impl; + +import org.apache.axis2.AxisFault; +import org.apache.axis2.client.Stub; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.analytics.api.AnalyticsDataAPI; +import org.wso2.carbon.analytics.api.AnalyticsDataAPIUtil; +import org.wso2.carbon.analytics.dataservice.commons.AnalyticsDataResponse; +import org.wso2.carbon.analytics.dataservice.commons.SearchResultEntry; +import org.wso2.carbon.analytics.dataservice.commons.SortByField; +import org.wso2.carbon.analytics.dataservice.commons.SortType; +import org.wso2.carbon.analytics.stream.persistence.stub + .EventStreamPersistenceAdminServiceEventStreamPersistenceAdminServiceExceptionException; +import org.wso2.carbon.analytics.stream.persistence.stub.EventStreamPersistenceAdminServiceStub; +import org.wso2.carbon.analytics.stream.persistence.stub.dto.AnalyticsTable; +import org.wso2.carbon.analytics.stream.persistence.stub.dto.AnalyticsTableRecord; +import org.wso2.carbon.base.MultitenantConstants; +import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException; +import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.DeviceTypeEvent; +import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.EventRecords; +import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.Attribute; +import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.AttributeType; +import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.EventAttributeList; +import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.TransportType; +import org.wso2.carbon.device.mgt.jaxrs.service.api.DeviceEventManagementService; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; +import org.wso2.carbon.event.publisher.stub.EventPublisherAdminServiceCallbackHandler; +import org.wso2.carbon.event.publisher.stub.EventPublisherAdminServiceStub; +import org.wso2.carbon.event.receiver.stub.EventReceiverAdminServiceCallbackHandler; +import org.wso2.carbon.event.receiver.stub.EventReceiverAdminServiceStub; +import org.wso2.carbon.event.receiver.stub.types.BasicInputAdapterPropertyDto; +import org.wso2.carbon.event.receiver.stub.types.EventReceiverConfigurationDto; +import org.wso2.carbon.event.stream.stub.EventStreamAdminServiceStub; +import org.wso2.carbon.event.stream.stub.types.EventStreamAttributeDto; +import org.wso2.carbon.event.stream.stub.types.EventStreamDefinitionDto; +import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException; + +import javax.validation.Valid; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Response; +import java.rmi.RemoteException; +import java.util.ArrayList; +import java.util.List; + +/** + * This is used for device type integration with DAS, to create streams and receiver dynamically and a common endpoint + * to retrieve data. + */ +@Path("/events") +public class DeviceEventManagementServiceImpl implements DeviceEventManagementService { + + private static final Log log = LogFactory.getLog(DeviceEventManagementServiceImpl.class); + + private static final String DEFAULT_EVENT_STORE_NAME = "EVENT_STORE"; + private static final String DEFAULT_WEBSOCKET_PUBLISHER_ADAPTER_TYPE = "secured-websocket"; + private static final String OAUTH_MQTT_ADAPTER_TYPE = "oauth-mqtt"; + private static final String THRIFT_ADAPTER_TYPE = "iot-event"; + private static final String DEFAULT_DEVICE_ID_ATTRIBUTE = "deviceId"; + private static final String DEFAULT_META_DEVICE_ID_ATTRIBUTE = "meta_deviceId"; + private static final String MQTT_CONTENT_TRANSFORMER = "device-meta-transformer"; + private static final String MQTT_CONTENT_TRANSFORMER_TYPE = "contentTransformer"; + private static final String MQTT_CONTENT_VALIDATOR_TYPE = "contentValidator"; + private static final String MQTT_CONTENT_VALIDATOR = "default"; + private static final String TIMESTAMP_FIELD_NAME = "_timestamp"; + + /** + * Retrieves the stream definition from das for the given device type. + * @return dynamic event attribute list + */ + @GET + @Path("/{type}") + @Override + public Response getDeviceTypeEventDefinition(@PathParam("type") String deviceType) { + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + EventStreamAdminServiceStub eventStreamAdminServiceStub = null; + EventReceiverAdminServiceStub eventReceiverAdminServiceStub = null; + try { + if (deviceType == null || + !DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(deviceType)) { + String errorMessage = "Invalid device type"; + log.error(errorMessage); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + String streamName = DeviceMgtAPIUtils.getStreamDefinition(deviceType, tenantDomain); + eventStreamAdminServiceStub = DeviceMgtAPIUtils.getEventStreamAdminServiceStub(); + EventStreamDefinitionDto eventStreamDefinitionDto = eventStreamAdminServiceStub.getStreamDefinitionDto( + streamName + ":" + Constants.DEFAULT_STREAM_VERSION); + if (eventStreamDefinitionDto == null) { + return Response.status(Response.Status.NO_CONTENT).build(); + } + + EventStreamAttributeDto[] eventStreamAttributeDtos = eventStreamDefinitionDto.getPayloadData(); + EventAttributeList eventAttributeList = new EventAttributeList(); + List attributes = new ArrayList<>(); + for (EventStreamAttributeDto eventStreamAttributeDto : eventStreamAttributeDtos) { + attributes.add(new Attribute(eventStreamAttributeDto.getAttributeName() + , AttributeType.valueOf(eventStreamAttributeDto.getAttributeType().toUpperCase()))); + } + eventAttributeList.setList(attributes); + + DeviceTypeEvent deviceTypeEvent = new DeviceTypeEvent(); + deviceTypeEvent.setEventAttributeList(eventAttributeList); + deviceTypeEvent.setTransportType(TransportType.HTTP); + eventReceiverAdminServiceStub = DeviceMgtAPIUtils.getEventReceiverAdminServiceStub(); + EventReceiverConfigurationDto eventReceiverConfigurationDto = eventReceiverAdminServiceStub + .getActiveEventReceiverConfiguration(getReceiverName(deviceType, tenantDomain, TransportType.MQTT)); + if (eventReceiverConfigurationDto != null) { + deviceTypeEvent.setTransportType(TransportType.MQTT); + } + return Response.ok().entity(deviceTypeEvent).build(); + } catch (AxisFault e) { + log.error("Failed to retrieve event definitions for tenantDomain:" + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (RemoteException e) { + log.error("Failed to connect with the remote services:" + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (JWTClientException e) { + log.error("Failed to generate jwt token for tenantDomain:" + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (UserStoreException e) { + log.error("Failed to connect with the user store, tenantDomain: " + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (DeviceManagementException e) { + log.error("Failed to access device management service, tenantDomain: " + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } finally { + cleanup(eventStreamAdminServiceStub); + cleanup(eventReceiverAdminServiceStub); + } + } + + /** + * Deploy Event Stream, Receiver, Publisher and Store Configuration. + */ + @POST + @Path("/{type}") + @Override + public Response deployDeviceTypeEventDefinition(@PathParam("type") String deviceType, + @Valid DeviceTypeEvent deviceTypeEvent) { + TransportType transportType = deviceTypeEvent.getTransportType(); + EventAttributeList eventAttributes = deviceTypeEvent.getEventAttributeList(); + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + try { + if (eventAttributes == null || eventAttributes.getList() == null || eventAttributes.getList().size() == 0 || + deviceType == null || transportType == null || + !DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(deviceType)) { + String errorMessage = "Invalid Payload"; + log.error(errorMessage); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + String streamName = DeviceMgtAPIUtils.getStreamDefinition(deviceType, tenantDomain); + String streamNameWithVersion = streamName + ":" + Constants.DEFAULT_STREAM_VERSION; + publishStreamDefinitons(streamName, Constants.DEFAULT_STREAM_VERSION, deviceType, eventAttributes); + publishEventReceivers(streamNameWithVersion, transportType, tenantDomain, deviceType); + publishEventStore(streamName, Constants.DEFAULT_STREAM_VERSION, eventAttributes); + publishWebsocketPublisherDefinition(streamNameWithVersion, deviceType); + try { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain( + MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, true); + if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { + publishStreamDefinitons(streamName, Constants.DEFAULT_STREAM_VERSION, deviceType, eventAttributes); + publishEventReceivers(streamNameWithVersion, transportType, tenantDomain, deviceType); + } + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + return Response.ok().build(); + } catch (AxisFault e) { + log.error("Failed to create event definitions for tenantDomain:" + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (RemoteException e) { + log.error("Failed to connect with the remote services:" + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (JWTClientException e) { + log.error("Failed to generate jwt token for tenantDomain:" + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (UserStoreException e) { + log.error("Failed to connect with the user store, tenantDomain: " + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (DeviceManagementException e) { + log.error("Failed to access device management service, tenantDomain: " + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (EventStreamPersistenceAdminServiceEventStreamPersistenceAdminServiceExceptionException e) { + log.error("Failed to create event store for, tenantDomain: " + tenantDomain + " deviceType" + deviceType, + e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } + } + + /** + * Delete device type specific artifacts from DAS. + */ + @DELETE + @Path("/{type}") + @Override + public Response deleteDeviceTypeEventDefinitions(@PathParam("type") String deviceType) { + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + EventReceiverAdminServiceStub eventReceiverAdminServiceStub = null; + EventPublisherAdminServiceStub eventPublisherAdminServiceStub = null; + EventStreamAdminServiceStub eventStreamAdminServiceStub = null; + + EventReceiverAdminServiceStub tenantBasedEventReceiverAdminServiceStub = null; + EventStreamAdminServiceStub tenantBasedEventStreamAdminServiceStub = null; + try { + if (deviceType == null || + !DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(deviceType)) { + String errorMessage = "Invalid device type"; + return Response.status(Response.Status.BAD_REQUEST).entity(errorMessage).build(); + } + String eventPublisherName = deviceType.trim().replace(" ", "_") + "_websocket_publisher"; + String streamName = DeviceMgtAPIUtils.getStreamDefinition(deviceType, tenantDomain); + eventStreamAdminServiceStub = DeviceMgtAPIUtils.getEventStreamAdminServiceStub(); + if (eventStreamAdminServiceStub.getStreamDefinitionDto(streamName + ":" + Constants.DEFAULT_STREAM_VERSION) == null) { + return Response.status(Response.Status.NO_CONTENT).build(); + } + eventStreamAdminServiceStub.removeEventStreamDefinition(streamName, Constants.DEFAULT_STREAM_VERSION); + EventReceiverAdminServiceCallbackHandler eventReceiverAdminServiceCallbackHandler = + new EventReceiverAdminServiceCallbackHandler() {}; + EventPublisherAdminServiceCallbackHandler eventPublisherAdminServiceCallbackHandler = + new EventPublisherAdminServiceCallbackHandler() {}; + + + String eventReceiverName = getReceiverName(deviceType, tenantDomain, TransportType.MQTT); + eventReceiverAdminServiceStub = DeviceMgtAPIUtils.getEventReceiverAdminServiceStub(); + if (eventReceiverAdminServiceStub.getInactiveEventReceiverConfigurationContent(eventReceiverName) == null) { + eventReceiverName = getReceiverName(deviceType, tenantDomain, TransportType.HTTP); + } + eventReceiverAdminServiceStub.startundeployInactiveEventReceiverConfiguration(eventReceiverName + , eventReceiverAdminServiceCallbackHandler); + + eventPublisherAdminServiceStub = DeviceMgtAPIUtils.getEventPublisherAdminServiceStub(); + eventPublisherAdminServiceStub.startundeployInactiveEventPublisherConfiguration(eventPublisherName + , eventPublisherAdminServiceCallbackHandler); + + try { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain( + MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, true); + if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { + tenantBasedEventReceiverAdminServiceStub = DeviceMgtAPIUtils.getEventReceiverAdminServiceStub(); + tenantBasedEventStreamAdminServiceStub = DeviceMgtAPIUtils.getEventStreamAdminServiceStub(); + tenantBasedEventStreamAdminServiceStub.removeEventStreamDefinition(streamName, + Constants.DEFAULT_STREAM_VERSION); + + tenantBasedEventReceiverAdminServiceStub.startundeployInactiveEventReceiverConfiguration( + eventReceiverName, eventReceiverAdminServiceCallbackHandler); + + } + } finally { + cleanup(tenantBasedEventReceiverAdminServiceStub); + cleanup(tenantBasedEventStreamAdminServiceStub); + PrivilegedCarbonContext.endTenantFlow(); + } + return Response.ok().build(); + } catch (AxisFault e) { + log.error("Failed to delete event definitions for tenantDomain:" + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (RemoteException e) { + log.error("Failed to connect with the remote services:" + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (JWTClientException e) { + log.error("Failed to generate jwt token for tenantDomain:" + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (UserStoreException e) { + log.error("Failed to connect with the user store, tenantDomain: " + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (DeviceManagementException e) { + log.error("Failed to access device management service, tenantDomain: " + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } finally { + cleanup(eventStreamAdminServiceStub); + cleanup(eventPublisherAdminServiceStub); + cleanup(eventReceiverAdminServiceStub); + cleanup(eventReceiverAdminServiceStub); + cleanup(eventStreamAdminServiceStub); + } + } + + /** + * Returns device specific data for the give period of time. + */ + @GET + @Path("/{type}/{deviceId}") + @Override + public Response getData(@PathParam("deviceId") String deviceId, @QueryParam("from") long from, + @QueryParam("to") long to, @PathParam("type") String deviceType, @QueryParam("offset") + int offset, @QueryParam("limit") int limit) { + if (from == 0 || to == 0) { + String errorMessage = "Invalid values for from/to"; + return Response.status(Response.Status.BAD_REQUEST).entity(errorMessage).build(); + } + String fromDate = String.valueOf(from); + String toDate = String.valueOf(to); + String query = DEFAULT_META_DEVICE_ID_ATTRIBUTE + ":" + deviceId + + " AND _timestamp : [" + fromDate + " TO " + toDate + "]"; + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + String sensorTableName = getTableName(DeviceMgtAPIUtils.getStreamDefinition(deviceType, tenantDomain)); + try { + if (deviceType == null || + !DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(deviceType)) { + String errorMessage = "Invalid device type"; + log.error(errorMessage); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized( + new DeviceIdentifier(deviceId, deviceType))) { + return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); + } + List sortByFields = new ArrayList<>(); + SortByField sortByField = new SortByField(TIMESTAMP_FIELD_NAME, SortType.DESC); + sortByFields.add(sortByField); + EventRecords eventRecords = getAllEventsForDevice(sensorTableName, query, sortByFields, offset, limit); + return Response.status(Response.Status.OK.getStatusCode()).entity(eventRecords).build(); + } catch (AnalyticsException e) { + String errorMsg = "Error on retrieving stats on table " + sensorTableName + " with query " + query; + log.error(errorMsg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).entity(errorMsg).build(); + } catch (DeviceAccessAuthorizationException e) { + log.error(e.getErrorMessage(), e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (DeviceManagementException e) { + String errorMsg = "Error on retrieving stats on table " + sensorTableName + " with query " + query; + log.error(errorMsg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).entity(errorMsg).build(); + } + } + + /** + * Returns the last know data point of the device type. + */ + @GET + @Path("/last-known/{type}/{deviceId}") + @Override + public Response getLastKnownData(@PathParam("deviceId") String deviceId, @PathParam("type") String deviceType) { + String query = DEFAULT_META_DEVICE_ID_ATTRIBUTE + ":" + deviceId; + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + String sensorTableName = getTableName(DeviceMgtAPIUtils.getStreamDefinition(deviceType, tenantDomain)); + try { + if (deviceType == null || + !DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(deviceType)) { + String errorMessage = "Invalid device type"; + log.error(errorMessage); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized( + new DeviceIdentifier(deviceId, deviceType))) { + return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); + } + List sortByFields = new ArrayList<>(); + SortByField sortByField = new SortByField(TIMESTAMP_FIELD_NAME, SortType.DESC); + sortByFields.add(sortByField); + EventRecords eventRecords = getAllEventsForDevice(sensorTableName, query, sortByFields, 0, 1); + return Response.status(Response.Status.OK.getStatusCode()).entity(eventRecords).build(); + } catch (AnalyticsException e) { + String errorMsg = "Error on retrieving stats on table " + sensorTableName + " with query " + query; + log.error(errorMsg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).entity(errorMsg).build(); + } catch (DeviceAccessAuthorizationException e) { + log.error(e.getErrorMessage(), e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (DeviceManagementException e) { + String errorMsg = "Error on retrieving stats on table " + sensorTableName + " with query " + query; + log.error(errorMsg); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).entity(errorMsg).build(); + } + } + + private void publishEventReceivers(String streamNameWithVersion, TransportType transportType + , String requestedTenantDomain, String deviceType) + throws RemoteException, UserStoreException, JWTClientException { + EventReceiverAdminServiceStub receiverAdminServiceStub = DeviceMgtAPIUtils.getEventReceiverAdminServiceStub(); + try { + TransportType transportTypeToBeRemoved = TransportType.HTTP; + if (transportType == TransportType.HTTP) { + transportTypeToBeRemoved = TransportType.MQTT; + } + String eventRecieverNameTobeRemoved = getReceiverName(deviceType, requestedTenantDomain, transportTypeToBeRemoved); + EventReceiverConfigurationDto eventReceiverConfigurationDto = receiverAdminServiceStub + .getActiveEventReceiverConfiguration(eventRecieverNameTobeRemoved); + if (eventReceiverConfigurationDto != null) { + EventReceiverAdminServiceCallbackHandler eventReceiverAdminServiceCallbackHandler = + new EventReceiverAdminServiceCallbackHandler() {}; + receiverAdminServiceStub.startundeployActiveEventReceiverConfiguration(eventRecieverNameTobeRemoved + , eventReceiverAdminServiceCallbackHandler); + } + + String adapterType = OAUTH_MQTT_ADAPTER_TYPE; + BasicInputAdapterPropertyDto basicInputAdapterPropertyDtos[]; + if (transportType == TransportType.MQTT) { + basicInputAdapterPropertyDtos = new BasicInputAdapterPropertyDto[3]; + basicInputAdapterPropertyDtos[0] = getBasicInputAdapterPropertyDto("topic", requestedTenantDomain + + "/" + deviceType + "/+/events"); + basicInputAdapterPropertyDtos[1] = getBasicInputAdapterPropertyDto(MQTT_CONTENT_TRANSFORMER_TYPE + , MQTT_CONTENT_TRANSFORMER); + basicInputAdapterPropertyDtos[2] = getBasicInputAdapterPropertyDto(MQTT_CONTENT_VALIDATOR_TYPE + , MQTT_CONTENT_VALIDATOR); + } else { + adapterType = THRIFT_ADAPTER_TYPE; + basicInputAdapterPropertyDtos = new BasicInputAdapterPropertyDto[1]; + basicInputAdapterPropertyDtos[0] = getBasicInputAdapterPropertyDto("events.duplicated.in.cluster", "false"); + } + String eventRecieverName = getReceiverName(deviceType, requestedTenantDomain, transportType); + if (receiverAdminServiceStub.getActiveEventReceiverConfiguration(eventRecieverName) == null) { + if (transportType == TransportType.MQTT) { + receiverAdminServiceStub.deployJsonEventReceiverConfiguration(eventRecieverName, streamNameWithVersion + , adapterType, null, basicInputAdapterPropertyDtos, false); + } else { + receiverAdminServiceStub.deployWso2EventReceiverConfiguration(eventRecieverName, streamNameWithVersion + , adapterType, null, null, null, basicInputAdapterPropertyDtos, false, null); + } + } + } finally { + cleanup(receiverAdminServiceStub); + } + } + + private void publishStreamDefinitons(String streamName, String version, String deviceType + , EventAttributeList eventAttributes) + throws RemoteException, UserStoreException, JWTClientException { + EventStreamAdminServiceStub eventStreamAdminServiceStub = DeviceMgtAPIUtils.getEventStreamAdminServiceStub(); + try { + EventStreamDefinitionDto eventStreamDefinitionDto = new EventStreamDefinitionDto(); + eventStreamDefinitionDto.setName(streamName); + eventStreamDefinitionDto.setVersion(version); + EventStreamAttributeDto eventStreamAttributeDtos[] = + new EventStreamAttributeDto[eventAttributes.getList().size()]; + EventStreamAttributeDto metaStreamAttributeDtos[] = + new EventStreamAttributeDto[1]; + int i = 0; + for (Attribute attribute : eventAttributes.getList()) { + EventStreamAttributeDto eventStreamAttributeDto = new EventStreamAttributeDto(); + eventStreamAttributeDto.setAttributeName(attribute.getName()); + eventStreamAttributeDto.setAttributeType(attribute.getType().toString()); + eventStreamAttributeDtos[i] = eventStreamAttributeDto; + i++; + } + + EventStreamAttributeDto eventStreamAttributeDto = new EventStreamAttributeDto(); + eventStreamAttributeDto.setAttributeName(DEFAULT_DEVICE_ID_ATTRIBUTE); + eventStreamAttributeDto.setAttributeType(AttributeType.STRING.toString()); + metaStreamAttributeDtos[0] = eventStreamAttributeDto; + eventStreamDefinitionDto.setPayloadData(eventStreamAttributeDtos); + eventStreamDefinitionDto.setMetaData(metaStreamAttributeDtos); + String streamId = streamName + ":" + version; + if (eventStreamAdminServiceStub.getStreamDefinitionDto(streamId) != null) { + eventStreamAdminServiceStub.editEventStreamDefinitionAsDto(eventStreamDefinitionDto, streamId); + } else { + eventStreamAdminServiceStub.addEventStreamDefinitionAsDto(eventStreamDefinitionDto); + } + } finally { + cleanup(eventStreamAdminServiceStub); + } + } + + private void publishEventStore(String streamName, String version, EventAttributeList eventAttributes) + throws RemoteException, UserStoreException, JWTClientException, + EventStreamPersistenceAdminServiceEventStreamPersistenceAdminServiceExceptionException { + EventStreamPersistenceAdminServiceStub eventStreamPersistenceAdminServiceStub = + DeviceMgtAPIUtils.getEventStreamPersistenceAdminServiceStub(); + try { + AnalyticsTable analyticsTable = new AnalyticsTable(); + analyticsTable.setRecordStoreName(DEFAULT_EVENT_STORE_NAME); + analyticsTable.setStreamVersion(version); + analyticsTable.setTableName(streamName); + analyticsTable.setMergeSchema(false); + analyticsTable.setPersist(true); + AnalyticsTableRecord analyticsTableRecords[] = new AnalyticsTableRecord[eventAttributes.getList().size() + 1]; + int i = 0; + for (Attribute attribute : eventAttributes.getList()) { + AnalyticsTableRecord analyticsTableRecord = new AnalyticsTableRecord(); + analyticsTableRecord.setColumnName(attribute.getName()); + analyticsTableRecord.setColumnType(attribute.getType().toString().toUpperCase()); + analyticsTableRecord.setFacet(false); + analyticsTableRecord.setIndexed(false); + analyticsTableRecord.setPersist(true); + analyticsTableRecord.setPrimaryKey(false); + analyticsTableRecord.setScoreParam(false); + analyticsTableRecords[i] = analyticsTableRecord; + i++; + } + AnalyticsTableRecord analyticsTableRecord = new AnalyticsTableRecord(); + analyticsTableRecord.setColumnName(DEFAULT_META_DEVICE_ID_ATTRIBUTE); + analyticsTableRecord.setColumnType(AttributeType.STRING.toString().toUpperCase()); + analyticsTableRecord.setFacet(false); + analyticsTableRecord.setIndexed(true); + analyticsTableRecord.setPersist(true); + analyticsTableRecord.setPrimaryKey(false); + analyticsTableRecord.setScoreParam(false); + analyticsTableRecords[i] = analyticsTableRecord; + analyticsTable.setAnalyticsTableRecords(analyticsTableRecords); + eventStreamPersistenceAdminServiceStub.addAnalyticsTable(analyticsTable); + } finally { + cleanup(eventStreamPersistenceAdminServiceStub); + } + } + + private void publishWebsocketPublisherDefinition(String streamNameWithVersion, String deviceType) + throws RemoteException, UserStoreException, JWTClientException { + EventPublisherAdminServiceStub eventPublisherAdminServiceStub = DeviceMgtAPIUtils + .getEventPublisherAdminServiceStub(); + try { + String eventPublisherName = deviceType.trim().replace(" ", "_") + "_websocket_publisher"; + if (eventPublisherAdminServiceStub.getActiveEventPublisherConfiguration(eventPublisherName) == null) { + eventPublisherAdminServiceStub.deployJsonEventPublisherConfiguration(eventPublisherName + , streamNameWithVersion, DEFAULT_WEBSOCKET_PUBLISHER_ADAPTER_TYPE, null, null + , null, false); + } + } finally { + cleanup(eventPublisherAdminServiceStub); + } + } + + private BasicInputAdapterPropertyDto getBasicInputAdapterPropertyDto(String key, String value) { + BasicInputAdapterPropertyDto basicInputAdapterPropertyDto = new BasicInputAdapterPropertyDto(); + basicInputAdapterPropertyDto.setKey(key); + basicInputAdapterPropertyDto.setValue(value); + return basicInputAdapterPropertyDto; + } + + private String getTableName(String streamName) { + return streamName.toUpperCase().replace('.', '_'); + } + + private String getReceiverName(String deviceType, String tenantDomain, TransportType transportType) { + return deviceType.replace(" ", "_").trim() + "-" + tenantDomain + "-" + transportType.toString() + "-receiver"; + } + + private static AnalyticsDataAPI getAnalyticsDataAPI() { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + AnalyticsDataAPI analyticsDataAPI = + (AnalyticsDataAPI) ctx.getOSGiService(AnalyticsDataAPI.class, null); + if (analyticsDataAPI == null) { + String msg = "Analytics api service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + return analyticsDataAPI; + } + + private static EventRecords getAllEventsForDevice(String tableName, String query, List sortByFields + , int offset, int limit) throws AnalyticsException { + int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId(); + AnalyticsDataAPI analyticsDataAPI = getAnalyticsDataAPI(); + EventRecords eventRecords = new EventRecords(); + int eventCount = analyticsDataAPI.searchCount(tenantId, tableName, query); + if (eventCount == 0) { + eventRecords.setCount(0); + } + List resultEntries = analyticsDataAPI.search(tenantId, tableName, query, offset, limit, + sortByFields); + List recordIds = getRecordIds(resultEntries); + AnalyticsDataResponse response = analyticsDataAPI.get(tenantId, tableName, 1, null, recordIds); + eventRecords.setCount(eventCount); + eventRecords.setList(AnalyticsDataAPIUtil.listRecords(analyticsDataAPI, response)); + return eventRecords; + } + + private static List getRecordIds(List searchResults) { + List ids = new ArrayList<>(); + for (SearchResultEntry searchResult : searchResults) { + ids.add(searchResult.getId()); + } + return ids; + } + + private void cleanup(Stub stub) { + if (stub != null) { + try { + stub.cleanup(); + } catch (AxisFault axisFault) { + log.warn("Failed to clean the stub " + stub.getClass()); + } + } + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java new file mode 100644 index 0000000000..fa02ed7eaa --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java @@ -0,0 +1,782 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.impl; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.EnrolmentInfo; +import org.wso2.carbon.device.mgt.common.Feature; +import org.wso2.carbon.device.mgt.common.FeatureManager; +import org.wso2.carbon.device.mgt.common.InvalidConfigurationException; +import org.wso2.carbon.device.mgt.common.InvalidDeviceException; +import org.wso2.carbon.device.mgt.common.PaginationRequest; +import org.wso2.carbon.device.mgt.common.PaginationResult; +import org.wso2.carbon.device.mgt.common.app.mgt.Application; +import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException; +import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException; +import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService; +import org.wso2.carbon.device.mgt.common.device.details.DeviceInfo; +import org.wso2.carbon.device.mgt.common.device.details.DeviceLocation; +import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; +import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; +import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException; +import org.wso2.carbon.device.mgt.common.policy.mgt.Policy; +import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.NonComplianceData; +import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.PolicyComplianceException; +import org.wso2.carbon.device.mgt.common.search.SearchContext; +import org.wso2.carbon.device.mgt.core.app.mgt.ApplicationManagementProviderService; +import org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceDetailsMgtException; +import org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceInformationManager; +import org.wso2.carbon.device.mgt.core.operation.mgt.CommandOperation; +import org.wso2.carbon.device.mgt.core.operation.mgt.ConfigOperation; +import org.wso2.carbon.device.mgt.core.operation.mgt.ProfileOperation; +import org.wso2.carbon.device.mgt.core.search.mgt.SearchManagerService; +import org.wso2.carbon.device.mgt.core.search.mgt.SearchMgtException; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceCompliance; +import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceList; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.beans.OperationList; +import org.wso2.carbon.device.mgt.jaxrs.beans.OperationRequest; +import org.wso2.carbon.device.mgt.jaxrs.service.api.DeviceManagementService; +import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; +import org.wso2.carbon.policy.mgt.common.PolicyManagementException; +import org.wso2.carbon.policy.mgt.core.PolicyManagerService; +import org.wso2.carbon.utils.multitenancy.MultitenantUtils; + +import javax.validation.Valid; +import javax.validation.constraints.Size; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +@Path("/devices") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class DeviceManagementServiceImpl implements DeviceManagementService { + + public static final String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss"; + private static final Log log = LogFactory.getLog(DeviceManagementServiceImpl.class); + + @GET + @Path("/{type}/{id}/status") + @Override + public Response isEnrolled(@PathParam("type") String type, @PathParam("id") String id) { + boolean result; + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(id, type); + try { + result = DeviceMgtAPIUtils.getDeviceManagementService().isEnrolled(deviceIdentifier); + if (result) { + return Response.status(Response.Status.OK).build(); + } else { + return Response.status(Response.Status.NO_CONTENT).build(); + } + } catch (DeviceManagementException e) { + String msg = "Error occurred while checking enrollment status of the device."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @GET + @Deprecated + @Override + public Response getDevices( + @QueryParam("name") String name, + @QueryParam("type") String type, + @QueryParam("user") String user, + @QueryParam("userPattern") String userPattern, + @QueryParam("role") String role, + @QueryParam("ownership") String ownership, + @QueryParam("status") String status, + @QueryParam("groupId") int groupId, + @QueryParam("since") String since, + @HeaderParam("If-Modified-Since") String ifModifiedSince, + @QueryParam("offset") int offset, + @QueryParam("limit") int limit) { + try { + if (!StringUtils.isEmpty(name) && !StringUtils.isEmpty(role)) { + return Response.status(Response.Status.BAD_REQUEST).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage("Request contains both name and role " + + "parameters. Only one is allowed " + + "at once.").build()).build(); + } + RequestValidationUtil.validatePaginationParameters(offset, limit); + DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService(); + DeviceAccessAuthorizationService deviceAccessAuthorizationService = + DeviceMgtAPIUtils.getDeviceAccessAuthorizationService(); + if (deviceAccessAuthorizationService == null) { + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage("Device access authorization service is " + + "failed").build()).build(); + } + PaginationRequest request = new PaginationRequest(offset, limit); + PaginationResult result; + DeviceList devices = new DeviceList(); + + if (name != null && !name.isEmpty()) { + request.setDeviceName(name); + } + if (type != null && !type.isEmpty()) { + request.setDeviceType(type); + } + if (ownership != null && !ownership.isEmpty()) { + RequestValidationUtil.validateOwnershipType(ownership); + request.setOwnership(ownership); + } + if (status != null && !status.isEmpty()) { + RequestValidationUtil.validateStatus(status); + request.setStatus(status); + } + if (groupId != 0) { + request.setGroupId(groupId); + } + if (role != null && !role.isEmpty()) { + request.setOwnerRole(role); + } + + String authorizedUser = MultitenantUtils.getTenantAwareUsername(CarbonContext.getThreadLocalCarbonContext().getUsername()); + + if (deviceAccessAuthorizationService.isDeviceAdminUser()) { + if (user != null && !user.isEmpty()) { + request.setOwner(MultitenantUtils.getTenantAwareUsername(user)); + } else if (userPattern != null && !userPattern.isEmpty()) { + request.setOwnerPattern(userPattern); + } + } else { + if (user != null && !user.isEmpty()) { + user = MultitenantUtils.getTenantAwareUsername(user); + if (user.equals(authorizedUser)) { + request.setOwner(user); + } else { + String msg = "User '" + authorizedUser + "' is not authorized to retrieve devices of '" + user + + "' user"; + log.error(msg); + return Response.status(Response.Status.UNAUTHORIZED).entity( + new ErrorResponse.ErrorResponseBuilder().setCode(401l).setMessage(msg).build()).build(); + } + } else { + request.setOwner(authorizedUser); + } + } + + if (ifModifiedSince != null && !ifModifiedSince.isEmpty()) { + Date sinceDate; + SimpleDateFormat format = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z"); + try { + sinceDate = format.parse(ifModifiedSince); + } catch (ParseException e) { + return Response.status(Response.Status.BAD_REQUEST).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage("Invalid date " + + "string is provided in 'If-Modified-Since' header").build()).build(); + } + request.setSince(sinceDate); + result = dms.getAllDevices(request); + + if (result == null || result.getData() == null || result.getData().size() <= 0) { + return Response.status(Response.Status.NOT_MODIFIED).entity("No device is modified " + + "after the timestamp provided in 'If-Modified-Since' header").build(); + } + } else if (since != null && !since.isEmpty()) { + Date sinceDate; + SimpleDateFormat format = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z"); + try { + sinceDate = format.parse(since); + } catch (ParseException e) { + return Response.status(Response.Status.BAD_REQUEST).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage("Invalid date " + + "string is provided in 'since' filter").build()).build(); + } + request.setSince(sinceDate); + result = dms.getAllDevices(request); + + if (result == null || result.getData() == null || result.getData().size() <= 0) { + devices.setList(new ArrayList()); + devices.setCount(0); + return Response.status(Response.Status.OK).entity(devices).build(); + } + } else { + result = dms.getAllDevices(request); + int resultCount = result.getRecordsTotal(); + if (resultCount == 0) { + Response.status(Response.Status.OK).entity(devices).build(); + } + } + + devices.setList((List) result.getData()); + devices.setCount(result.getRecordsTotal()); + return Response.status(Response.Status.OK).entity(devices).build(); + } catch (DeviceManagementException e) { + String msg = "Error occurred while fetching all enrolled devices"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (DeviceAccessAuthorizationException e) { + String msg = "Error occurred while checking device access authorization"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + + @GET + @Override + @Path("/user-devices") + public Response getDeviceByUser(@QueryParam("requireDeviceInfo") boolean requireDeviceInfo, + @QueryParam("offset") int offset, + @QueryParam("limit") int limit) { + + RequestValidationUtil.validatePaginationParameters(offset, limit); + PaginationRequest request = new PaginationRequest(offset, limit); + PaginationResult result; + DeviceList devices = new DeviceList(); + + String currentUser = CarbonContext.getThreadLocalCarbonContext().getUsername(); + request.setOwner(currentUser); + + try { + if (requireDeviceInfo) { + result = DeviceMgtAPIUtils.getDeviceManagementService().getDevicesOfUser(request); + } else { + result = DeviceMgtAPIUtils.getDeviceManagementService().getDevicesOfUser(request, false); + } + devices.setList((List) result.getData()); + devices.setCount(result.getRecordsTotal()); + return Response.status(Response.Status.OK).entity(devices).build(); + } catch (DeviceManagementException e) { + String msg = "Error occurred while fetching all enrolled devices"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + @DELETE + @Override + @Path("/type/{device-type}/id/{device-id}") + public Response deleteDevice(@PathParam("device-type") String deviceType, @PathParam("device-id") String deviceId) { + DeviceManagementProviderService deviceManagementProviderService = + DeviceMgtAPIUtils.getDeviceManagementService(); + try { + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(deviceId, deviceType); + Device persistedDevice = deviceManagementProviderService.getDevice(deviceIdentifier, true); + if (persistedDevice == null) { + return Response.status(Response.Status.NOT_FOUND).build(); + } + + boolean response = deviceManagementProviderService.disenrollDevice(deviceIdentifier); + return Response.status(Response.Status.OK).entity(response).build(); + + } catch (DeviceManagementException e) { + String msg = "Error encountered while deleting device of type : " + deviceType + " and " + + "ID : " + deviceId; + log.error(msg); + return Response.status(Response.Status.BAD_REQUEST).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build() + ).build(); + } + } + + @POST + @Override + @Path("/type/{device-type}/id/{device-id}/rename") + public Response renameDevice(Device device, @PathParam("device-type") String deviceType, + @PathParam("device-id") String deviceId) { + DeviceManagementProviderService deviceManagementProviderService = DeviceMgtAPIUtils.getDeviceManagementService(); + try { + Device persistedDevice = deviceManagementProviderService.getDevice(new DeviceIdentifier + (deviceId, deviceType), true); + persistedDevice.setName(device.getName()); + boolean response = deviceManagementProviderService.modifyEnrollment(persistedDevice); + return Response.status(Response.Status.CREATED).entity(response).build(); + + } catch (DeviceManagementException e) { + log.error("Error encountered while updating device of type : " + deviceType + " and " + + "ID : " + deviceId); + return Response.status(Response.Status.BAD_REQUEST).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage("Error while updating " + + "device of type " + deviceType + " and ID : " + deviceId).build()).build(); + } + } + + @GET + @Path("/{type}/{id}") + @Override + public Response getDevice( + @PathParam("type") @Size(max = 45) String type, + @PathParam("id") @Size(max = 45) String id, + @QueryParam("owner") @Size(max = 100) String owner, + @HeaderParam("If-Modified-Since") String ifModifiedSince) { + Device device = null; + try { + RequestValidationUtil.validateDeviceIdentifier(type, id); + DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService(); + DeviceAccessAuthorizationService deviceAccessAuthorizationService = + DeviceMgtAPIUtils.getDeviceAccessAuthorizationService(); + + // this is the user who initiates the request + String authorizedUser = CarbonContext.getThreadLocalCarbonContext().getUsername(); + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(id, type); + // check whether the user is authorized + if (!deviceAccessAuthorizationService.isUserAuthorized(deviceIdentifier, authorizedUser)) { + String msg = "User '" + authorizedUser + "' is not authorized to retrieve the given device id '" + id + "'"; + log.error(msg); + return Response.status(Response.Status.UNAUTHORIZED).entity( + new ErrorResponse.ErrorResponseBuilder().setCode(401l).setMessage(msg).build()).build(); + } + + Date sinceDate = null; + if (ifModifiedSince != null && !ifModifiedSince.isEmpty()) { + SimpleDateFormat format = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z"); + try { + sinceDate = format.parse(ifModifiedSince); + } catch (ParseException e) { + return Response.status(Response.Status.BAD_REQUEST).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage("Invalid date " + + "string is provided in 'If-Modified-Since' header").build()).build(); + } + } + + if (!StringUtils.isEmpty(owner)) { + if (authorizedUser.equalsIgnoreCase(owner) || deviceAccessAuthorizationService.isDeviceAdminUser()) { + if (sinceDate != null) { + device = dms.getDevice(new DeviceIdentifier(id, type), owner, sinceDate, true); + if (device == null) { + return Response.status(Response.Status.NOT_MODIFIED).entity("No device is modified " + + "after the timestamp provided in 'If-Modified-Since' header").build(); + } + } else { + device = dms.getDevice(new DeviceIdentifier(id, type), owner, true); + } + } else { + String msg = "User '" + authorizedUser + "' is not authorized to retrieve the given device id '" + id + + "' which belongs to user '" + owner + "'"; + log.error(msg); + return Response.status(Response.Status.UNAUTHORIZED).entity( + new ErrorResponse.ErrorResponseBuilder().setCode(401l).setMessage(msg).build()).build(); + } + } else if (deviceAccessAuthorizationService.isDeviceAdminUser()) { + if (sinceDate != null) { + device = dms.getDevice(new DeviceIdentifier(id, type), sinceDate); + if (device == null) { + return Response.status(Response.Status.NOT_MODIFIED).entity("No device is modified " + + "after the timestamp provided in 'If-Modified-Since' header").build(); + } + } else { + device = dms.getDevice(new DeviceIdentifier(id, type)); + } + } else { + owner = authorizedUser; + if (sinceDate != null) { + device = dms.getDevice(new DeviceIdentifier(id, type), owner, sinceDate, true); + if (device == null) { + return Response.status(Response.Status.NOT_MODIFIED).entity("No device is modified " + + "after the timestamp provided in 'If-Modified-Since' header").build(); + } + } else { + device = dms.getDevice(new DeviceIdentifier(id, type), owner, true); + } + } + } catch (DeviceManagementException e) { + String msg = "Error occurred while fetching the device information."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (DeviceAccessAuthorizationException e) { + String msg = "Error occurred while checking the device authorization."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + if (device == null) { + return Response.status(Response.Status.NOT_FOUND).entity( + new ErrorResponse.ErrorResponseBuilder().setCode(404l).setMessage("Requested device of type '" + + type + "', which carries id '" + id + "' does not exist").build()).build(); + } + return Response.status(Response.Status.OK).entity(device).build(); + } + + @GET + @Path("/{type}/{id}/location") + @Override + public Response getDeviceLocation( + @PathParam("type") @Size(max = 45) String type, + @PathParam("id") @Size(max = 45) String id, + @HeaderParam("If-Modified-Since") String ifModifiedSince) { + DeviceInformationManager informationManager; + DeviceLocation deviceLocation; + try { + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); + deviceIdentifier.setId(id); + deviceIdentifier.setType(type); + informationManager = DeviceMgtAPIUtils.getDeviceInformationManagerService(); + deviceLocation = informationManager.getDeviceLocation(deviceIdentifier); + + } catch (DeviceDetailsMgtException e) { + String msg = "Error occurred while getting the device location."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + return Response.status(Response.Status.OK).entity(deviceLocation).build(); + + } + + + @GET + @Path("/{type}/{id}/info") + @Override + public Response getDeviceInformation( + @PathParam("type") @Size(max = 45) String type, + @PathParam("id") @Size(max = 45) String id, + @HeaderParam("If-Modified-Since") String ifModifiedSince) { + DeviceInformationManager informationManager; + DeviceInfo deviceInfo; + try { + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); + deviceIdentifier.setId(id); + deviceIdentifier.setType(type); + informationManager = DeviceMgtAPIUtils.getDeviceInformationManagerService(); + deviceInfo = informationManager.getDeviceInfo(deviceIdentifier); + + } catch (DeviceDetailsMgtException e) { + String msg = "Error occurred while getting the device information of id : " + id + " type : " + type ; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + return Response.status(Response.Status.OK).entity(deviceInfo).build(); + + } + + @GET + @Path("/{type}/{id}/features") + @Override + public Response getFeaturesOfDevice( + @PathParam("type") @Size(max = 45) String type, + @PathParam("id") @Size(max = 45) String id, + @HeaderParam("If-Modified-Since") String ifModifiedSince) { + List features; + DeviceManagementProviderService dms; + try { + RequestValidationUtil.validateDeviceIdentifier(type, id); + dms = DeviceMgtAPIUtils.getDeviceManagementService(); + FeatureManager fm = dms.getFeatureManager(type); + if (fm == null) { + return Response.status(Response.Status.NOT_FOUND).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage("No feature manager is " + + "registered with the given type '" + type + "'").build()).build(); + } + features = fm.getFeatures(); + } catch (DeviceManagementException e) { + String msg = "Error occurred while retrieving the list of features of '" + type + "' device, which " + + "carries the id '" + id + "'"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + return Response.status(Response.Status.OK).entity(features).build(); + } + + @POST + @Path("/search-devices") + @Override + public Response searchDevices(@QueryParam("offset") int offset, + @QueryParam("limit") int limit, SearchContext searchContext) { + SearchManagerService searchManagerService; + List devices; + DeviceList deviceList = new DeviceList(); + try { + searchManagerService = DeviceMgtAPIUtils.getSearchManagerService(); + devices = searchManagerService.search(searchContext); + } catch (SearchMgtException e) { + String msg = "Error occurred while searching for devices that matches the provided selection criteria"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + deviceList.setList(devices); + deviceList.setCount(devices.size()); + return Response.status(Response.Status.OK).entity(deviceList).build(); + } + + @GET + @Path("/{type}/{id}/applications") + @Override + public Response getInstalledApplications( + @PathParam("type") @Size(max = 45) String type, + @PathParam("id") @Size(max = 45) String id, + @HeaderParam("If-Modified-Since") String ifModifiedSince, + @QueryParam("offset") int offset, + @QueryParam("limit") int limit) { + List applications; + ApplicationManagementProviderService amc; + try { + RequestValidationUtil.validateDeviceIdentifier(type, id); + + amc = DeviceMgtAPIUtils.getAppManagementService(); + applications = amc.getApplicationListForDevice(new DeviceIdentifier(id, type)); + return Response.status(Response.Status.OK).entity(applications).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while fetching the apps of the '" + type + "' device, which carries " + + "the id '" + id + "'"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + @GET + @Path("/{type}/{id}/operations") + @Deprecated + @Override + public Response getDeviceOperations( + @PathParam("type") @Size(max = 45) String type, + @PathParam("id") @Size(max = 45) String id, + @HeaderParam("If-Modified-Since") String ifModifiedSince, + @QueryParam("offset") int offset, + @QueryParam("limit") int limit) + { + OperationList operationsList = new OperationList(); + String owner = CarbonContext.getThreadLocalCarbonContext().getUsername(); + RequestValidationUtil.validateOwnerParameter(owner); + RequestValidationUtil.validatePaginationParameters(offset, limit); + PaginationRequest request = new PaginationRequest(offset, limit); + request.setOwner(owner); + PaginationResult result; + DeviceManagementProviderService dms; + try { + RequestValidationUtil.validateDeviceIdentifier(type, id); + + dms = DeviceMgtAPIUtils.getDeviceManagementService(); + result = dms.getOperations(new DeviceIdentifier(id, type), request); + + operationsList.setList((List) result.getData()); + operationsList.setCount(result.getRecordsTotal()); + return Response.status(Response.Status.OK).entity(operationsList).build(); + } catch (OperationManagementException e) { + String msg = "Error occurred while fetching the operations for the '" + type + "' device, which " + + "carries the id '" + id + "'"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + @GET + @Path("/{type}/{id}/effective-policy") + @Override + public Response getEffectivePolicyOfDevice(@PathParam("type") @Size(max = 45) String type, + @PathParam("id") @Size(max = 45) String id, + @HeaderParam("If-Modified-Since") String ifModifiedSince) { + try { + RequestValidationUtil.validateDeviceIdentifier(type, id); + + PolicyManagerService policyManagementService = DeviceMgtAPIUtils.getPolicyManagementService(); + Policy policy = policyManagementService.getAppliedPolicyToDevice(new DeviceIdentifier(id, type)); + + return Response.status(Response.Status.OK).entity(policy).build(); + } catch (PolicyManagementException e) { + String msg = "Error occurred while retrieving the current policy associated with the '" + type + + "' device, which carries the id '" + id + "'"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + @GET + @Path("{type}/{id}/compliance-data") + public Response getComplianceDataOfDevice(@PathParam("type") @Size(max = 45) String type, + @PathParam("id") @Size(max = 45) String id) { + + RequestValidationUtil.validateDeviceIdentifier(type, id); + PolicyManagerService policyManagementService = DeviceMgtAPIUtils.getPolicyManagementService(); + Policy policy; + NonComplianceData complianceData; + DeviceCompliance deviceCompliance = new DeviceCompliance(); + + try { + policy = policyManagementService.getAppliedPolicyToDevice(new DeviceIdentifier(id, type)); + } catch (PolicyManagementException e) { + String msg = "Error occurred while retrieving the current policy associated with the '" + type + + "' device, which carries the id '" + id + "'"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + + if (policy == null) { + deviceCompliance.setDeviceID(id); + deviceCompliance.setComplianceData(null); + return Response.status(Response.Status.OK).entity(deviceCompliance).build(); + } else { + try { + policyManagementService = DeviceMgtAPIUtils.getPolicyManagementService(); + complianceData = policyManagementService.getDeviceCompliance( + new DeviceIdentifier(id, type)); + deviceCompliance.setDeviceID(id); + deviceCompliance.setComplianceData(complianceData); + return Response.status(Response.Status.OK).entity(deviceCompliance).build(); + } catch (PolicyComplianceException e) { + String error = "Error occurred while getting the compliance data."; + log.error(error, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(error).build()).build(); + } + } + } + + /** + * Change device status. + * + * @param type Device type + * @param id Device id + * @param newsStatus Device new status + * @return {@link Response} object + */ + @PUT + @Path("/{type}/{id}/changestatus") + public Response changeDeviceStatus(@PathParam("type") @Size(max = 45) String type, + @PathParam("id") @Size(max = 45) String id, + @QueryParam("newStatus") EnrolmentInfo.Status newsStatus) { + RequestValidationUtil.validateDeviceIdentifier(type, id); + DeviceManagementProviderService deviceManagementProviderService = + DeviceMgtAPIUtils.getDeviceManagementService(); + try { + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(id, type); + Device persistedDevice = deviceManagementProviderService.getDevice(deviceIdentifier, false); + if (persistedDevice == null) { + return Response.status(Response.Status.NOT_FOUND).build(); + } + boolean response = deviceManagementProviderService.changeDeviceStatus(deviceIdentifier, newsStatus); + return Response.status(Response.Status.OK).entity(response).build(); + } catch (DeviceManagementException e) { + String msg = "Error occurred while changing device status of type : " + type + " and " + + "device id : " + id; + log.error(msg); + return Response.status(Response.Status.BAD_REQUEST).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + @POST + @Path("/{type}/operations") + public Response addOperation(@PathParam("type") String type, @Valid OperationRequest operationRequest) { + try { + if (operationRequest == null || operationRequest.getDeviceIdentifiers() == null + || operationRequest.getOperation() == null) { + String errorMessage = "Operation cannot be empty"; + log.error(errorMessage); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + if (!DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) { + String errorMessage = "Device Type is invalid"; + log.error(errorMessage); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + Operation.Type operationType = operationRequest.getOperation().getType(); + if (operationType == Operation.Type.COMMAND || operationType == Operation.Type.CONFIG || operationType == Operation.Type.PROFILE) { + DeviceIdentifier deviceIdentifier; + List deviceIdentifiers = new ArrayList<>(); + for (String deviceId : operationRequest.getDeviceIdentifiers()) { + deviceIdentifier = new DeviceIdentifier(); + deviceIdentifier.setId(deviceId); + deviceIdentifier.setType(type); + deviceIdentifiers.add(deviceIdentifier); + } + Operation operation; + if (operationType == Operation.Type.COMMAND) { + Operation commandOperation = operationRequest.getOperation(); + operation = new CommandOperation(); + operation.setType(Operation.Type.COMMAND); + operation.setCode(commandOperation.getCode()); + operation.setEnabled(commandOperation.isEnabled()); + operation.setStatus(commandOperation.getStatus()); + + } else if (operationType == Operation.Type.CONFIG) { + Operation configOperation = operationRequest.getOperation(); + operation = new ConfigOperation(); + operation.setType(Operation.Type.CONFIG); + operation.setCode(configOperation.getCode()); + operation.setEnabled(configOperation.isEnabled()); + operation.setPayLoad(configOperation.getPayLoad()); + operation.setStatus(configOperation.getStatus()); + + } else { + Operation profileOperation = operationRequest.getOperation(); + operation = new ProfileOperation(); + operation.setType(Operation.Type.PROFILE); + operation.setCode(profileOperation.getCode()); + operation.setEnabled(profileOperation.isEnabled()); + operation.setPayLoad(profileOperation.getPayLoad()); + operation.setStatus(profileOperation.getStatus()); + } + String date = new SimpleDateFormat(DATE_FORMAT_NOW).format(new Date()); + operation.setCreatedTimeStamp(date); + Activity activity = DeviceMgtAPIUtils.getDeviceManagementService().addOperation(type, operation, + deviceIdentifiers); + return Response.status(Response.Status.CREATED).entity(activity).build(); + } else { + String message = "Only Command and Config operation is supported through this api"; + return Response.status(Response.Status.NOT_ACCEPTABLE).entity(message).build(); + } + + } catch (InvalidDeviceException e) { + String errorMessage = "Invalid Device Identifiers found."; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); + } catch (OperationManagementException e) { + String errorMessage = "Issue in retrieving operation management service instance"; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); + } catch (DeviceManagementException e) { + String errorMessage = "Issue in retrieving deivce management service instance"; + log.error(errorMessage, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(errorMessage).build()).build(); + } catch (InvalidConfigurationException e) { + log.error("failed to add operation", e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceImpl.java new file mode 100644 index 0000000000..5fdc06a501 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceImpl.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.Feature; +import org.wso2.carbon.device.mgt.common.FeatureManager; +import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig; +import org.wso2.carbon.device.mgt.common.type.mgt.DeviceTypeMetaDefinition; +import org.wso2.carbon.device.mgt.core.dto.DeviceType; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceTypeList; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.service.api.DeviceTypeManagementService; +import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; + +import javax.validation.constraints.Size; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Response; +import java.util.ArrayList; +import java.util.List; + +@Path("/device-types") +public class DeviceTypeManagementServiceImpl implements DeviceTypeManagementService { + + private static Log log = LogFactory.getLog(DeviceTypeManagementServiceImpl.class); + + @GET + @Override + public Response getDeviceTypes(@HeaderParam("If-Modified-Since") String ifModifiedSince) { + List deviceTypes; + try { + deviceTypes = DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes(); + + DeviceTypeList deviceTypeList = new DeviceTypeList(); + deviceTypeList.setCount(deviceTypes.size()); + deviceTypeList.setList(deviceTypes); + return Response.status(Response.Status.OK).entity(deviceTypeList).build(); + } catch (DeviceManagementException e) { + String msg = "Error occurred while fetching the list of device types."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + @GET + @Override + @Path("/{type}/features") + public Response getFeatures(@PathParam("type") @Size(max = 45) String type, @HeaderParam("If-Modified-Since") String ifModifiedSince) { + List features; + DeviceManagementProviderService dms; + try { + dms = DeviceMgtAPIUtils.getDeviceManagementService(); + FeatureManager fm = dms.getFeatureManager(type); + if (fm == null) { + return Response.status(Response.Status.NOT_FOUND).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage("No feature manager is " + + "registered with the given type '" + type + "'").build()).build(); + } + features = fm.getFeatures(); + } catch (DeviceManagementException e) { + String msg = "Error occurred while retrieving the list of features of '" + type + "' device type"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + return Response.status(Response.Status.OK).entity(features).build(); + } + + @Override + @GET + @Path("/config") + public Response getDeviceTypes() { + try { + List deviceTypes = DeviceMgtAPIUtils.getDeviceManagementService().getDeviceTypes(); + List filteredDeviceTypes = new ArrayList<>(); + for (DeviceType deviceType : deviceTypes) { + filteredDeviceTypes.add(clearMetaEntryInfo(deviceType)); + } + return Response.status(Response.Status.OK).entity(filteredDeviceTypes).build(); + } catch (DeviceManagementException e) { + String msg = "Error occurred at server side while fetching device type."; + log.error(msg, e); + return Response.serverError().entity(msg).build(); + } + } + + @Override + @GET + @Path("/config/{type}") + public Response getDeviceTypeByName(@PathParam("type") String type) { + if (type != null && type.length() > 0) { + try { + DeviceType deviceType = DeviceMgtAPIUtils.getDeviceManagementService().getDeviceType(type); + if (deviceType == null) { + String msg = "Device type does not exist, " + type; + return Response.status(Response.Status.NO_CONTENT).entity(msg).build(); + } + return Response.status(Response.Status.OK).entity(deviceType).build(); + } catch (DeviceManagementException e) { + String msg = "Error occurred at server side while fetching device type."; + log.error(msg, e); + return Response.serverError().entity(msg).build(); + } + } else { + return Response.status(Response.Status.BAD_REQUEST).build(); + } + } + + /** + * This cleans up the configs that should not be exposed to iot users. + * @param deviceType + * @return + */ + private DeviceType clearMetaEntryInfo(DeviceType deviceType) { + DeviceTypeMetaDefinition metaDefinition = deviceType.getDeviceTypeMetaDefinition(); + if (metaDefinition != null) { + metaDefinition.setInitialOperationConfig(null); + if (metaDefinition.getPushNotificationConfig() != null) { + metaDefinition.setPushNotificationConfig(new PushNotificationConfig(metaDefinition. + getPushNotificationConfig().getType(), false, null)); + } + deviceType.setDeviceTypeMetaDefinition(metaDefinition); + } + return deviceType; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GeoLocationBasedServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GeoLocationBasedServiceImpl.java new file mode 100644 index 0000000000..311dd44a06 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GeoLocationBasedServiceImpl.java @@ -0,0 +1,400 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.service.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.analytics.api.AnalyticsDataAPI; +import org.wso2.carbon.analytics.api.AnalyticsDataAPIUtil; +import org.wso2.carbon.analytics.dataservice.commons.AnalyticsDataResponse; +import org.wso2.carbon.analytics.dataservice.commons.SearchResultEntry; +import org.wso2.carbon.analytics.dataservice.commons.SortByField; +import org.wso2.carbon.analytics.dataservice.commons.SortType; +import org.wso2.carbon.analytics.datasource.commons.Record; +import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException; +import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceManagementConstants.GeoServices; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException; +import org.wso2.carbon.device.mgt.common.geo.service.*; +import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants; +import org.wso2.carbon.device.mgt.core.geo.GeoCluster; +import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate; +import org.wso2.carbon.device.mgt.core.geo.geoHash.geoHashStrategy.GeoHashLengthStrategy; +import org.wso2.carbon.device.mgt.core.geo.geoHash.geoHashStrategy.ZoomGeoHashLengthStrategy; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil; +import org.wso2.carbon.device.mgt.jaxrs.service.api.GeoLocationBasedService; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtUtil; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.utils.multitenancy.MultitenantUtils; + +import javax.ws.rs.*; +import javax.ws.rs.core.Response; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * The api for + */ +public class GeoLocationBasedServiceImpl implements GeoLocationBasedService { + + private static Log log = LogFactory.getLog(GeoLocationBasedServiceImpl.class); + + @Path("stats/{deviceType}/{deviceId}") + @GET + @Consumes("application/json") + @Produces("application/json") + public Response getGeoDeviceStats(@PathParam("deviceId") String deviceId, + @PathParam("deviceType") String deviceType, + @QueryParam("from") long from, @QueryParam("to") long to) { + try { + if (!DeviceManagerUtil.isPublishOperationResponseEnabled()) { + return Response.status(Response.Status.BAD_REQUEST.getStatusCode()) + .entity("Unable to retrive Geo Device stats. Geo Data publishing does not enabled.").build(); + } + } catch (DeviceManagementException e) { + return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).entity(e.getMessage()).build(); + } + String tableName = "IOT_PER_DEVICE_STREAM_GEO_FUSEDSPATIALEVENT"; + String fromDate = String.valueOf(from); + String toDate = String.valueOf(to); + String query = "id:" + deviceId + " AND type:" + deviceType; + if (from != 0 || to != 0) { + query += " AND timeStamp : [" + fromDate + " TO " + toDate + "]"; + } + try { + if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized( + new DeviceIdentifier(deviceId, deviceType), + DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) { + return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); + } + List sortByFields = new ArrayList<>(); + SortByField sortByField = new SortByField("timeStamp", SortType.ASC); + sortByFields.add(sortByField); + + // this is the user who initiates the request + String authorizedUser = MultitenantUtils.getTenantAwareUsername( + CarbonContext.getThreadLocalCarbonContext().getUsername()); + + try { + String tenantDomain = MultitenantUtils.getTenantDomain(authorizedUser); + int tenantId = DeviceMgtAPIUtils.getRealmService().getTenantManager().getTenantId(tenantDomain); + AnalyticsDataAPI analyticsDataAPI = DeviceMgtAPIUtils.getAnalyticsDataAPI(); + List searchResults = analyticsDataAPI.search(tenantId, tableName, query, + 0, + 100, + sortByFields); + List events = getEventBeans(analyticsDataAPI, tenantId, tableName, new ArrayList(), + searchResults); + return Response.ok().entity(events).build(); + } catch (AnalyticsException | UserStoreException e) { + log.error("Failed to perform search on table: " + tableName + " : " + e.getMessage(), e); + throw DeviceMgtUtil.buildBadRequestException( + Constants.ErrorMessages.STATUS_BAD_REQUEST_MESSAGE_DEFAULT); + } + } catch (DeviceAccessAuthorizationException e) { + log.error(e.getErrorMessage()); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build(); + } + } + + @Path("stats/deviceLocations") + @GET + @Consumes("application/json") + @Produces("application/json") + public Response getGeoDeviceLocations( + @QueryParam("minLat") double minLat, + @QueryParam("maxLat") double maxLat, + @QueryParam("minLong") double minLong, + @QueryParam("maxLong") double maxLong, + @QueryParam("zoom") int zoom) { + + GeoHashLengthStrategy geoHashLengthStrategy = new ZoomGeoHashLengthStrategy(); + GeoCoordinate southWest = new GeoCoordinate(minLat, minLong); + GeoCoordinate northEast = new GeoCoordinate(maxLat, maxLong); + int geohashLength = geoHashLengthStrategy.getGeohashLength(southWest, northEast, zoom); + DeviceManagementProviderService deviceManagementService = DeviceMgtAPIUtils.getDeviceManagementService(); + List geoClusters; + try { + geoClusters = deviceManagementService.findGeoClusters(southWest, northEast, geohashLength); + } catch (DeviceManagementException e) { + String msg = "Error occurred while retrieving geo clusters "; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build(); + } + return Response.ok().entity(geoClusters).build(); + + } + + @Path("alerts/{alertType}/{deviceType}/{deviceId}") + @POST + @Consumes("application/json") + @Produces("application/json") + public Response createGeoAlerts(Alert alert, @PathParam("deviceId") String deviceId, + @PathParam("deviceType") String deviceType, + @PathParam("alertType") String alertType) { + try { + if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized( + new DeviceIdentifier(deviceId, deviceType), + DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) { + return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); + } + + // this is the user who initiates the request + String authorizedUser = MultitenantUtils.getTenantAwareUsername( + CarbonContext.getThreadLocalCarbonContext().getUsername() + ); + + DeviceIdentifier identifier = new DeviceIdentifier(); + identifier.setId(deviceId); + identifier.setType(deviceType); + + GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService(); + geoService.createGeoAlert(alert, identifier, alertType); + return Response.ok().build(); + } catch (DeviceAccessAuthorizationException | GeoLocationBasedServiceException e) { + String error = "Error occurred while creating the geo alert for " + deviceType + " with id: " + deviceId; + log.error(error, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build(); + } + } + + @Path("alerts/{alertType}/{deviceType}/{deviceId}") + @PUT + @Consumes("application/json") + @Produces("application/json") + public Response updateGeoAlerts(Alert alert, @PathParam("deviceId") String deviceId, + @PathParam("deviceType") String deviceType, + @PathParam("alertType") String alertType) { + try { + if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized( + new DeviceIdentifier(deviceId, deviceType), + DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) { + return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); + } + + // this is the user who initiates the request + String authorizedUser = MultitenantUtils.getTenantAwareUsername( + CarbonContext.getThreadLocalCarbonContext().getUsername() + ); + + DeviceIdentifier identifier = new DeviceIdentifier(); + identifier.setId(deviceId); + identifier.setType(deviceType); + + GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService(); + geoService.updateGeoAlert(alert, identifier, alertType); + return Response.ok().build(); + } catch (DeviceAccessAuthorizationException | GeoLocationBasedServiceException e) { + String error = "Error occurred while creating the geo alert for " + deviceType + " with id: " + deviceId; + log.error(error, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build(); + } + } + + @Path("alerts/{alertType}/{deviceType}/{deviceId}") + @DELETE + @Consumes("application/json") + @Produces("application/json") + public Response removeGeoAlerts(@PathParam("deviceId") String deviceId, + @PathParam("deviceType") String deviceType, + @PathParam("alertType") String alertType, + @QueryParam("queryName") String queryName) { + try { + if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized( + new DeviceIdentifier(deviceId, deviceType), + DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) { + return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); + } + + // this is the user who initiates the request + String authorizedUser = MultitenantUtils.getTenantAwareUsername( + CarbonContext.getThreadLocalCarbonContext().getUsername() + ); + + DeviceIdentifier identifier = new DeviceIdentifier(); + identifier.setId(deviceId); + identifier.setType(deviceType); + + GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService(); + geoService.removeGeoAlert(alertType, identifier, queryName); + return Response.ok().build(); + } catch (DeviceAccessAuthorizationException | GeoLocationBasedServiceException e) { + String error = "Error occurred while removing the geo alert for " + deviceType + " with id: " + deviceId; + log.error(error, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build(); + } + } + + @Path("alerts/{alertType}/{deviceType}/{deviceId}") + @GET + @Consumes("application/json") + @Produces("application/json") + public Response getGeoAlerts(@PathParam("deviceId") String deviceId, + @PathParam("deviceType") String deviceType, + @PathParam("alertType") String alertType) { + try { + if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized( + new DeviceIdentifier(deviceId, deviceType), + DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) { + return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); + } + + // this is the user who initiates the request + String authorizedUser = MultitenantUtils.getTenantAwareUsername( + CarbonContext.getThreadLocalCarbonContext().getUsername() + ); + + DeviceIdentifier identifier = new DeviceIdentifier(); + identifier.setId(deviceId); + identifier.setType(deviceType); + + GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService(); + + if (GeoServices.ALERT_TYPE_WITHIN.equals(alertType)) { + List alerts = geoService.getWithinAlerts(identifier); + return Response.ok().entity(alerts).build(); + } else if (GeoServices.ALERT_TYPE_EXIT.equals(alertType)) { + List alerts = geoService.getExitAlerts(identifier); + return Response.ok().entity(alerts).build(); + } else if (GeoServices.ALERT_TYPE_SPEED.equals(alertType)) { + String result = geoService.getSpeedAlerts(identifier); + return Response.ok().entity(result).build(); + } else if (GeoServices.ALERT_TYPE_PROXIMITY.equals(alertType)) { + String result = geoService.getProximityAlerts(identifier); + return Response.ok().entity(result).build(); + } else if (GeoServices.ALERT_TYPE_STATIONARY.equals(alertType)) { + List alerts = geoService.getStationaryAlerts(identifier); + return Response.ok().entity(alerts).build(); + } else if (GeoServices.ALERT_TYPE_TRAFFIC.equals(alertType)) { + List alerts = geoService.getTrafficAlerts(identifier); + return Response.ok().entity(alerts).build(); + } + return null; + } catch (DeviceAccessAuthorizationException | GeoLocationBasedServiceException e) { + String error = "Error occurred while getting the geo alerts for " + deviceType + " with id: " + deviceId; + log.error(error, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build(); + } + } + + @Path("alerts/history/{deviceType}/{deviceId}") + @GET + @Consumes("application/json") + @Produces("application/json") + public Response getGeoAlertsHistory(@PathParam("deviceId") String deviceId, + @PathParam("deviceType") String deviceType, + @QueryParam("from") long from, @QueryParam("to") long to) { + String tableName = "IOT_PER_DEVICE_STREAM_GEO_ALERTNOTIFICATIONS"; + String fromDate = String.valueOf(from); + String toDate = String.valueOf(to); + String query = "id:" + deviceId + " AND type:" + deviceType; + if (from != 0 || to != 0) { + query += " AND timeStamp : [" + fromDate + " TO " + toDate + "]"; + } + try { + if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized( + new DeviceIdentifier(deviceId, deviceType), + DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) { + return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); + } + List sortByFields = new ArrayList<>(); + SortByField sortByField = new SortByField("timeStamp", SortType.ASC); + sortByFields.add(sortByField); + + // this is the user who initiates the request + String authorizedUser = MultitenantUtils.getTenantAwareUsername( + CarbonContext.getThreadLocalCarbonContext().getUsername()); + + try { + String tenantDomain = MultitenantUtils.getTenantDomain(authorizedUser); + int tenantId = DeviceMgtAPIUtils.getRealmService().getTenantManager().getTenantId(tenantDomain); + AnalyticsDataAPI analyticsDataAPI = DeviceMgtAPIUtils.getAnalyticsDataAPI(); + List searchResults = analyticsDataAPI.search(tenantId, tableName, query, + 0, + 100, + sortByFields); + List events = getEventBeans(analyticsDataAPI, tenantId, tableName, new ArrayList(), + searchResults); + return Response.ok().entity(events).build(); + } catch (AnalyticsException | UserStoreException e) { + log.error("Failed to perform search on table: " + tableName + " : " + e.getMessage(), e); + throw DeviceMgtUtil.buildBadRequestException( + Constants.ErrorMessages.STATUS_BAD_REQUEST_MESSAGE_DEFAULT); + } + } catch (DeviceAccessAuthorizationException e) { + log.error(e.getErrorMessage()); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build(); + } + } + + private List getEventBeans(AnalyticsDataAPI analyticsDataAPI, int tenantId, String tableName, + List columns, + List searchResults) throws AnalyticsException { + List ids = getIds(searchResults); + List requiredColumns = (columns == null || columns.isEmpty()) ? null : columns; + AnalyticsDataResponse response = analyticsDataAPI.get(tenantId, tableName, 1, requiredColumns, ids); + List records = AnalyticsDataAPIUtil.listRecords(analyticsDataAPI, response); + Map eventBeanMap = getEventBeanKeyedWithIds(records); + return getSortedEventBeans(eventBeanMap, searchResults); + } + + private List getSortedEventBeans(Map eventBeanMap, + List searchResults) { + List sortedRecords = new ArrayList<>(); + for (SearchResultEntry entry : searchResults) { + sortedRecords.add(eventBeanMap.get(entry.getId())); + } + return sortedRecords; + } + + private Map getEventBeanKeyedWithIds(List records) { + Map eventBeanMap = new HashMap<>(); + for (Record record : records) { + Event event = getEventBean(record); + eventBeanMap.put(event.getId(), event); + } + return eventBeanMap; + } + + private List getIds(List searchResults) { + List ids = new ArrayList<>(); + if (searchResults != null) { + for (SearchResultEntry resultEntry : searchResults) { + ids.add(resultEntry.getId()); + } + } + return ids; + } + + private static Event getEventBean(Record record) { + Event eventBean = new Event(); + eventBean.setId(record.getId()); + eventBean.setTableName(record.getTableName()); + eventBean.setTimestamp(record.getTimestamp()); + eventBean.setValues(record.getValues()); + return eventBean; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImpl.java new file mode 100644 index 0000000000..49f0b4ad76 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImpl.java @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ + +package org.wso2.carbon.device.mgt.jaxrs.service.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.CarbonConstants; +import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceNotFoundException; +import org.wso2.carbon.device.mgt.common.GroupPaginationRequest; +import org.wso2.carbon.device.mgt.common.PaginationResult; +import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup; +import org.wso2.carbon.device.mgt.common.group.mgt.GroupAlreadyExistException; +import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException; +import org.wso2.carbon.device.mgt.common.group.mgt.RoleDoesNotExistException; +import org.wso2.carbon.device.mgt.common.group.mgt.GroupNotExistException; +import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService; +import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceGroupList; +import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceList; +import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceToGroupsAssignment; +import org.wso2.carbon.device.mgt.jaxrs.beans.RoleList; +import org.wso2.carbon.device.mgt.jaxrs.service.api.GroupManagementService; +import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; + +import javax.ws.rs.core.Response; +import java.util.ArrayList; +import java.util.List; + +public class GroupManagementServiceImpl implements GroupManagementService { + + private static final Log log = LogFactory.getLog(GroupManagementServiceImpl.class); + + private static final String DEFAULT_ADMIN_ROLE = "admin"; + private static final String[] DEFAULT_ADMIN_PERMISSIONS = {"/permission/device-mgt/admin/groups", + "/permission/device-mgt/user/groups"}; + + @Override + public Response getGroups(String name, String owner, int offset, int limit) { + try { + RequestValidationUtil.validatePaginationParameters(offset, limit); + String currentUser = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + GroupPaginationRequest request = new GroupPaginationRequest(offset, limit); + request.setGroupName(name); + request.setOwner(owner); + PaginationResult deviceGroupsResult = DeviceMgtAPIUtils.getGroupManagementProviderService() + .getGroups(currentUser, request); + DeviceGroupList deviceGroupList = new DeviceGroupList(); + if (deviceGroupsResult.getData() != null && deviceGroupsResult.getRecordsTotal() > 0) { + deviceGroupList.setList(deviceGroupsResult.getData()); + deviceGroupList.setCount(deviceGroupsResult.getRecordsTotal()); + } else { + deviceGroupList.setList(new ArrayList<>()); + deviceGroupList.setCount(0); + } + return Response.status(Response.Status.OK).entity(deviceGroupList).build(); + } catch (GroupManagementException e) { + String error = "Error occurred while getting the groups."; + log.error(error, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build(); + } + } + + @Override + public Response getGroupCount() { + try { + String currentUser = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + int count = DeviceMgtAPIUtils.getGroupManagementProviderService().getGroupCount(currentUser); + return Response.status(Response.Status.OK).entity(count).build(); + } catch (GroupManagementException e) { + String msg = "Error occurred while retrieving group count."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @Override + public Response createGroup(DeviceGroup group) { + String owner = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + if (group == null) { + return Response.status(Response.Status.BAD_REQUEST).build(); + } + group.setOwner(owner); + try { + DeviceMgtAPIUtils.getGroupManagementProviderService().createGroup(group, DEFAULT_ADMIN_ROLE, DEFAULT_ADMIN_PERMISSIONS); + return Response.status(Response.Status.CREATED).build(); + } catch (GroupManagementException e) { + String msg = "Error occurred while adding new group."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (GroupAlreadyExistException e) { + String msg = "Group already exists with name " + group.getName() + "."; + log.warn(msg); + return Response.status(Response.Status.CONFLICT).entity(msg).build(); + } + } + + @Override + public Response getGroup(int groupId) { + try { + GroupManagementProviderService service = DeviceMgtAPIUtils.getGroupManagementProviderService(); + DeviceGroup deviceGroup = service.getGroup(groupId); + if (deviceGroup != null) { + return Response.status(Response.Status.OK).entity(deviceGroup).build(); + } else { + return Response.status(Response.Status.NOT_FOUND).build(); + } + } catch (GroupManagementException e) { + String error = "Error occurred while getting the group."; + log.error(error, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build(); + } + } + + @Override + public Response updateGroup(int groupId, DeviceGroup deviceGroup) { + if (deviceGroup == null) { + return Response.status(Response.Status.BAD_REQUEST).build(); + } + try { + DeviceMgtAPIUtils.getGroupManagementProviderService().updateGroup(deviceGroup, groupId); + return Response.status(Response.Status.OK).build(); + } catch (GroupManagementException e) { + String msg = "Error occurred while adding new group."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (GroupNotExistException e) { + String msg = "There is another group already exists with name '" + deviceGroup.getName() + "'."; + log.warn(msg); + return Response.status(Response.Status.CONFLICT).entity(msg).build(); + } + } + + @Override + public Response deleteGroup(int groupId) { + try { + if (DeviceMgtAPIUtils.getGroupManagementProviderService().deleteGroup(groupId)) { + return Response.status(Response.Status.OK).build(); + } else { + return Response.status(Response.Status.NOT_FOUND).entity("Group not found.").build(); + } + } catch (GroupManagementException e) { + String msg = "Error occurred while deleting the group."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @Override + public Response manageGroupSharing(int groupId, List userRoles) { + try { + DeviceMgtAPIUtils.getGroupManagementProviderService() + .manageGroupSharing(groupId, userRoles); + return Response.status(Response.Status.OK).build(); + } catch (GroupManagementException e) { + String msg = "Error occurred while managing group share. "; + if (e.getErrorMessage() != null){ + msg += e.getErrorMessage(); + } + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (RoleDoesNotExistException e) { + return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build(); + } + } + + @Override + public Response getRolesOfGroup(int groupId) { + try { + List groupRoles = DeviceMgtAPIUtils.getGroupManagementProviderService().getRoles(groupId); + RoleList deviceGroupRolesList = new RoleList(); + if(groupRoles != null) { + deviceGroupRolesList.setList(groupRoles); + deviceGroupRolesList.setCount(groupRoles.size()); + } else { + deviceGroupRolesList.setList(new ArrayList<>()); + deviceGroupRolesList.setCount(0); + } + return Response.status(Response.Status.OK).entity(deviceGroupRolesList).build(); + } catch (GroupManagementException e) { + String msg = "Error occurred while getting roles of the group."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @Override + public Response getDevicesOfGroup(int groupId, int offset, int limit) { + try { + GroupManagementProviderService service = DeviceMgtAPIUtils.getGroupManagementProviderService(); + List deviceList = service.getDevices(groupId, offset, limit); + int deviceCount = service.getDeviceCount(groupId); + DeviceList deviceListWrapper = new DeviceList(); + if (deviceList != null) { + deviceListWrapper.setList(deviceList); + } else { + deviceListWrapper.setList(new ArrayList<>()); + } + deviceListWrapper.setCount(deviceCount); + return Response.status(Response.Status.OK).entity(deviceListWrapper).build(); + } catch (GroupManagementException e) { + String msg = "Error occurred while getting devices the group."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @Override + public Response getDeviceCountOfGroup(int groupId) { + try { + int count = DeviceMgtAPIUtils.getGroupManagementProviderService().getDeviceCount(groupId); + return Response.status(Response.Status.OK).entity(count).build(); + } catch (GroupManagementException e) { + String msg = "Error occurred while getting device count of the group."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @Override + public Response addDevicesToGroup(int groupId, List deviceIdentifiers) { + try { + DeviceMgtAPIUtils.getGroupManagementProviderService().addDevices(groupId, deviceIdentifiers); + return Response.status(Response.Status.OK).build(); + } catch (GroupManagementException e) { + String msg = "Error occurred while adding devices to group."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (DeviceNotFoundException e) { + return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build(); + } + } + + @Override + public Response removeDevicesFromGroup(int groupId, List deviceIdentifiers) { + try { + DeviceMgtAPIUtils.getGroupManagementProviderService().removeDevice(groupId, deviceIdentifiers); + return Response.status(Response.Status.OK).build(); + } catch (GroupManagementException e) { + String msg = "Error occurred while removing devices from group."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (DeviceNotFoundException e) { + return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build(); + } + } + + @Override + public Response updateDeviceAssigningToGroups(DeviceToGroupsAssignment deviceToGroupsAssignment) { + try { + List deviceIdentifiers = new ArrayList<>(); + deviceIdentifiers.add(deviceToGroupsAssignment.getDeviceIdentifier()); + GroupManagementProviderService service = DeviceMgtAPIUtils.getGroupManagementProviderService(); + List deviceGroups = service.getGroups(deviceToGroupsAssignment.getDeviceIdentifier()); + for (DeviceGroup group : deviceGroups) { + Integer groupId = group.getGroupId(); + if (deviceToGroupsAssignment.getDeviceGroupIds().contains(groupId)) { + deviceToGroupsAssignment.getDeviceGroupIds().remove(groupId); + } else if (!CarbonConstants.REGISTRY_SYSTEM_USERNAME.equals(group.getOwner())) { + DeviceMgtAPIUtils.getGroupManagementProviderService().removeDevice(groupId, deviceIdentifiers); + } + } + for (int groupId : deviceToGroupsAssignment.getDeviceGroupIds()) { + DeviceMgtAPIUtils.getGroupManagementProviderService().addDevices(groupId, deviceIdentifiers); + } + return Response.status(Response.Status.OK).build(); + } catch (GroupManagementException e) { + String msg = "Error occurred while assigning device to groups."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } catch (DeviceNotFoundException e) { + return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build(); + } + } + + @Override + public Response getGroups(String deviceId, String deviceType) { + try { + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(deviceId, deviceType); + List deviceGroups = DeviceMgtAPIUtils.getGroupManagementProviderService().getGroups(deviceIdentifier); + return Response.status(Response.Status.OK).entity(deviceGroups).build(); + } catch (GroupManagementException e) { + String msg = "Error occurred while getting groups of device."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + +} \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/NotificationManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/NotificationManagementServiceImpl.java new file mode 100644 index 0000000000..8e2322cd0a --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/NotificationManagementServiceImpl.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.common.PaginationRequest; +import org.wso2.carbon.device.mgt.common.PaginationResult; +import org.wso2.carbon.device.mgt.common.notification.mgt.Notification; +import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementException; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.beans.NotificationList; +import org.wso2.carbon.device.mgt.jaxrs.service.api.NotificationManagementService; +import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; +import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.UnexpectedServerErrorException; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Size; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.util.List; + +@Path("/notifications") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class NotificationManagementServiceImpl implements NotificationManagementService { + + private static final Log log = LogFactory.getLog(NotificationManagementServiceImpl.class); + + @GET + @Override + public Response getNotifications( + @QueryParam("status") @Size(max = 45) String status, + @HeaderParam("If-Modified-Since") String ifModifiedSince, + @QueryParam("offset") int offset, @QueryParam("limit") int limit) { + + RequestValidationUtil.validatePaginationParameters(offset, limit); + PaginationRequest request = new PaginationRequest(offset, limit); + PaginationResult result; + + NotificationList notificationList = new NotificationList(); + + String msg; + try { + if (status != null) { + RequestValidationUtil.validateNotificationStatus(status); + result = DeviceMgtAPIUtils.getNotificationManagementService().getNotificationsByStatus( + Notification.Status.valueOf(status), request); + } else { + result = DeviceMgtAPIUtils.getNotificationManagementService().getAllNotifications(request); + } + notificationList.setCount(result.getRecordsTotal()); + notificationList.setNotifications((List) result.getData()); + return Response.status(Response.Status.OK).entity(notificationList).build(); + } catch (NotificationManagementException e) { + msg = "Error occurred while retrieving notification list"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + @PUT + @Path("/{id}/mark-checked") + public Response updateNotificationStatus(@PathParam("id") @Max(45)int id) { + String msg; + Notification.Status status = Notification.Status.CHECKED; + Notification notification; + try { + DeviceMgtAPIUtils.getNotificationManagementService().updateNotificationStatus(id, status); + } catch (NotificationManagementException e) { + msg = "Error occurred while updating notification status."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + try { + notification = DeviceMgtAPIUtils.getNotificationManagementService().getNotification(id); + return Response.status(Response.Status.OK).entity(notification).build(); + } catch (NotificationManagementException e) { + msg = "Notification updated successfully. But the retrial of the updated notification failed"; + log.error(msg, e); + return Response.status(Response.Status.OK).entity(msg).build(); + } + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/PolicyManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/PolicyManagementServiceImpl.java new file mode 100644 index 0000000000..01dd4880c1 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/PolicyManagementServiceImpl.java @@ -0,0 +1,401 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException; +import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService; +import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.beans.PolicyList; +import org.wso2.carbon.device.mgt.jaxrs.beans.PolicyWrapper; +import org.wso2.carbon.device.mgt.jaxrs.beans.PriorityUpdatedPolicyWrapper; +import org.wso2.carbon.device.mgt.jaxrs.service.api.PolicyManagementService; +import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.FilteringUtil; +import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtUtil; +import org.wso2.carbon.device.mgt.common.policy.mgt.Policy; +import org.wso2.carbon.policy.mgt.common.PolicyAdministratorPoint; +import org.wso2.carbon.policy.mgt.common.PolicyManagementException; +import org.wso2.carbon.policy.mgt.core.PolicyManagerService; + +import javax.validation.Valid; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; + +@Path("/policies") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class PolicyManagementServiceImpl implements PolicyManagementService { + + private static final String API_BASE_PATH = "/policies"; + private static final Log log = LogFactory.getLog(PolicyManagementServiceImpl.class); + + @POST + @Override + public Response addPolicy(@Valid PolicyWrapper policyWrapper) { + RequestValidationUtil.validatePolicyDetails(policyWrapper); + PolicyManagerService policyManagementService = DeviceMgtAPIUtils.getPolicyManagementService(); + + try { + Policy policy = this.getPolicyFromWrapper(policyWrapper); + + List devices = policy.getDevices(); + if (devices != null && devices.size() == 1) { + DeviceAccessAuthorizationService deviceAccessAuthorizationService = + DeviceManagementDataHolder.getInstance().getDeviceAccessAuthorizationService(); + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(devices.get(0).getDeviceIdentifier(), + devices.get(0).getType()); + PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + String username = threadLocalCarbonContext.getUsername(); + try { + if (!deviceAccessAuthorizationService.isUserAuthorized(deviceIdentifier, username)) { + return Response.status(Response.Status.UNAUTHORIZED).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage + ("Current logged in user is not authorized to add policies").build()).build(); + } + } catch (DeviceAccessAuthorizationException e) { + String msg = "Error occurred while checking if the current user is authorized to add a policy"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + PolicyAdministratorPoint pap = policyManagementService.getPAP(); + Policy createdPolicy = pap.addPolicy(policy); + + return Response.created(new URI(API_BASE_PATH + "/" + createdPolicy.getId())).entity(createdPolicy).build(); + } catch (PolicyManagementException e) { + String msg = "Error occurred while adding policy"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()).build(); + } catch (DeviceManagementException e) { + String msg = "Error occurred while retrieving device list."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()).build(); + } catch (URISyntaxException e) { + String msg = "Error occurred while composing the location URI, which represents information of the " + + "newly created policy"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + private Policy getPolicyFromWrapper(@Valid PolicyWrapper policyWrapper) throws DeviceManagementException { + Policy policy = new Policy(); + policy.setPolicyName(policyWrapper.getPolicyName()); + policy.setDescription(policyWrapper.getDescription()); + policy.setProfile(DeviceMgtUtil.convertProfile(policyWrapper.getProfile())); + policy.setOwnershipType(policyWrapper.getOwnershipType()); + policy.setActive(policyWrapper.isActive()); + policy.setRoles(policyWrapper.getRoles()); + policy.setUsers(policyWrapper.getUsers()); + policy.setCompliance(policyWrapper.getCompliance()); + policy.setDeviceGroups(policyWrapper.getDeviceGroups()); + //TODO iterates the device identifiers to create the object. need to implement a proper DAO layer here. + List devices = new ArrayList(); + List deviceIdentifiers = policyWrapper.getDeviceIdentifiers(); + if (deviceIdentifiers != null) { + for (DeviceIdentifier id : deviceIdentifiers) { + devices.add(DeviceMgtAPIUtils.getDeviceManagementService().getDevice(id, false)); + } + } + policy.setDevices(devices); + policy.setTenantId(PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId()); + return policy; + } + + @GET + @Override + public Response getPolicies( + @HeaderParam("If-Modified-Since") String ifModifiedSince, + @QueryParam("offset") int offset, + @QueryParam("limit") int limit) { + RequestValidationUtil.validatePaginationParameters(offset, limit); + PolicyManagerService policyManagementService = DeviceMgtAPIUtils.getPolicyManagementService(); + List policies; + List filteredPolicies; + PolicyList targetPolicies = new PolicyList(); + try { + PolicyAdministratorPoint policyAdministratorPoint = policyManagementService.getPAP(); + policies = policyAdministratorPoint.getPolicies(); + targetPolicies.setCount(policies.size()); + filteredPolicies = FilteringUtil.getFilteredList(policies, offset, limit); + targetPolicies.setList(filteredPolicies); + } catch (PolicyManagementException e) { + String msg = "Error occurred while retrieving all available policies"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + + return Response.status(Response.Status.OK).entity(targetPolicies).build(); + } + + @GET + @Path("/{id}") + @Override + public Response getPolicy(@PathParam("id") int id, @HeaderParam("If-Modified-Since") String ifModifiedSince) { + PolicyManagerService policyManagementService = DeviceMgtAPIUtils.getPolicyManagementService(); + final Policy policy; + try { + PolicyAdministratorPoint policyAdministratorPoint = policyManagementService.getPAP(); + policy = policyAdministratorPoint.getPolicy(id); + if (policy == null) { + return Response.status(Response.Status.NOT_FOUND).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage( + "No policy found with the id '" + id + "'").build()).build(); + } + } catch (PolicyManagementException e) { + String msg = "Error occurred while retrieving policy corresponding to the id '" + id + "'"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + return Response.status(Response.Status.OK).entity(policy).build(); + } + + @PUT + @Path("/{id}") + @Override + public Response updatePolicy(@PathParam("id") int id, @Valid PolicyWrapper policyWrapper) { + RequestValidationUtil.validatePolicyDetails(policyWrapper); + PolicyManagerService policyManagementService = DeviceMgtAPIUtils.getPolicyManagementService(); + try { + Policy policy = this.getPolicyFromWrapper(policyWrapper); + policy.setId(id); + PolicyAdministratorPoint pap = policyManagementService.getPAP(); + Policy existingPolicy = pap.getPolicy(id); + if (existingPolicy == null) { + return Response.status(Response.Status.NOT_FOUND).entity("Policy not found.").build(); + } + pap.updatePolicy(policy); + return Response.status(Response.Status.OK).entity("Policy has successfully been updated.").build(); + } catch (PolicyManagementException e) { + String msg = "Error occurred while updating the policy"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (DeviceManagementException e) { + String msg = "Error occurred while retrieving the device list."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + @POST + @Path("/remove-policy") + @Override + public Response removePolicies(List policyIds) { + RequestValidationUtil.validatePolicyIds(policyIds); + PolicyManagerService policyManagementService = DeviceMgtAPIUtils.getPolicyManagementService(); + boolean policyDeleted = true; + String invalidPolicyIds = ""; + try { + PolicyAdministratorPoint pap = policyManagementService.getPAP(); + for (int i : policyIds) { + Policy policy = pap.getPolicy(i); + if (policy == null) { + invalidPolicyIds += i + ","; + policyDeleted = false; + } + } + if (policyDeleted) { + for (int i : policyIds) { + Policy policy = pap.getPolicy(i); + pap.deletePolicy(policy); + } + } + } catch (PolicyManagementException e) { + String msg = "ErrorResponse occurred while removing policies"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + if (policyDeleted) { + return Response.status(Response.Status.OK).entity("Policies have been successfully " + + "deleted").build(); + } else { + //TODO:Check of this logic is correct + String modifiedInvalidPolicyIds = + invalidPolicyIds.substring(0, invalidPolicyIds.length() - 1); + return Response.status(Response.Status.BAD_REQUEST). + entity(new ErrorResponse.ErrorResponseBuilder(). + setMessage("Policies with the policy ID " + modifiedInvalidPolicyIds + + " doesn't exist").build()).build(); + } + } + + @POST + @Path("/activate-policy") + @Override + public Response activatePolicies(List policyIds) { + RequestValidationUtil.validatePolicyIds(policyIds); + boolean isPolicyActivated = false; + try { + PolicyManagerService policyManagementService = DeviceMgtAPIUtils.getPolicyManagementService(); + PolicyAdministratorPoint pap = policyManagementService.getPAP(); + for (int i : policyIds) { + Policy policy = pap.getPolicy(i); + if (policy != null) { + pap.activatePolicy(i); + isPolicyActivated = true; + } + } + } catch (PolicyManagementException e) { + String msg = "Error occurred while activating policies"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()).build(); + } + if (isPolicyActivated) { + return Response.status(Response.Status.OK).entity("Selected policies have been successfully activated") + .build(); + } else { + return Response.status(Response.Status.NOT_FOUND).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage("Selected policies have " + + "not been activated").build()).build(); + } + } + + @POST + @Path("/deactivate-policy") + @Override + public Response deactivatePolicies(List policyIds) { + RequestValidationUtil.validatePolicyIds(policyIds); + boolean isPolicyDeActivated = false; + try { + PolicyManagerService policyManagementService = DeviceMgtAPIUtils.getPolicyManagementService(); + PolicyAdministratorPoint pap = policyManagementService.getPAP(); + for (int i : policyIds) { + Policy policy = pap.getPolicy(i); + if (policy != null) { + pap.inactivatePolicy(i); + isPolicyDeActivated = true; + } + } + } catch (PolicyManagementException e) { + String msg = "Exception in inactivating policies."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + if (isPolicyDeActivated) { + return Response.status(Response.Status.OK).entity("Selected policies have been successfully " + + "deactivated").build(); + } else { + return Response.status(Response.Status.NOT_FOUND).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage("Selected policies have " + + "not been deactivated").build()).build(); + } + } + + @Override + @PUT + @Produces("application/json") + @Path("apply-changes") + public Response applyChanges() { + try { + PolicyManagerService policyManagementService = DeviceMgtAPIUtils.getPolicyManagementService(); + PolicyAdministratorPoint pap = policyManagementService.getPAP(); + pap.publishChanges(); + } catch (PolicyManagementException e) { + String msg = "Exception in applying changes."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()).build(); + } + return Response.status(Response.Status.OK).entity("Changes have been successfully updated.").build(); + } + + @PUT + @Path("/priorities") + public Response updatePolicyPriorities(List priorityUpdatedPolicies) { + PolicyManagerService policyManagementService = DeviceMgtAPIUtils.getPolicyManagementService(); + List policiesToUpdate = new ArrayList<>(priorityUpdatedPolicies.size()); + + for (PriorityUpdatedPolicyWrapper priorityUpdatedPolicy : priorityUpdatedPolicies) { + Policy policyObj = new Policy(); + policyObj.setId(priorityUpdatedPolicy.getId()); + policyObj.setPriorityId(priorityUpdatedPolicy.getPriority()); + policiesToUpdate.add(policyObj); + } + boolean policiesUpdated; + try { + PolicyAdministratorPoint pap = policyManagementService.getPAP(); + policiesUpdated = pap.updatePolicyPriorities(policiesToUpdate); + } catch (PolicyManagementException e) { + String error = "Exception in updating policy priorities."; + log.error(error, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(error).build()).build(); + } + if (policiesUpdated) { + return Response.status(Response.Status.OK).entity("Policy Priorities successfully " + + "updated.").build(); + + } else { + return Response.status(Response.Status.NOT_FOUND).entity( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Policy priorities did " + + "not update. Bad Request.").build()).build(); + } + } + + @GET + @Path("/effective-policy/{deviceType}/{deviceId}") + @Override + public Response getEffectivePolicy(@PathParam("deviceType") String deviceType, @PathParam("deviceId") String deviceId) { + PolicyManagerService policyManagementService = DeviceMgtAPIUtils.getPolicyManagementService(); + final Policy policy; + try { + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); + deviceIdentifier.setId(deviceId); + deviceIdentifier.setType(deviceType); + policy = policyManagementService.getAppliedPolicyToDevice(deviceIdentifier); + if (policy == null) { + return Response.status(Response.Status.NOT_FOUND).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage( + "No policy found for device ID '" + deviceId + "'"+ deviceId).build()).build(); + } + } catch (PolicyManagementException e) { + String msg = "Error occurred while retrieving policy corresponding to the id '" + deviceType + "'"+ deviceId; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + return Response.status(Response.Status.OK).entity(policy).build(); + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/RemoteSessionServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/RemoteSessionServiceImpl.java new file mode 100644 index 0000000000..a972df9826 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/RemoteSessionServiceImpl.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.service.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager; +import org.wso2.carbon.device.mgt.core.config.DeviceManagementConfig; +import org.wso2.carbon.device.mgt.core.config.remote.session.RemoteSessionConfiguration; +import org.wso2.carbon.device.mgt.jaxrs.beans.RemoteSessionInfo; +import org.wso2.carbon.device.mgt.jaxrs.service.api.RemoteSessionService; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Response; + +/** + * The api for + */ +public class RemoteSessionServiceImpl implements RemoteSessionService { + + private static Log log = LogFactory.getLog(RemoteSessionServiceImpl.class); + + @Path("connect/{deviceType}/{deviceId}") + @GET + @Consumes("application/json") + @Produces("application/json") + public Response getRemoteSessionDeviceConnect(@PathParam("deviceId") String deviceId, + @PathParam("deviceType") String deviceType) { + //First, check whether the remote session is enabled. + RemoteSessionInfo sessionInfo = new RemoteSessionInfo(); + sessionInfo.setEnabled(false); + DeviceManagementConfig deviceManagementConfig = DeviceConfigurationManager.getInstance() + .getDeviceManagementConfig(); + if (deviceManagementConfig != null) { + RemoteSessionConfiguration remoteSessionConfiguration = deviceManagementConfig.getRemoteSessionConfiguration(); + if (remoteSessionConfiguration != null) { + boolean isEnabled = remoteSessionConfiguration.isEnabled(); + sessionInfo.setEnabled(isEnabled); + if (isEnabled) { + sessionInfo.setServerUrl(remoteSessionConfiguration.getRemoteSessionServerUrl()); + } + return Response.ok().entity(sessionInfo).build(); + } + } + + return Response.ok().entity(sessionInfo).build(); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/RoleManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/RoleManagementServiceImpl.java new file mode 100644 index 0000000000..978b449885 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/RoleManagementServiceImpl.java @@ -0,0 +1,660 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.CarbonConstants; +import org.wso2.carbon.base.MultitenantConstants; +import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.context.RegistryType; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.beans.RoleInfo; +import org.wso2.carbon.device.mgt.jaxrs.beans.RoleList; +import org.wso2.carbon.device.mgt.jaxrs.service.api.RoleManagementService; +import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.FilteringUtil; +import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; +import org.wso2.carbon.device.mgt.jaxrs.util.SetReferenceTransformer; +import org.wso2.carbon.registry.api.Registry; +import org.wso2.carbon.registry.core.session.UserRegistry; +import org.wso2.carbon.registry.resource.services.utils.ChangeRolePermissionsUtil; +import org.wso2.carbon.user.api.*; +import org.wso2.carbon.user.core.common.AbstractUserStoreManager; +import org.wso2.carbon.user.mgt.UserRealmProxy; +import org.wso2.carbon.user.mgt.common.UIPermissionNode; +import org.wso2.carbon.user.mgt.common.UserAdminException; + +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URLEncoder; +import java.util.*; + +import static org.wso2.carbon.device.mgt.jaxrs.util.Constants.PRIMARY_USER_STORE; + +@Path("/roles") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class RoleManagementServiceImpl implements RoleManagementService { + + private static final String API_BASE_PATH = "/roles"; + private static final Log log = LogFactory.getLog(RoleManagementServiceImpl.class); + + @GET + @Override + public Response getRoles( + @QueryParam("filter") String filter, + @QueryParam("user-store") String userStore, + @HeaderParam("If-Modified-Since") String ifModifiedSince, + @QueryParam("offset") int offset, @QueryParam("limit") int limit) { + RequestValidationUtil.validatePaginationParameters(offset, limit); + if (limit == 0){ + limit = Constants.DEFAULT_PAGE_LIMIT; + } + List filteredRoles; + RoleList targetRoles = new RoleList(); + + //if user store is null set it to primary + if (userStore == null || "".equals(userStore)) { + userStore = PRIMARY_USER_STORE; + } + + try { + //Get the total role count that matches the given filter + filteredRoles = getRolesFromUserStore(filter, userStore); + targetRoles.setCount(filteredRoles.size()); + + filteredRoles = FilteringUtil.getFilteredList(getRolesFromUserStore(filter, userStore), offset, limit); + targetRoles.setList(filteredRoles); + + return Response.ok().entity(targetRoles).build(); + } catch (UserStoreException e) { + String msg = "Error occurred while retrieving roles from the underlying user stores"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + @GET + @Path("/filter/{prefix}") + @Override + public Response getFilteredRoles( + @PathParam("prefix") String prefix, + @QueryParam("filter") String filter, + @QueryParam("user-store") String userStore, + @HeaderParam("If-Modified-Since") String ifModifiedSince, + @QueryParam("offset") int offset, @QueryParam("limit") int limit) { + RequestValidationUtil.validatePaginationParameters(offset, limit); + List finalRoleList; + RoleList targetRoles = new RoleList(); + + //if user store is null set it to primary + if (userStore == null || "".equals(userStore)) { + userStore = PRIMARY_USER_STORE; + } + + try { + + //Get the total role count that matches the given filter + List filteredRoles = getRolesFromUserStore(filter, userStore); + finalRoleList = new ArrayList(); + + filteredRoles = FilteringUtil.getFilteredList(getRolesFromUserStore(filter, userStore), offset, limit); + for (String rolename : filteredRoles){ + if (rolename.startsWith(prefix)){ + finalRoleList.add(rolename); + } + } + targetRoles.setCount(finalRoleList.size()); + targetRoles.setList(finalRoleList); + + return Response.ok().entity(targetRoles).build(); + } catch (UserStoreException e) { + String msg = "Error occurred while retrieving roles from the underlying user stores"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + @GET + @Path("/{roleName}/permissions") + @Override + public Response getPermissionsOfRole(@PathParam("roleName") String roleName, + @QueryParam("user-store") String userStoreName, + @HeaderParam("If-Modified-Since") String ifModifiedSince) { + if (userStoreName != null && !userStoreName.isEmpty()) { + roleName = userStoreName + "/" + roleName; + } + RequestValidationUtil.validateRoleName(roleName); + try { + final UserRealm userRealm = DeviceMgtAPIUtils.getUserRealm(); + if (!userRealm.getUserStoreManager().isExistingRole(roleName)) { + return Response.status(404).entity(new ErrorResponse.ErrorResponseBuilder().setMessage( + "No role exists with the name '" + roleName + "'").build()).build(); + } + + final UIPermissionNode rolePermissions = this.getUIPermissionNode(roleName, userRealm); + if (rolePermissions == null) { + if (log.isDebugEnabled()) { + log.debug("No permissions found for the role '" + roleName + "'"); + } + } + return Response.status(Response.Status.OK).entity(rolePermissions).build(); + } catch (UserAdminException e) { + String msg = "Error occurred while retrieving the permissions of role '" + roleName + "'"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (UserStoreException e) { + String msg = "Error occurred while retrieving the underlying user realm attached to the " + + "current logged in user"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + private UIPermissionNode getAllRolePermissions(String roleName, UserRealm userRealm) throws UserAdminException { + org.wso2.carbon.user.core.UserRealm userRealmCore = null; + if (userRealm instanceof org.wso2.carbon.user.core.UserRealm) { + userRealmCore = (org.wso2.carbon.user.core.UserRealm) userRealm; + } + final UserRealmProxy userRealmProxy = new UserRealmProxy(userRealmCore); + final UIPermissionNode rolePermissions = + userRealmProxy.getRolePermissions(roleName, MultitenantConstants.SUPER_TENANT_ID); + return rolePermissions; + } + + private UIPermissionNode getUIPermissionNode(String roleName, UserRealm userRealm) + throws UserAdminException { + org.wso2.carbon.user.core.UserRealm userRealmCore = null; + if (userRealm instanceof org.wso2.carbon.user.core.UserRealm) { + userRealmCore = (org.wso2.carbon.user.core.UserRealm) userRealm; + } + final UserRealmProxy userRealmProxy = new UserRealmProxy(userRealmCore); + final UIPermissionNode rolePermissions = + userRealmProxy.getRolePermissions(roleName, MultitenantConstants.SUPER_TENANT_ID); + UIPermissionNode[] deviceMgtPermissions = new UIPermissionNode[4]; + + for (UIPermissionNode permissionNode : rolePermissions.getNodeList()) { + if (permissionNode.getResourcePath().equals("/permission/admin")) { + for (UIPermissionNode node : permissionNode.getNodeList()) { + if (node.getResourcePath().equals("/permission/admin/device-mgt")) { + deviceMgtPermissions[0] = node; + } else if (node.getResourcePath().equals("/permission/admin/login")) { + deviceMgtPermissions[1] = node; + } else if (node.getResourcePath().equals("/permission/admin/manage")) { + // Adding permissions related to app-store in emm-console + for (UIPermissionNode subNode : node.getNodeList()) { + if (subNode.getResourcePath().equals("/permission/admin/manage/mobileapp")) { + deviceMgtPermissions[2] = subNode; + } else if (subNode.getResourcePath().equals("/permission/admin/manage/webapp")) { + deviceMgtPermissions[3] = subNode; + } + } + } + } + } + } + rolePermissions.setNodeList(deviceMgtPermissions); + return rolePermissions; + } + + @GET + @Path("/{roleName}") + @Override + public Response getRole(@PathParam("roleName") String roleName, @QueryParam("user-store") String userStoreName, + @HeaderParam("If-Modified-Since") String ifModifiedSince) { + if (log.isDebugEnabled()) { + log.debug("Getting the list of user roles"); + } + if (userStoreName != null && !userStoreName.isEmpty()) { + roleName = userStoreName + "/" + roleName; + } + RequestValidationUtil.validateRoleName(roleName); + RoleInfo roleInfo = new RoleInfo(); + try { + final UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager(); + final UserRealm userRealm = DeviceMgtAPIUtils.getUserRealm(); + if (!userStoreManager.isExistingRole(roleName)) { + return Response.status(404).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage("No role exists with the name '" + + roleName + "'").build()).build(); + } + roleInfo.setRoleName(roleName); + roleInfo.setUsers(userStoreManager.getUserListOfRole(roleName)); + // Get the permission nodes and hand picking only device management and login perms + final UIPermissionNode rolePermissions = this.getUIPermissionNode(roleName, userRealm); + List permList = new ArrayList<>(); + this.iteratePermissions(rolePermissions, permList); + roleInfo.setPermissionList(rolePermissions); + String[] permListAr = new String[permList.size()]; + roleInfo.setPermissions(permList.toArray(permListAr)); + + return Response.status(Response.Status.OK).entity(roleInfo).build(); + } catch (UserStoreException | UserAdminException e) { + String msg = "Error occurred while retrieving the user role '" + roleName + "'"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + private List iteratePermissions(UIPermissionNode uiPermissionNode, List list) { + for (UIPermissionNode permissionNode : uiPermissionNode.getNodeList()) { + list.add(permissionNode.getResourcePath()); + if (permissionNode.getNodeList() != null && permissionNode.getNodeList().length > 0) { + iteratePermissions(permissionNode, list); + } + } + return list; + } + + + private List getAuthorizedPermissions(UIPermissionNode uiPermissionNode, List list) { + for (UIPermissionNode permissionNode : uiPermissionNode.getNodeList()) { + if (permissionNode.isSelected()) { + list.add(permissionNode.getResourcePath()); + } + if (permissionNode.getNodeList() != null && permissionNode.getNodeList().length > 0) { + getAuthorizedPermissions(permissionNode, list); + } + } + return list; + } + + @POST + @Override + public Response addRole(RoleInfo roleInfo) { + RequestValidationUtil.validateRoleDetails(roleInfo); + RequestValidationUtil.validateRoleName(roleInfo.getRoleName()); + try { + UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager(); + if (log.isDebugEnabled()) { + log.debug("Persisting the role in the underlying user store"); + } + Permission[] permissions = null; + if (roleInfo.getPermissions() != null && roleInfo.getPermissions().length > 0) { + permissions = new Permission[roleInfo.getPermissions().length]; + for (int i = 0; i < permissions.length; i++) { + String permission = roleInfo.getPermissions()[i]; + permissions[i] = new Permission(permission, CarbonConstants.UI_PERMISSION_ACTION); + } + } + userStoreManager.addRole(roleInfo.getRoleName(), roleInfo.getUsers(), permissions); + authorizeRoleForAppmgt(roleInfo.getRoleName(), roleInfo.getPermissions()); + + //TODO fix what's returned in the entity + return Response.created(new URI(API_BASE_PATH + "/" + URLEncoder.encode(roleInfo.getRoleName(), "UTF-8"))). + entity("Role '" + roleInfo.getRoleName() + "' has " + "successfully been" + + " added").build(); + } catch (UserStoreException e) { + String msg = "Error occurred while adding role '" + roleInfo.getRoleName() + "'"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (URISyntaxException e) { + String msg = "Error occurred while composing the URI at which the information of the newly created role " + + "can be retrieved"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (UnsupportedEncodingException e) { + String msg = "Error occurred while encoding role name"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + @POST + @Path("/create-combined-role/{roleName}") + @Override + public Response addCombinedRole(List roles, @PathParam("roleName") String roleName, + @QueryParam("user-store") String userStoreName) { + if (userStoreName != null && !userStoreName.isEmpty()) { + roleName = userStoreName + "/" + roleName; + } + if (roles.size() < 2) { + return Response.status(400).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage("Combining Roles requires at least two roles.") + .build() + ).build(); + } + for (String role : roles) { + RequestValidationUtil.validateRoleName(role); + } + try { + UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager(); + if (log.isDebugEnabled()) { + log.debug("Persisting the role in the underlying user store"); + } + + HashSet permsSet = new HashSet<>(); + try { + for (String role : roles) { + mergePermissions(new UIPermissionNode[]{getRolePermissions(role)}, permsSet); + } + } catch (IllegalArgumentException e) { + return Response.status(404).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(e.getMessage()).build() + ).build(); + } + + Permission[] permissions = permsSet.toArray(new Permission[permsSet.size()]); + userStoreManager.addRole(roleName, new String[0], permissions); + + //TODO fix what's returned in the entity + return Response.created(new URI(API_BASE_PATH + "/" + URLEncoder.encode(roleName, "UTF-8"))). + entity("Role '" + roleName + "' has " + "successfully been" + + " added").build(); + } catch (UserAdminException e) { + String msg = "Error occurred while retrieving the permissions of role '" + roleName + "'"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (UserStoreException e) { + String msg = "Error occurred while adding role '" + roleName + "'"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (URISyntaxException e) { + String msg = "Error occurred while composing the URI at which the information of the newly created role " + + "can be retrieved"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (UnsupportedEncodingException e) { + String msg = "Error occurred while encoding role name"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + @PUT + @Path("/{roleName}") + @Override + public Response updateRole(@PathParam("roleName") String roleName, RoleInfo roleInfo, + @QueryParam("user-store") String userStoreName) { + if (userStoreName != null && !userStoreName.isEmpty()) { + roleName = userStoreName + "/" + roleName; + } + RequestValidationUtil.validateRoleName(roleName); + RequestValidationUtil.validateRoleDetails(roleInfo); + try { + final UserRealm userRealm = DeviceMgtAPIUtils.getUserRealm(); + final UserStoreManager userStoreManager = userRealm.getUserStoreManager(); + if (!userStoreManager.isExistingRole(roleName)) { + return Response.status(404).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage("No role exists with the name '" + + roleName + "'").build()).build(); + } + + final AuthorizationManager authorizationManager = userRealm.getAuthorizationManager(); + if (log.isDebugEnabled()) { + log.debug("Updating the role to user store"); + } + + String newRoleName = roleInfo.getRoleName(); + if (newRoleName != null && !roleName.equals(newRoleName)) { + userStoreManager.updateRoleName(roleName, newRoleName); + } + + if (roleInfo.getUsers() != null) { + SetReferenceTransformer transformer = new SetReferenceTransformer<>(); + transformer.transform(Arrays.asList(userStoreManager.getUserListOfRole(newRoleName)), + Arrays.asList(roleInfo.getUsers())); + final String[] usersToAdd = transformer.getObjectsToAdd().toArray(new String[transformer + .getObjectsToAdd().size()]); + final String[] usersToDelete = transformer.getObjectsToRemove().toArray(new String[transformer + .getObjectsToRemove().size()]); + userStoreManager.updateUserListOfRole(newRoleName, usersToDelete, usersToAdd); + } + + if (roleInfo.getPermissions() != null) { + // Get all role permissions + final UIPermissionNode rolePermissions = this.getAllRolePermissions(roleName, userRealm); + List permissions = new ArrayList(); + final UIPermissionNode emmRolePermissions = (UIPermissionNode) this.getRolePermissions(roleName); + List emmConsolePermissions = new ArrayList(); + this.getAuthorizedPermissions(emmRolePermissions, emmConsolePermissions); + emmConsolePermissions.removeAll(new ArrayList(Arrays.asList(roleInfo.getPermissions()))); + this.getAuthorizedPermissions(rolePermissions, permissions); + for (String permission : roleInfo.getPermissions()) { + permissions.add(permission); + } + permissions.removeAll(emmConsolePermissions); + String[] allApplicablePerms = new String[permissions.size()]; + allApplicablePerms = permissions.toArray(allApplicablePerms); + roleInfo.setPermissions(allApplicablePerms); + + // Delete all authorizations for the current role before authorizing the permission tree + authorizationManager.clearRoleAuthorization(roleName); + if (roleInfo.getPermissions().length > 0) { + for (int i = 0; i < roleInfo.getPermissions().length; i++) { + String permission = roleInfo.getPermissions()[i]; + authorizationManager.authorizeRole(roleName, permission, CarbonConstants.UI_PERMISSION_ACTION); + } + } + authorizeRoleForAppmgt(roleName, roleInfo.getPermissions()); + } + //TODO: Need to send the updated role information in the entity back to the client + return Response.status(Response.Status.OK).entity("Role '" + roleInfo.getRoleName() + "' has " + + "successfully been updated").build(); + } catch (UserStoreException e) { + String msg = "Error occurred while updating role '" + roleName + "'"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (UserAdminException e) { + String msg = "Error occurred while updating permissions of the role '" + roleName + "'"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + /** + * When presented with role and a set of permissions, if given role has permission to + * perform mobile app management, said role will be given rights mobile app collection in the + * governance registry. + * + * @param role + * @param permissions + * @return state of role update Operation + */ + private boolean authorizeRoleForAppmgt(String role, String[] permissions) { + String permissionString = + "ra^true:rd^false:wa^true:wd^false:da^true:dd^false:aa^true:ad^false"; + String resourcePath = "/_system/governance/mobileapps/"; + boolean appmPermAvailable = false; + + if (permissions != null) { + for (int i = 0; i < permissions.length; i++) + switch (permissions[i]) { + case "/permission/admin/manage/mobileapp": + appmPermAvailable = true; + break; + case "/permission/admin/manage/mobileapp/create": + appmPermAvailable = true; + break; + case "/permission/admin/manage/mobileapp/publish": + appmPermAvailable = true; + break; + } + } + + if (appmPermAvailable) { + try { + Registry registry = CarbonContext.getThreadLocalCarbonContext(). + getRegistry(RegistryType.SYSTEM_GOVERNANCE); + ChangeRolePermissionsUtil.changeRolePermissions((UserRegistry) registry, + resourcePath, role + ":" + permissionString); + + return true; + } catch (Exception e) { + String msg = "Error while retrieving user registry in order to update permissions " + + "for resource : " + resourcePath; + log.error(msg, e); + return false; + } + } else { + if (log.isDebugEnabled()) { + log.debug("Mobile App Management permissions not selected, therefore role : " + + role + " not given permission for registry collection : " + resourcePath); + } + return false; + } + } + + @DELETE + @Path("/{roleName}") + @Override + public Response deleteRole(@PathParam("roleName") String roleName, @QueryParam("user-store") String userStoreName) { + if (userStoreName != null && !userStoreName.isEmpty()) { + roleName = userStoreName + "/" + roleName; + } + RequestValidationUtil.validateRoleName(roleName); + try { + final UserRealm userRealm = DeviceMgtAPIUtils.getUserRealm(); + final UserStoreManager userStoreManager = userRealm.getUserStoreManager(); + if (!userStoreManager.isExistingRole(roleName)) { + return Response.status(404).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage("No role exists with the name '" + + roleName + "'").build()).build(); + } + + final AuthorizationManager authorizationManager = userRealm.getAuthorizationManager(); + if (log.isDebugEnabled()) { + log.debug("Deleting the role in user store"); + } + userStoreManager.deleteRole(roleName); + // Delete all authorizations for the current role before deleting + authorizationManager.clearRoleAuthorization(roleName); + + return Response.status(Response.Status.OK).build(); + } catch (UserStoreException e) { + String msg = "Error occurred while deleting the role '" + roleName + "'"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + @PUT + @Path("/{roleName}/users") + @Override + public Response updateUsersOfRole(@PathParam("roleName") String roleName, + @QueryParam("user-store") String userStoreName, List users) { + if (userStoreName != null && !userStoreName.isEmpty()) { + roleName = userStoreName + "/" + roleName; + } + RequestValidationUtil.validateRoleName(roleName); + RequestValidationUtil.validateUsers(users); + try { + final UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager(); + if (log.isDebugEnabled()) { + log.debug("Updating the users of a role"); + } + SetReferenceTransformer transformer = new SetReferenceTransformer<>(); + transformer.transform(Arrays.asList(userStoreManager.getUserListOfRole(roleName)), + users); + final String[] usersToAdd = transformer.getObjectsToAdd().toArray(new String[transformer + .getObjectsToAdd().size()]); + final String[] usersToDelete = transformer.getObjectsToRemove().toArray(new String[transformer + .getObjectsToRemove().size()]); + + userStoreManager.updateUserListOfRole(roleName, usersToDelete, usersToAdd); + + return Response.status(Response.Status.OK).entity("Role '" + roleName + "' has " + + "successfully been updated with the user list") + .build(); + } catch (UserStoreException e) { + String msg = "Error occurred while updating the users of the role '" + roleName + "'"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + private List getRolesFromUserStore(String filter, String userStore) throws UserStoreException { + AbstractUserStoreManager userStoreManager = (AbstractUserStoreManager) DeviceMgtAPIUtils.getUserStoreManager(); + String[] roles; + boolean filterRolesByName = (!((filter == null) || filter.isEmpty())); + if (log.isDebugEnabled()) { + log.debug("Getting the list of user roles"); + } + if (userStore.equals("all")) { + roles = userStoreManager.getRoleNames("*", -1, false, true, true); + } else { + roles = userStoreManager.getRoleNames(userStore + "/*", -1, false, true, true); + } + // removing all internal roles, roles created for Service-providers and application related roles. + List filteredRoles = new ArrayList<>(); + for (String role : roles) { + if (!(role.startsWith("Internal/") || role.startsWith("Authentication/") || role.startsWith( + "Application/"))) { + if (!filterRolesByName) { + filteredRoles.add(role); + } else { + if (role.contains(filter)) { + filteredRoles.add(role); + } + } + } + } + return filteredRoles; + } + + private Set mergePermissions(UIPermissionNode[] permissionNodes, Set permissions) + throws UserStoreException, UserAdminException { + for (UIPermissionNode permissionNode : permissionNodes) { + if (permissionNode.getNodeList().length > 0) { + mergePermissions(permissionNode.getNodeList(), permissions); + } + if (permissionNode.isSelected()) { + permissions.add(new Permission(permissionNode.getResourcePath(), CarbonConstants.UI_PERMISSION_ACTION)); + } + } + return permissions; + } + + private UIPermissionNode getRolePermissions(String roleName) throws UserStoreException, UserAdminException { + final UserRealm userRealm = DeviceMgtAPIUtils.getUserRealm(); + if (!userRealm.getUserStoreManager().isExistingRole(roleName)) { + throw new IllegalArgumentException("No role exists with the name '" + roleName + "'"); + } + + final UIPermissionNode rolePermissions = this.getUIPermissionNode(roleName, userRealm); + if (rolePermissions == null) { + if (log.isDebugEnabled()) { + log.debug("No permissions found for the role '" + roleName + "'"); + } + } + return rolePermissions; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java new file mode 100644 index 0000000000..25794c833b --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImpl.java @@ -0,0 +1,697 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.impl; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.eclipse.wst.common.uriresolver.internal.util.URIEncoder; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.EnrolmentInfo; +import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException; +import org.wso2.carbon.device.mgt.core.DeviceManagementConstants; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.device.mgt.core.service.EmailMetaInfo; +import org.wso2.carbon.device.mgt.jaxrs.beans.BasicUserInfo; +import org.wso2.carbon.device.mgt.jaxrs.beans.BasicUserInfoList; +import org.wso2.carbon.device.mgt.jaxrs.beans.BasicUserInfoWrapper; +import org.wso2.carbon.device.mgt.jaxrs.beans.EnrollmentInvitation; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.beans.OldPasswordResetWrapper; +import org.wso2.carbon.device.mgt.jaxrs.beans.RoleList; +import org.wso2.carbon.device.mgt.jaxrs.beans.UserInfo; +import org.wso2.carbon.device.mgt.jaxrs.service.api.UserManagementService; +import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; +import org.wso2.carbon.device.mgt.jaxrs.util.CredentialManagementResponseBuilder; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; +import org.wso2.carbon.identity.user.store.count.UserStoreCountRetriever; +import org.wso2.carbon.identity.user.store.count.exception.UserStoreCounterException; +import org.wso2.carbon.user.api.Permission; +import org.wso2.carbon.user.api.RealmConfiguration; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.api.UserStoreManager; +import org.wso2.carbon.utils.CarbonUtils; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.io.File; +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +@Path("/users") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class UserManagementServiceImpl implements UserManagementService { + + private static final String ROLE_EVERYONE = "Internal/everyone"; + private static final String API_BASE_PATH = "/users"; + private static final Log log = LogFactory.getLog(UserManagementServiceImpl.class); + + private static final String DEFAULT_DEVICE_USER = "Internal/devicemgt-user"; + + // Permissions that are given for a normal device user. + private static final Permission[] PERMISSIONS_FOR_DEVICE_USER = { + new Permission("/permission/admin/Login", "ui.execute"), + new Permission("/permission/admin/device-mgt/device/api/subscribe", "ui.execute"), + new Permission("/permission/admin/device-mgt/devices/enroll", "ui.execute"), + new Permission("/permission/admin/device-mgt/devices/disenroll", "ui.execute"), + new Permission("/permission/admin/device-mgt/devices/owning-device/view", "ui.execute"), + new Permission("/permission/admin/manage/portal", "ui.execute") + }; + + @POST + @Override + public Response addUser(UserInfo userInfo) { + try { + UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager(); + if (userStoreManager.isExistingUser(userInfo.getUsername())) { + // if user already exists + if (log.isDebugEnabled()) { + log.debug("User by username: " + userInfo.getUsername() + + " already exists. Therefore, request made to add user was refused."); + } + // returning response with bad request state + return Response.status(Response.Status.CONFLICT).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage("User by username: " + + userInfo.getUsername() + " already exists. Therefore, request made to add user " + + "was refused.").build()).build(); + } + + String initialUserPassword = this.generateInitialUserPassword(); + Map defaultUserClaims = + this.buildDefaultUserClaims(userInfo.getFirstname(), userInfo.getLastname(), + userInfo.getEmailAddress()); + // calling addUser method of carbon user api + List tmpRoles = new ArrayList<>(); + String[] userInfoRoles = userInfo.getRoles(); + tmpRoles.add(DEFAULT_DEVICE_USER); + if (userInfoRoles != null) { + tmpRoles.addAll(Arrays.asList(userInfoRoles)); + } + String[] roles = new String[tmpRoles.size()]; + tmpRoles.toArray(roles); + + // If the normal device user role does not exist, create a new role with the minimal permissions + if (!userStoreManager.isExistingRole(DEFAULT_DEVICE_USER)) { + userStoreManager.addRole(DEFAULT_DEVICE_USER, null, PERMISSIONS_FOR_DEVICE_USER); + } + + userStoreManager.addUser(userInfo.getUsername(), initialUserPassword, + roles, defaultUserClaims, null); + // Outputting debug message upon successful addition of user + if (log.isDebugEnabled()) { + log.debug("User '" + userInfo.getUsername() + "' has successfully been added."); + } + + BasicUserInfo createdUserInfo = this.getBasicUserInfo(userInfo.getUsername()); + // Outputting debug message upon successful retrieval of user + if (log.isDebugEnabled()) { + log.debug("User by username: " + userInfo.getUsername() + " was found."); + } + DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService(); + String[] bits = userInfo.getUsername().split("/"); + String username = bits[bits.length - 1]; + String recipient = userInfo.getEmailAddress(); + Properties props = new Properties(); + props.setProperty("first-name", userInfo.getFirstname()); + props.setProperty("username", username); + props.setProperty("password", initialUserPassword); + + EmailMetaInfo metaInfo = new EmailMetaInfo(recipient, props); + BasicUserInfoWrapper userInfoWrapper = new BasicUserInfoWrapper(); + String message; + try { + dms.sendRegistrationEmail(metaInfo); + message = "An invitation mail will be sent to this user to initiate device enrollment."; + } catch (ConfigurationManagementException e) { + message = "Mail Server is not configured. Email invitation will not be sent."; + } + userInfoWrapper.setBasicUserInfo(createdUserInfo); + userInfoWrapper.setMessage(message); + return Response.created(new URI(API_BASE_PATH + "/" + URIEncoder.encode(userInfo.getUsername(), + "UTF-8"))).entity(userInfoWrapper).build(); + } catch (UserStoreException e) { + String msg = "Error occurred while trying to add user '" + userInfo.getUsername() + "' to the " + + "underlying user management system"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (URISyntaxException e) { + String msg = "Error occurred while composing the location URI, which represents information of the " + + "newly created user '" + userInfo.getUsername() + "'"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (UnsupportedEncodingException e) { + String msg = "Error occurred while encoding username in the URI for the newly created user " + + userInfo.getUsername(); + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (DeviceManagementException e) { + String msg = "Error occurred while sending registration email to the user " + userInfo.getUsername(); + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + @GET + @Path("/{username}") + @Override + public Response getUser(@PathParam("username") String username, @QueryParam("domain") String domain, + @HeaderParam("If-Modified-Since") String ifModifiedSince) { + if (domain != null && !domain.isEmpty()) { + username = domain + '/' + username; + } + try { + UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager(); + if (!userStoreManager.isExistingUser(username)) { + if (log.isDebugEnabled()) { + log.debug("User by username: " + username + " does not exist."); + } + return Response.status(Response.Status.NOT_FOUND).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage( + "User doesn't exist.").build()).build(); + } + + BasicUserInfo user = this.getBasicUserInfo(username); + return Response.status(Response.Status.OK).entity(user).build(); + } catch (UserStoreException e) { + String msg = "Error occurred while retrieving information of the user '" + username + "'"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + @PUT + @Path("/{username}") + @Override + public Response updateUser(@PathParam("username") String username, @QueryParam("domain") String domain, UserInfo userInfo) { + if (domain != null && !domain.isEmpty()) { + username = domain + '/' + username; + } + try { + UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager(); + if (!userStoreManager.isExistingUser(username)) { + if (log.isDebugEnabled()) { + log.debug("User by username: " + username + + " doesn't exists. Therefore, request made to update user was refused."); + } + return Response.status(Response.Status.NOT_FOUND).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage("User by username: " + + username + " doesn't exist.").build()).build(); + } + + Map defaultUserClaims = + this.buildDefaultUserClaims(userInfo.getFirstname(), userInfo.getLastname(), + userInfo.getEmailAddress()); + if (StringUtils.isNotEmpty(userInfo.getPassword())) { + // Decoding Base64 encoded password + userStoreManager.updateCredentialByAdmin(username, + userInfo.getPassword()); + log.debug("User credential of username: " + username + " has been changed"); + } + List currentRoles = this.getFilteredRoles(userStoreManager, username); + + List newRoles = new ArrayList<>(); + if (userInfo.getRoles() != null) { + newRoles = Arrays.asList(userInfo.getRoles()); + } + + List rolesToAdd = new ArrayList<>(newRoles); + List rolesToDelete = new ArrayList<>(); + + for (String role : currentRoles) { + if (newRoles.contains(role)) { + rolesToAdd.remove(role); + } else { + rolesToDelete.add(role); + } + } + rolesToDelete.remove(ROLE_EVERYONE); + rolesToAdd.remove(ROLE_EVERYONE); + userStoreManager.updateRoleListOfUser(username, + rolesToDelete.toArray(new String[rolesToDelete.size()]), + rolesToAdd.toArray(new String[rolesToAdd.size()])); + userStoreManager.setUserClaimValues(username, defaultUserClaims, null); + // Outputting debug message upon successful addition of user + if (log.isDebugEnabled()) { + log.debug("User by username: " + username + " was successfully updated."); + } + + BasicUserInfo updatedUserInfo = this.getBasicUserInfo(username); + return Response.ok().entity(updatedUserInfo).build(); + } catch (UserStoreException e) { + String msg = "Error occurred while trying to update user '" + username + "'"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + private List getFilteredRoles(UserStoreManager userStoreManager, String username) + throws UserStoreException { + String[] roleListOfUser; + roleListOfUser = userStoreManager.getRoleListOfUser(username); + List filteredRoles = new ArrayList<>(); + for (String role : roleListOfUser) { + if (!(role.startsWith("Internal/") || role.startsWith("Authentication/"))) { + filteredRoles.add(role); + } + } + return filteredRoles; + } + + @DELETE + @Path("/{username}") + @Override + public Response removeUser(@PathParam("username") String username, @QueryParam("domain") String domain) { + if (domain != null && !domain.isEmpty()) { + username = domain + '/' + username; + } + try { + UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager(); + if (!userStoreManager.isExistingUser(username)) { + if (log.isDebugEnabled()) { + log.debug("User by username: " + username + " does not exist for removal."); + } + return Response.status(Response.Status.NOT_FOUND).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage("User '" + + username + "' does not exist for removal.").build()).build(); + } + // Un-enroll all devices for the user + DeviceManagementProviderService deviceManagementService = DeviceMgtAPIUtils.getDeviceManagementService(); + deviceManagementService.setStatus(username, EnrolmentInfo.Status.REMOVED); + + userStoreManager.deleteUser(username); + if (log.isDebugEnabled()) { + log.debug("User '" + username + "' was successfully removed."); + } + return Response.status(Response.Status.OK).build(); + } catch (DeviceManagementException | UserStoreException e) { + String msg = "Exception in trying to remove user by username: " + username; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + @GET + @Path("/{username}/roles") + @Override + public Response getRolesOfUser(@PathParam("username") String username, @QueryParam("domain") String domain) { + if (domain != null && !domain.isEmpty()) { + username = domain + '/' + username; + } + try { + UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager(); + if (!userStoreManager.isExistingUser(username)) { + if (log.isDebugEnabled()) { + log.debug("User by username: " + username + " does not exist for role retrieval."); + } + return Response.status(Response.Status.NOT_FOUND).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage("User by username: " + username + + " does not exist for role retrieval.").build()).build(); + } + + RoleList result = new RoleList(); + result.setList(getFilteredRoles(userStoreManager, username)); + return Response.status(Response.Status.OK).entity(result).build(); + } catch (UserStoreException e) { + String msg = "Error occurred while trying to retrieve roles of the user '" + username + "'"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + @GET + @Override + public Response getUsers(@QueryParam("filter") String filter, @HeaderParam("If-Modified-Since") String timestamp, + @QueryParam("offset") int offset, + @QueryParam("limit") int limit) { + if (log.isDebugEnabled()) { + log.debug("Getting the list of users with all user-related information"); + } + + RequestValidationUtil.validatePaginationParameters(offset, limit); + if (limit == 0) { + limit = Constants.DEFAULT_PAGE_LIMIT; + } + List userList, offsetList; + String appliedFilter = ((filter == null) || filter.isEmpty() ? "*" : filter + "*"); + // to get whole set of users, appliedLimit is set to -1 + // by default, this whole set is limited to 100 - MaxUserNameListLength of user-mgt.xml + int appliedLimit = -1; + + try { + UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager(); + + //As the listUsers function accepts limit only to accommodate offset we are passing offset + limit + String[] users = userStoreManager.listUsers(appliedFilter, appliedLimit); + userList = new ArrayList<>(users.length); + BasicUserInfo user; + for (String username : users) { + user = new BasicUserInfo(); + user.setUsername(username); + user.setEmailAddress(getClaimValue(username, Constants.USER_CLAIM_EMAIL_ADDRESS)); + user.setFirstname(getClaimValue(username, Constants.USER_CLAIM_FIRST_NAME)); + user.setLastname(getClaimValue(username, Constants.USER_CLAIM_LAST_NAME)); + userList.add(user); + } + + int toIndex = offset + limit; + int listSize = userList.size(); + int lastIndex = listSize - 1; + + if (offset <= lastIndex) { + if (toIndex <= listSize) { + offsetList = userList.subList(offset, toIndex); + } else { + offsetList = userList.subList(offset, listSize); + } + } else { + offsetList = new ArrayList<>(); + } + BasicUserInfoList result = new BasicUserInfoList(); + result.setList(offsetList); + result.setCount(users.length); + + return Response.status(Response.Status.OK).entity(result).build(); + } catch (UserStoreException e) { + String msg = "Error occurred while retrieving the list of users."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + @GET + @Path("/count") + @Override + public Response getUserCount() { + try { + UserStoreCountRetriever userStoreCountRetrieverService = DeviceMgtAPIUtils.getUserStoreCountRetrieverService(); + RealmConfiguration secondaryRealmConfiguration = DeviceMgtAPIUtils.getUserRealm().getRealmConfiguration() + .getSecondaryRealmConfig(); + + if (secondaryRealmConfiguration != null) { + if (!secondaryRealmConfiguration.isPrimary() && !Constants.JDBC_USERSTOREMANAGER. + equals(secondaryRealmConfiguration.getUserStoreClass().getClass())) { + return getUserCountViaUserStoreManager(); + } + } + if (userStoreCountRetrieverService != null) { + long count = userStoreCountRetrieverService.countUsers(""); + if (count != -1) { + BasicUserInfoList result = new BasicUserInfoList(); + result.setCount(count); + return Response.status(Response.Status.OK).entity(result).build(); + } + } + } catch (UserStoreCounterException e) { + String msg = + "Error occurred while retrieving the count of users that exist within the current tenant"; + log.error(msg, e); + } catch (UserStoreException e) { + String msg = + "Error occurred while retrieving user stores."; + log.error(msg, e); + } + return getUserCountViaUserStoreManager(); + } + + /** + * This method returns the count of users using UserStoreManager. + * + * @return user count + */ + private Response getUserCountViaUserStoreManager() { + if (log.isDebugEnabled()) { + log.debug("Getting the user count"); + } + + try { + UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager(); + int userCount = userStoreManager.listUsers("*", -1).length; + BasicUserInfoList result = new BasicUserInfoList(); + result.setCount(userCount); + return Response.status(Response.Status.OK).entity(result).build(); + } catch (UserStoreException e) { + String msg = "Error occurred while retrieving the user count."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + @GET + @Path("/checkUser") + @Override + public Response isUserExists(@QueryParam("username") String userName) { + try { + UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager(); + if (userStoreManager.isExistingUser(userName)) { + return Response.status(Response.Status.OK).entity(true).build(); + } else { + return Response.status(Response.Status.OK).entity(false).build(); + } + } catch (UserStoreException e) { + String msg = "Error while retrieving the user."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @GET + @Path("/search/usernames") + @Override + public Response getUserNames(@QueryParam("filter") String filter, @QueryParam("domain") String domain, + @HeaderParam("If-Modified-Since") String timestamp, + @QueryParam("offset") int offset, @QueryParam("limit") int limit) { + if (log.isDebugEnabled()) { + log.debug("Getting the list of users with all user-related information using the filter : " + filter); + } + String userStoreDomain = Constants.PRIMARY_USER_STORE; + if (domain != null && !domain.isEmpty()) { + userStoreDomain = domain; + } + if (limit == 0){ + //If there is no limit is passed, then return all. + limit = -1; + } + List userList; + try { + UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager(); + String[] users = userStoreManager.listUsers(userStoreDomain + "/" + filter + "*", limit); + userList = new ArrayList<>(); + UserInfo user; + for (String username : users) { + user = new UserInfo(); + user.setUsername(username); + user.setEmailAddress(getClaimValue(username, Constants.USER_CLAIM_EMAIL_ADDRESS)); + user.setFirstname(getClaimValue(username, Constants.USER_CLAIM_FIRST_NAME)); + user.setLastname(getClaimValue(username, Constants.USER_CLAIM_LAST_NAME)); + userList.add(user); + } + return Response.status(Response.Status.OK).entity(userList).build(); + } catch (UserStoreException e) { + String msg = "Error occurred while retrieving the list of users using the filter : " + filter; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + @PUT + @Path("/credentials") + @Override + public Response resetPassword(OldPasswordResetWrapper credentials) { + return CredentialManagementResponseBuilder.buildChangePasswordResponse(credentials); + } + + /** + * Method used to send an invitation email to a existing user to enroll a device. + * + * @param usernames Username list of the users to be invited + */ + @POST + @Path("/send-invitation") + @Produces({MediaType.APPLICATION_JSON}) + public Response inviteExistingUsersToEnrollDevice(List usernames) { + if (log.isDebugEnabled()) { + log.debug("Sending enrollment invitation mail to existing user."); + } + DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService(); + try { + for (String username : usernames) { + String recipient = getClaimValue(username, Constants.USER_CLAIM_EMAIL_ADDRESS); + + Properties props = new Properties(); + props.setProperty("first-name", getClaimValue(username, Constants.USER_CLAIM_FIRST_NAME)); + props.setProperty("username", username); + + EmailMetaInfo metaInfo = new EmailMetaInfo(recipient, props); + dms.sendEnrolmentInvitation(DeviceManagementConstants.EmailAttributes.USER_ENROLLMENT_TEMPLATE, + metaInfo); + } + } catch (DeviceManagementException e) { + String msg = "Error occurred while inviting user to enrol their device"; + if (e.getMessage() != null && !e.getMessage().isEmpty()) { + msg = e.getMessage(); + } + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (UserStoreException e) { + String msg = "Error occurred while getting claim values to invite user"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (ConfigurationManagementException e) { + String msg = "Error occurred while sending the email invitations. Mail server not configured."; + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + return Response.status(Response.Status.OK).entity("Invitation mails have been sent.").build(); + } + + @POST + @Path("/enrollment-invite") + @Override + public Response inviteToEnrollDevice(EnrollmentInvitation enrollmentInvitation) { + if (log.isDebugEnabled()) { + log.debug("Sending enrollment invitation mail to existing user."); + } + DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService(); + try { + Set recipients = new HashSet<>(); + recipients.addAll(enrollmentInvitation.getRecipients()); + Properties props = new Properties(); + String username = DeviceMgtAPIUtils.getAuthenticatedUser(); + String firstName = getClaimValue(username, Constants.USER_CLAIM_FIRST_NAME); + if (firstName == null) { + firstName = username; + } + props.setProperty("first-name", firstName); + props.setProperty("device-type", enrollmentInvitation.getDeviceType()); + EmailMetaInfo metaInfo = new EmailMetaInfo(recipients, props); + dms.sendEnrolmentInvitation(getEnrollmentTemplateName(enrollmentInvitation.getDeviceType()), metaInfo); + } catch (DeviceManagementException e) { + String msg = "Error occurred while inviting user to enrol their device"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (UserStoreException e) { + String msg = "Error occurred while getting claim values to invite user"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (ConfigurationManagementException e) { + String msg = "Error occurred while sending the email invitations. Mail server not configured."; + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + return Response.status(Response.Status.OK).entity("Invitation mails have been sent.").build(); + } + + private Map buildDefaultUserClaims(String firstName, String lastName, String emailAddress) { + Map defaultUserClaims = new HashMap<>(); + defaultUserClaims.put(Constants.USER_CLAIM_FIRST_NAME, firstName); + defaultUserClaims.put(Constants.USER_CLAIM_LAST_NAME, lastName); + defaultUserClaims.put(Constants.USER_CLAIM_EMAIL_ADDRESS, emailAddress); + if (log.isDebugEnabled()) { + log.debug("Default claim map is created for new user: " + defaultUserClaims.toString()); + } + return defaultUserClaims; + } + + private String generateInitialUserPassword() { + int passwordLength = 6; + //defining the pool of characters to be used for initial password generation + String lowerCaseCharset = "abcdefghijklmnopqrstuvwxyz"; + String upperCaseCharset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + String numericCharset = "0123456789"; + SecureRandom randomGenerator = new SecureRandom(); + String totalCharset = lowerCaseCharset + upperCaseCharset + numericCharset; + int totalCharsetLength = totalCharset.length(); + StringBuilder initialUserPassword = new StringBuilder(); + for (int i = 0; i < passwordLength; i++) { + initialUserPassword.append( + totalCharset.charAt(randomGenerator.nextInt(totalCharsetLength))); + } + if (log.isDebugEnabled()) { + log.debug("Initial user password is created for new user: " + initialUserPassword); + } + return initialUserPassword.toString(); + } + + private BasicUserInfo getBasicUserInfo(String username) throws UserStoreException { + BasicUserInfo userInfo = new BasicUserInfo(); + userInfo.setUsername(username); + userInfo.setEmailAddress(getClaimValue(username, Constants.USER_CLAIM_EMAIL_ADDRESS)); + userInfo.setFirstname(getClaimValue(username, Constants.USER_CLAIM_FIRST_NAME)); + userInfo.setLastname(getClaimValue(username, Constants.USER_CLAIM_LAST_NAME)); + return userInfo; + } + + private String getClaimValue(String username, String claimUri) throws UserStoreException { + UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager(); + return userStoreManager.getUserClaimValue(username, claimUri, null); + } + + private String getEnrollmentTemplateName(String deviceType) { + String templateName = deviceType + "-enrollment-invitation"; + File template = new File(CarbonUtils.getCarbonHome() + File.separator + "repository" + File.separator + + "resources" + File.separator + "email-templates" + File.separator + templateName + + ".vm"); + if (template.exists()) { + return templateName; + } else { + if (log.isDebugEnabled()) { + log.debug("The template that is expected to use is not available. Therefore, using default template."); + } + } + return DeviceManagementConstants.EmailAttributes.DEFAULT_ENROLLMENT_TEMPLATE; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/ApplicationManagementAdminServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/ApplicationManagementAdminServiceImpl.java new file mode 100644 index 0000000000..5141399fa1 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/ApplicationManagementAdminServiceImpl.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.impl.admin; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.Platform; +import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException; +import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager; +import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; +import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.exception.UnknownApplicationTypeException; +import org.wso2.carbon.device.mgt.jaxrs.service.api.admin.ApplicationManagementAdminService; +import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; +import org.wso2.carbon.device.mgt.jaxrs.util.MDMAndroidOperationUtil; +import org.wso2.carbon.device.mgt.jaxrs.util.MDMIOSOperationUtil; +import org.wso2.carbon.device.mgt.jaxrs.beans.ApplicationWrapper; +import org.wso2.carbon.device.mgt.jaxrs.beans.MobileApp; + +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +@Path("/admin/applications") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class ApplicationManagementAdminServiceImpl implements ApplicationManagementAdminService { + + private static final Log log = LogFactory.getLog(ApplicationManagementAdminServiceImpl.class); + + @POST + @Path("/install-application") + @Override + public Response installApplication(ApplicationWrapper applicationWrapper) { + ApplicationManager appManagerConnector; + Operation operation = null; + Activity activity = null; + + RequestValidationUtil.validateApplicationInstallationContext(applicationWrapper); + try { + appManagerConnector = DeviceMgtAPIUtils.getAppManagementService(); + MobileApp mobileApp = applicationWrapper.getApplication(); + + if (applicationWrapper.getDeviceIdentifiers() != null) { + for (DeviceIdentifier deviceIdentifier : applicationWrapper.getDeviceIdentifiers()) { + String deviceType = deviceIdentifier.getType().toUpperCase(); + if (Platform.ANDROID.toString().equals(deviceType)) { + operation = MDMAndroidOperationUtil.createInstallAppOperation(mobileApp); + } else if (Platform.IOS.toString().equals(deviceType)) { + operation = MDMIOSOperationUtil.createInstallAppOperation(mobileApp); + } + } + if (applicationWrapper.getRoleNameList() != null && applicationWrapper.getRoleNameList().size() > 0) { + activity = appManagerConnector.installApplicationForUserRoles(operation, applicationWrapper.getRoleNameList()); + } else if (applicationWrapper.getUserNameList() != null && + applicationWrapper.getUserNameList().size() > 0) { + activity = appManagerConnector.installApplicationForUsers(operation, applicationWrapper.getUserNameList()); + } else if (applicationWrapper.getDeviceIdentifiers() != null && + applicationWrapper.getDeviceIdentifiers().size() > 0) { + activity = appManagerConnector.installApplicationForDevices(operation, applicationWrapper.getDeviceIdentifiers()); + } else { + return Response.status(Response.Status.BAD_REQUEST).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage( + "No application installation criteria i.e. user/role/device is given").build()).build(); + } + } + return Response.status(Response.Status.ACCEPTED).entity(activity).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while processing application installation request"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (UnknownApplicationTypeException e) { + String msg = "The type of application requested to be installed is not supported"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + @POST + @Path("/uninstall-application") + @Override + public Response uninstallApplication(ApplicationWrapper applicationWrapper) { + ApplicationManager appManagerConnector; + org.wso2.carbon.device.mgt.common.operation.mgt.Operation operation = null; + Activity activity = null; + + RequestValidationUtil.validateApplicationInstallationContext(applicationWrapper); + try { + appManagerConnector = DeviceMgtAPIUtils.getAppManagementService(); + MobileApp mobileApp = applicationWrapper.getApplication(); + + if (applicationWrapper.getDeviceIdentifiers() != null) { + for (DeviceIdentifier deviceIdentifier : applicationWrapper.getDeviceIdentifiers()) { + String deviceType = deviceIdentifier.getType().toUpperCase(); + if (Platform.ANDROID.toString().equals(deviceType)) { + operation = MDMAndroidOperationUtil.createAppUninstallOperation(mobileApp); + } else if (deviceType.equals(Platform.IOS.toString())) { + operation = MDMIOSOperationUtil.createAppUninstallOperation(mobileApp); + } + } + if (applicationWrapper.getRoleNameList() != null && applicationWrapper.getRoleNameList().size() > 0) { + activity = appManagerConnector.installApplicationForUserRoles(operation, applicationWrapper.getRoleNameList()); + } else if (applicationWrapper.getUserNameList() != null && + applicationWrapper.getUserNameList().size() > 0) { + activity = appManagerConnector.installApplicationForUsers(operation, applicationWrapper.getUserNameList()); + } else if (applicationWrapper.getDeviceIdentifiers() != null && + applicationWrapper.getDeviceIdentifiers().size() > 0) { + activity = appManagerConnector.installApplicationForDevices(operation, applicationWrapper.getDeviceIdentifiers()); + } else { + return Response.status(Response.Status.BAD_REQUEST).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage( + "No application un-installation criteria i.e. user/role/device is given").build()).build(); + } + } + return Response.status(Response.Status.ACCEPTED).entity(activity).build(); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while processing application un-installation request"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (UnknownApplicationTypeException e) { + String msg = "The type of application requested to be un-installed is not supported"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceAccessAuthorizationAdminServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceAccessAuthorizationAdminServiceImpl.java new file mode 100644 index 0000000000..035caa3a18 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceAccessAuthorizationAdminServiceImpl.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.impl.admin; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.base.MultitenantConstants; +import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException; +import org.wso2.carbon.device.mgt.common.authorization.DeviceAuthorizationResult; +import org.wso2.carbon.device.mgt.jaxrs.beans.AuthorizationRequest; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.service.api.admin.DeviceAccessAuthorizationAdminService; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; + +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.util.ArrayList; +import java.util.List; + +@Path("/admin/authorization") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class DeviceAccessAuthorizationAdminServiceImpl implements DeviceAccessAuthorizationAdminService { + + private static final Log log = LogFactory.getLog(DeviceAccessAuthorizationAdminServiceImpl.class); + private static final String DEFAULT_STAT_PERMISSION = "/permission/admin/device-mgt/device/realtime_analytics"; + + @POST + @Override + public Response isAuthorized(AuthorizationRequest authorizationRequest) { + int currentTenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId(); + String loggedinUserTenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + if (authorizationRequest.getTenantDomain() != null) { + if (!loggedinUserTenantDomain.equals(authorizationRequest.getTenantDomain())) { + if (MultitenantConstants.SUPER_TENANT_ID != currentTenantId) { + return Response.status(Response.Status.UNAUTHORIZED).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage( + "Current logged in user is not authorized to perform this operation").build()) + .build(); + } + } + } else { + authorizationRequest.setTenantDomain(loggedinUserTenantDomain); + } + if (authorizationRequest.getTenantDomain() == null || authorizationRequest.getTenantDomain().isEmpty()) { + authorizationRequest.setTenantDomain( + PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain()); + } + try { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain( + authorizationRequest.getTenantDomain(), true); + String[] permissionArr = null; + if (authorizationRequest.getPermissions() != null && authorizationRequest.getPermissions().size() > 0) { + permissionArr = new String[authorizationRequest.getPermissions().size()]; + permissionArr = authorizationRequest.getPermissions().toArray(permissionArr); + } + DeviceAuthorizationResult deviceAuthorizationResult = + DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized( + authorizationRequest.getDeviceIdentifiers(), authorizationRequest.getUsername() + , permissionArr); + + return Response.status(Response.Status.OK).entity(deviceAuthorizationResult).build(); + } catch (DeviceAccessAuthorizationException e) { + String msg = "Error occurred at server side while fetching authorization information."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + } + + @POST + @Path("/stat") + @Override + public Response isAuthorizedForStat(AuthorizationRequest authorizationRequest) { + List permissions = new ArrayList<>(); + permissions.add(DEFAULT_STAT_PERMISSION); + authorizationRequest.setPermissions(permissions); + return isAuthorized(authorizationRequest); + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceAnalyticsArtifactUploaderAdminServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceAnalyticsArtifactUploaderAdminServiceImpl.java new file mode 100644 index 0000000000..c6325a4ec7 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceAnalyticsArtifactUploaderAdminServiceImpl.java @@ -0,0 +1,505 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.impl.admin; + +import org.apache.axis2.AxisFault; +import org.apache.axis2.client.Options; +import org.apache.axis2.client.Stub; +import org.apache.axis2.java.security.SSLProtocolSocketFactory; +import org.apache.axis2.transport.http.HTTPConstants; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.httpclient.Header; +import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.wso2.carbon.application.mgt.stub.upload.CarbonAppUploaderStub; +import org.wso2.carbon.application.mgt.stub.upload.types.carbon.UploadedFileItem; +import org.wso2.carbon.base.ServerConfiguration; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.core.util.Utils; +import org.wso2.carbon.device.mgt.jaxrs.service.api.admin.DeviceAnalyticsArtifactUploaderAdminService; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; +import org.wso2.carbon.identity.jwt.client.extension.JWTClient; +import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; +import org.wso2.carbon.registry.core.exceptions.RegistryException; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.utils.CarbonUtils; +import org.wso2.carbon.event.receiver.stub.EventReceiverAdminServiceStub; +import org.wso2.carbon.event.stream.stub.EventStreamAdminServiceStub; +import org.wso2.carbon.utils.multitenancy.MultitenantConstants; + +import javax.activation.DataHandler; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.core.Response; +import java.io.*; +import java.nio.file.Files; +import java.rmi.RemoteException; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.util.ArrayList; +import java.util.List; + +@Path("/admin/publish-artifact") +public class DeviceAnalyticsArtifactUploaderAdminServiceImpl implements DeviceAnalyticsArtifactUploaderAdminService { + + /** + * required soap header for authorization + */ + private static final String AUTHORIZATION_HEADER = "Authorization"; + + /** + * required soap header value for mutualSSL + */ + private static final String AUTHORIZATION_HEADER_VALUE = "Bearer"; + + private static final String KEY_STORE_TYPE = "JKS"; + /** + * Default truststore type of the client + */ + private static final String TRUST_STORE_TYPE = "JKS"; + /** + * Default keymanager type of the client + */ + private static final String KEY_MANAGER_TYPE = "SunX509"; //Default Key Manager Type + /** + * Default trustmanager type of the client + */ + private static final String TRUST_MANAGER_TYPE = "SunX509"; //Default Trust Manager Type + + private static final String SSLV3 = "SSLv3"; + + + + private KeyStore keyStore; + private KeyStore trustStore; + private char[] keyStorePassword; + private SSLContext sslContext; + + private String tenantDomain; + + private static final Log log = LogFactory.getLog(DeviceAnalyticsArtifactUploaderAdminServiceImpl.class); + private static final String DEFAULT_RESOURCE_LOCATION = "/resources/devicetypes"; + private static final String CAR_FILE_LOCATION = CarbonUtils.getCarbonHome() + File.separator + "repository" + + File.separator + "resources" + File.separator + "devicetypes"; + private static final String DAS_PORT = "${iot.analytics.https.port}"; + private static final String DAS_HOST_NAME = "${iot.analytics.host}"; + private static final String DEFAULT_HTTP_PROTOCOL = "https"; + private static final String IOT_MGT_PORT = "${iot.manager.https.port}"; + private static final String IOT_MGT_HOST_NAME = "${iot.manager.host}"; + private static final String DAS_URL = DEFAULT_HTTP_PROTOCOL + "://" + DAS_HOST_NAME + + ":" + DAS_PORT + "/services/CarbonAppUploader/"; + private static final String DAS_EVENT_RECEIVER_EP = DEFAULT_HTTP_PROTOCOL + "://" + DAS_HOST_NAME + + ":" + DAS_PORT + "/services/EventReceiverAdminService/"; + private static final String DAS_EVENT_STREAM_EP = DEFAULT_HTTP_PROTOCOL + "://" + DAS_HOST_NAME + + ":" + DAS_PORT + "/services/EventStreamAdminService/"; + + private static final String IOT_MGT_URL = DEFAULT_HTTP_PROTOCOL + "://" + IOT_MGT_HOST_NAME + + ":" + IOT_MGT_PORT + "/services/CarbonAppUploader/"; + private static final String MEDIA_TYPE_XML = "application/xml"; + private static final String DEVICE_MANAGEMENT_TYPE = "device_management"; + private static final String TENANT_DOMAIN_PROPERTY = "\\$\\{tenant-domain\\}"; + + + @Override + @POST + @Path("/deploy/{type}") + public Response doPublish(@PathParam("type") String type) { + try { + //Getting the tenant Domain + tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + String tenantAdminUser = username + "@" + tenantDomain; + + String keyStorePassword = ServerConfiguration.getInstance().getFirstProperty("Security.KeyStore.Password"); + String trustStorePassword = ServerConfiguration.getInstance().getFirstProperty( + "Security.TrustStore.Password"); + String keyStoreLocation = ServerConfiguration.getInstance().getFirstProperty("Security.KeyStore.Location"); + String trustStoreLocation = ServerConfiguration.getInstance().getFirstProperty( + "Security.TrustStore.Location"); + + //Call to load the keystore. + loadKeyStore(keyStoreLocation, keyStorePassword); + //Call to load the TrustStore. + loadTrustStore(trustStoreLocation, trustStorePassword); + //Create the SSL context with the loaded TrustStore/keystore. + initSSLConnection(); + JWTClient jwtClient = DeviceMgtAPIUtils.getJWTClientManagerService().getJWTClient(); + + String authValue = AUTHORIZATION_HEADER_VALUE + " " + new String(Base64.encodeBase64( + jwtClient.getJwtToken(tenantAdminUser).getBytes())); + + List
list = new ArrayList<>(); + Header httpHeader = new Header(); + httpHeader.setName(AUTHORIZATION_HEADER); + httpHeader.setValue(authValue); + list.add(httpHeader);//"https" + + List streamFileList = getStreamsList(type); + List receiverFileList = getReceiversList(type); + + if (!tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) { + if (streamFileList != null) { + publishDynamicEventStream(type, MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, streamFileList); + } + if (receiverFileList != null) { + publishDynamicEventReceivers(type, MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, receiverFileList); + } + } + if (streamFileList != null) { + publishDynamicEventStream(type, tenantDomain, streamFileList); + } + if (deployAnalyticsCapp(type, list)){ + return Response.status(Response.Status.BAD_REQUEST) + .entity("\"Error, Artifact does not exist.\"").build(); + } + if (receiverFileList != null) { + publishDynamicEventReceivers(type, tenantDomain, receiverFileList); + } + return Response.status(Response.Status.CREATED).entity("\"OK. \\n Successfully uploaded the artifacts.\"") + .build(); + } catch (AxisFault e) { + log.error("failed to publish event definitions for tenantDomain:" + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (RemoteException e) { + log.error("Failed to connect with the remote services:" + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (JWTClientException e) { + log.error("Failed to generate jwt token for tenantDomain:" + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (UserStoreException e) { + log.error("Failed to connect with the user store, tenantDomain: " + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (CertificateException | UnrecoverableKeyException | KeyStoreException | + KeyManagementException | IOException | NoSuchAlgorithmException e) { + log.error("Failed to access keystore for, tenantDomain: " + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (RegistryException e) { + log.error("Failed to load tenant, tenantDomain: " + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } catch (ParseException e) { + log.error("Invalid stream definition for device type" + type + " for tenant, tenantDomain: " + tenantDomain, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); + } + } + + private boolean deployAnalyticsCapp(@PathParam("type") String type, List
list) throws IOException, RegistryException { + CarbonAppUploaderStub carbonAppUploaderStub = null; + try { + File directory = new File(CAR_FILE_LOCATION + File.separator + type); + if (directory.isDirectory() && directory.exists()) { + UploadedFileItem[] uploadedFileItems = loadCappFromFileSystem(type); + if (uploadedFileItems.length > 0) { + if (DEVICE_MANAGEMENT_TYPE.equals(type.toLowerCase())) { + carbonAppUploaderStub = new CarbonAppUploaderStub(Utils.replaceSystemProperty( + IOT_MGT_URL)); + Options appUploaderOptions = carbonAppUploaderStub._getServiceClient().getOptions(); + if (appUploaderOptions == null) { + appUploaderOptions = new Options(); + } + appUploaderOptions.setProperty(HTTPConstants.HTTP_HEADERS, list); + appUploaderOptions.setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER + , new Protocol(DEFAULT_HTTP_PROTOCOL, + (ProtocolSocketFactory) new SSLProtocolSocketFactory + (sslContext), Integer.parseInt(Utils.replaceSystemProperty( + IOT_MGT_PORT)))); + + carbonAppUploaderStub._getServiceClient().setOptions(appUploaderOptions); + carbonAppUploaderStub.uploadApp(uploadedFileItems); + } else { + carbonAppUploaderStub = new CarbonAppUploaderStub(Utils.replaceSystemProperty(DAS_URL)); + Options appUploaderOptions = carbonAppUploaderStub._getServiceClient().getOptions(); + if (appUploaderOptions == null) { + appUploaderOptions = new Options(); + } + appUploaderOptions.setProperty(HTTPConstants.HTTP_HEADERS, list); + appUploaderOptions.setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER + , new Protocol(DEFAULT_HTTP_PROTOCOL + , (ProtocolSocketFactory) new SSLProtocolSocketFactory(sslContext) + , Integer.parseInt(Utils.replaceSystemProperty(DAS_PORT)))); + + carbonAppUploaderStub._getServiceClient().setOptions(appUploaderOptions); + carbonAppUploaderStub.uploadApp(uploadedFileItems); + } + } + } else { + return true; + } + return false; + } finally { + cleanup(carbonAppUploaderStub); + } + } + + private void publishDynamicEventReceivers(String deviceType, String tenantDomain, List receiversList) + throws IOException, UserStoreException, JWTClientException { + + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true); + EventReceiverAdminServiceStub receiverAdminServiceStub = null; + try { + receiverAdminServiceStub = new EventReceiverAdminServiceStub + (Utils.replaceSystemProperty(DAS_EVENT_RECEIVER_EP)); + Options eventReciverOptions = receiverAdminServiceStub._getServiceClient().getOptions(); + if (eventReciverOptions == null) { + eventReciverOptions = new Options(); + } + String username; + if(!tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) { + username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() + .getRealmConfiguration().getAdminUserName()+"@"+tenantDomain; + }else { + username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() + .getRealmConfiguration().getAdminUserName(); + } + + + JWTClient jwtClient = DeviceMgtAPIUtils.getJWTClientManagerService().getJWTClient(); + + String authValue = AUTHORIZATION_HEADER_VALUE + " " + new String(Base64.encodeBase64( + jwtClient.getJwtToken(username).getBytes())); + + List
list = new ArrayList<>(); + Header httpHeader = new Header(); + httpHeader.setName(AUTHORIZATION_HEADER); + httpHeader.setValue(authValue); + list.add(httpHeader);//"https" + + eventReciverOptions.setProperty(HTTPConstants.HTTP_HEADERS, list); + eventReciverOptions.setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER + , new Protocol(DEFAULT_HTTP_PROTOCOL + , (ProtocolSocketFactory) new SSLProtocolSocketFactory(sslContext) + , Integer.parseInt(Utils.replaceSystemProperty(DAS_PORT)))); + + receiverAdminServiceStub._getServiceClient().setOptions(eventReciverOptions); + for (String receiverContent:receiversList) { + receiverAdminServiceStub.deployEventReceiverConfiguration(receiverContent); + } + } finally { + cleanup(receiverAdminServiceStub); + PrivilegedCarbonContext.endTenantFlow(); + } + } + + private void publishDynamicEventStream(String deviceType, String tenantDomain, List streamList) + throws IOException, UserStoreException, JWTClientException, ParseException { + + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true); + EventStreamAdminServiceStub eventStreamAdminServiceStub = null; + try { + eventStreamAdminServiceStub = new EventStreamAdminServiceStub + (Utils.replaceSystemProperty(DAS_EVENT_STREAM_EP)); + Options eventReciverOptions = eventStreamAdminServiceStub._getServiceClient().getOptions(); + if (eventReciverOptions == null) { + eventReciverOptions = new Options(); + } + String username; + if(!tenantDomain.equals(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)) { + username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() + .getRealmConfiguration().getAdminUserName()+"@"+tenantDomain; + }else { + username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() + .getRealmConfiguration().getAdminUserName(); + } + + + JWTClient jwtClient = DeviceMgtAPIUtils.getJWTClientManagerService().getJWTClient(); + + String authValue = AUTHORIZATION_HEADER_VALUE + " " + new String(Base64.encodeBase64( + jwtClient.getJwtToken(username).getBytes())); + + List
list = new ArrayList<>(); + Header httpHeader = new Header(); + httpHeader.setName(AUTHORIZATION_HEADER); + httpHeader.setValue(authValue); + list.add(httpHeader);//"https" + + eventReciverOptions.setProperty(HTTPConstants.HTTP_HEADERS, list); + eventReciverOptions.setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER + , new Protocol(DEFAULT_HTTP_PROTOCOL + , (ProtocolSocketFactory) new SSLProtocolSocketFactory(sslContext) + , Integer.parseInt(Utils.replaceSystemProperty(DAS_PORT)))); + + eventStreamAdminServiceStub._getServiceClient().setOptions(eventReciverOptions); + for (String streamContent:streamList) { + JSONParser jsonParser = new JSONParser(); + JSONObject steamJson = (JSONObject)jsonParser.parse(streamContent); + String name = (String) steamJson.get("name"); + String version = (String) steamJson.get("version"); + String streamId = name +":"+version; + if (eventStreamAdminServiceStub.getStreamDefinitionDto(streamId) == null) { + eventStreamAdminServiceStub.addEventStreamDefinitionAsString(streamContent); + } + } + } finally { + cleanup(eventStreamAdminServiceStub); + PrivilegedCarbonContext.endTenantFlow(); + } + } + + + private List getReceiversList(String deviceType) throws IOException { + File directory = new File(CAR_FILE_LOCATION + File.separator + deviceType+File.separator+"receiver"); + if (!directory.exists()) { + return null; + } + File[] receiverFiles = directory.listFiles(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return name.toLowerCase().endsWith(".xml"); + } + }); + List receiverList = new ArrayList<>(); + for (File receiverFile:receiverFiles) { + String receiverContentTemplate =new String(Files.readAllBytes(receiverFile.toPath())); + final String receiverContent = receiverContentTemplate.replaceAll(TENANT_DOMAIN_PROPERTY, tenantDomain.toLowerCase()); + receiverList.add(receiverContent); + } + + return receiverList; + } + + private List getStreamsList(String deviceType) throws IOException { + File directory = new File(CAR_FILE_LOCATION + File.separator + deviceType+File.separator+"streams"); + if (!directory.exists()) { + return null; + } + File[] receiverFiles = directory.listFiles(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return name.toLowerCase().endsWith(".json"); + } + }); + List streamList = new ArrayList<>(); + for (File StreamFile:receiverFiles) { + String streamContent =new String(Files.readAllBytes(StreamFile.toPath())); + streamList.add(streamContent); + } + return streamList; + } + + private UploadedFileItem[] loadCappFromFileSystem(String deviceType) throws IOException { + + File directory = new File(CAR_FILE_LOCATION + File.separator + deviceType); + File[] carFiles = directory.listFiles(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return name.toLowerCase().endsWith(".car"); + } + }); + List uploadedFileItemLis = new ArrayList<>(); + if (carFiles != null) { + + for (File carFile : carFiles) { + UploadedFileItem uploadedFileItem = new UploadedFileItem(); + DataHandler param = new DataHandler(carFile.toURI().toURL()); + uploadedFileItem.setDataHandler(param); + uploadedFileItem.setFileName(carFile.getName()); + uploadedFileItem.setFileType("jar"); + uploadedFileItemLis.add(uploadedFileItem); + } + } + UploadedFileItem[] fileItems = new UploadedFileItem[uploadedFileItemLis.size()]; + fileItems = uploadedFileItemLis.toArray(fileItems); + return fileItems; + } + + /** + * Loads the keystore. + * + * @param keyStorePath - the path of the keystore + * @param ksPassword - the keystore password + */ + private void loadKeyStore(String keyStorePath, String ksPassword) + throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException { + InputStream fis = null; + try { + keyStorePassword = ksPassword.toCharArray(); + keyStore = KeyStore.getInstance(KEY_STORE_TYPE); + fis = new FileInputStream(keyStorePath); + keyStore.load(fis, keyStorePassword); + } finally { + if (fis != null) { + fis.close(); + } + } + } + + /** + * Loads the trustore + * + * @param trustStorePath - the trustore path in the filesystem. + * @param tsPassword - the truststore password + */ + private void loadTrustStore(String trustStorePath, String tsPassword) + throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException { + + InputStream fis = null; + try { + trustStore = KeyStore.getInstance(TRUST_STORE_TYPE); + fis = new FileInputStream(trustStorePath); + trustStore.load(fis, tsPassword.toCharArray()); + } finally { + if (fis != null) { + fis.close(); + } + } + } + + /** + * Initializes the SSL Context + */ + private void initSSLConnection() throws NoSuchAlgorithmException, UnrecoverableKeyException, + KeyStoreException, KeyManagementException { + KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KEY_MANAGER_TYPE); + keyManagerFactory.init(keyStore, keyStorePassword); + TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TRUST_MANAGER_TYPE); + trustManagerFactory.init(trustStore); + + // Create and initialize SSLContext for HTTPS communication + sslContext = SSLContext.getInstance(SSLV3); + sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null); + SSLContext.setDefault(sslContext); + } + + private void cleanup(Stub stub) { + if (stub != null) { + try { + stub.cleanup(); + } catch (AxisFault axisFault) { + //do nothing + } + } + } + +} + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java new file mode 100644 index 0000000000..a6d98fc73c --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.impl.admin; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.base.MultitenantConstants; +import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.PaginationRequest; +import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceList; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.service.api.admin.DeviceManagementAdminService; +import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; + +import javax.validation.constraints.Size; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.util.List; + +@Path("/admin/devices") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminService { + + private static final Log log = LogFactory.getLog(DeviceManagementAdminServiceImpl.class); + + @Override + @GET + public Response getDevicesByName(@QueryParam("name") @Size(max = 45) String name, + @QueryParam("type") @Size(min = 2, max = 45) String type, + @QueryParam("tenant-domain") String tenantDomain, + @HeaderParam("If-Modified-Since") String ifModifiedSince, + @QueryParam("offset") int offset, + @QueryParam("limit") int limit) { + RequestValidationUtil.validatePaginationParameters(offset, limit); + int currentTenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId(); + if (MultitenantConstants.SUPER_TENANT_ID != currentTenantId) { + return Response.status(Response.Status.UNAUTHORIZED).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage( + "Current logged in user is not authorized to perform this operation").build()).build(); + } + try { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain); + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(DeviceMgtAPIUtils.getTenantId(tenantDomain)); + + PaginationRequest request = new PaginationRequest(offset, limit); + request.setDeviceType(type); + request.setDeviceName(name); + List devices = DeviceMgtAPIUtils.getDeviceManagementService(). + getDevicesByNameAndType(request, false); + + // setting up paginated result + DeviceList deviceList = new DeviceList(); + deviceList.setList(devices); + deviceList.setCount(devices.size()); + + return Response.status(Response.Status.OK).entity(deviceList).build(); + } catch (DeviceManagementException e) { + String msg = "Error occurred at server side while fetching device list."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceTypeManagementAdminServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceTypeManagementAdminServiceImpl.java new file mode 100644 index 0000000000..57c0b7cde6 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceTypeManagementAdminServiceImpl.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.impl.admin; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.InvalidConfigurationException; +import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService; +import org.wso2.carbon.device.mgt.core.dto.DeviceType; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.service.api.admin.DeviceTypeManagementAdminService; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +@Path("/admin/device-types") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class DeviceTypeManagementAdminServiceImpl implements DeviceTypeManagementAdminService { + + private static final Log log = LogFactory.getLog(DeviceTypeManagementAdminServiceImpl.class); + private static final String DEVICETYPE_REGEX_PATTERN = "^[^ /]+$"; + private static final Pattern patternMatcher = Pattern.compile(DEVICETYPE_REGEX_PATTERN); + + @GET + @Override + public Response getDeviceTypes() { + try { + List deviceTypes = DeviceMgtAPIUtils.getDeviceManagementService().getDeviceTypes(); + return Response.status(Response.Status.OK).entity(deviceTypes).build(); + } catch (DeviceManagementException e) { + String msg = "Error occurred while fetching the list of device types."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + @Override + @POST + public Response addDeviceType(DeviceType deviceType) { + if (deviceType != null && deviceType.getDeviceTypeMetaDefinition() != null) { + try { + if (DeviceMgtAPIUtils.getDeviceManagementService().getDeviceType(deviceType.getName()) != null) { + String msg = "Device type already available, " + deviceType.getName(); + return Response.status(Response.Status.CONFLICT).entity(msg).build(); + } + Matcher matcher = patternMatcher.matcher(deviceType.getName()); + if(matcher.find()) { + DeviceManagementService httpDeviceTypeManagerService = + DeviceMgtAPIUtils.getDeviceTypeGeneratorService() + .populateDeviceManagementService(deviceType.getName(), + deviceType.getDeviceTypeMetaDefinition()); + DeviceMgtAPIUtils.getDeviceManagementService().registerDeviceType(httpDeviceTypeManagerService); + return Response.status(Response.Status.OK).build(); + } else { + return Response.status(Response.Status.BAD_REQUEST).entity("Device type name does not match the pattern " + + DEVICETYPE_REGEX_PATTERN).build(); + } + } catch (DeviceManagementException e) { + String msg = "Error occurred at server side while adding a device type."; + log.error(msg, e); + return Response.serverError().entity(msg).build(); + } + } else { + return Response.status(Response.Status.BAD_REQUEST).build(); + } + } + + @Override + @PUT + public Response updateDeviceType(DeviceType deviceType) { + if (deviceType != null && deviceType.getDeviceTypeMetaDefinition() != null) { + try { + if (DeviceMgtAPIUtils.getDeviceManagementService().getDeviceType(deviceType.getName()) == null) { + String msg = "Device type does not exist, " + deviceType.getName(); + return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); + } + DeviceManagementService httpDeviceTypeManagerService = DeviceMgtAPIUtils.getDeviceTypeGeneratorService() + .populateDeviceManagementService(deviceType.getName(), deviceType.getDeviceTypeMetaDefinition()); + DeviceMgtAPIUtils.getDeviceManagementService().registerDeviceType(httpDeviceTypeManagerService); + return Response.status(Response.Status.OK).build(); + } catch (DeviceManagementException e) { + String msg = "Error occurred at server side while updating the device type."; + log.error(msg, e); + return Response.serverError().entity(msg).build(); + } + } else { + return Response.status(Response.Status.BAD_REQUEST).build(); + } + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/GroupManagementAdminServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/GroupManagementAdminServiceImpl.java new file mode 100644 index 0000000000..0668b30c4e --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/GroupManagementAdminServiceImpl.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.impl.admin; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.common.GroupPaginationRequest; +import org.wso2.carbon.device.mgt.common.PaginationResult; +import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException; +import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceGroupList; +import org.wso2.carbon.device.mgt.jaxrs.service.api.admin.GroupManagementAdminService; +import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; + +import javax.ws.rs.core.Response; +import java.util.ArrayList; + +public class GroupManagementAdminServiceImpl implements GroupManagementAdminService { + + private static final Log log = LogFactory.getLog(GroupManagementAdminServiceImpl.class); + + @Override + public Response getGroups(String name, String owner, int offset, int limit) { + try { + RequestValidationUtil.validatePaginationParameters(offset, limit); + GroupPaginationRequest request = new GroupPaginationRequest(offset, limit); + request.setGroupName(name); + request.setOwner(owner); + PaginationResult deviceGroupsResult = DeviceMgtAPIUtils.getGroupManagementProviderService() + .getGroups(request); + DeviceGroupList deviceGroupList = new DeviceGroupList(); + if (deviceGroupsResult.getData() != null) { + deviceGroupList.setList(deviceGroupsResult.getData()); + deviceGroupList.setCount(deviceGroupsResult.getRecordsTotal()); + } else { + deviceGroupList.setList(new ArrayList<>()); + deviceGroupList.setCount(0); + } + return Response.status(Response.Status.OK).entity(deviceGroupList).build(); + } catch (GroupManagementException e) { + String msg = "ErrorResponse occurred while retrieving all groups."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } + + @Override + public Response getGroupCount() { + try { + int count = DeviceMgtAPIUtils.getGroupManagementProviderService().getGroupCount(); + return Response.status(Response.Status.OK).entity(count).build(); + } catch (GroupManagementException e) { + String msg = "ErrorResponse occurred while retrieving group count."; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/UserManagementAdminServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/UserManagementAdminServiceImpl.java new file mode 100644 index 0000000000..d268eff282 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/UserManagementAdminServiceImpl.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.impl.admin; + +import org.wso2.carbon.device.mgt.jaxrs.beans.PasswordResetWrapper; +import org.wso2.carbon.device.mgt.jaxrs.service.api.admin.UserManagementAdminService; +import org.wso2.carbon.device.mgt.jaxrs.util.CredentialManagementResponseBuilder; + +import javax.validation.constraints.Size; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +@Path("/admin/users") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class UserManagementAdminServiceImpl implements UserManagementAdminService { + + @POST + @Path("/{username}/credentials") + @Override + public Response resetUserPassword(@PathParam("username") + @Size(max = 45) + String user, @QueryParam("domain") String domain, PasswordResetWrapper credentials) { + if (domain != null && !domain.isEmpty()) { + user = domain + '/' + user; + } + return CredentialManagementResponseBuilder.buildResetPasswordResponse(user, credentials); + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/ConflictException.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/ConflictException.java new file mode 100644 index 0000000000..6afbf6f50a --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/ConflictException.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.impl.util; + +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; + +public class ConflictException extends WebApplicationException { + + private static final long serialVersionUID = 14234272342342340L; + + public ConflictException(ErrorResponse error) { + super(Response.status(Response.Status.CONFLICT).entity(error).build()); + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/FilteringUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/FilteringUtil.java new file mode 100644 index 0000000000..c0f578be39 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/FilteringUtil.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.impl.util; + + + +import java.util.Collections; +import java.util.List; + +/** + * This is used instead of filtering from cache. + */ +public class FilteringUtil { + + /** + * This is used to filter from the cached policies. + */ + public static List getFilteredList(List sourceList, int offset, int limit) { + if (sourceList == null || sourceList.size() < offset) { + return Collections.emptyList(); + } + return sourceList.subList(offset, Math.min(offset + limit, sourceList.size())); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/InputValidationException.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/InputValidationException.java new file mode 100644 index 0000000000..353131c9da --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/InputValidationException.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.impl.util; + +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; + +import javax.ws.rs.BadRequestException; +import javax.ws.rs.core.Response; +import java.io.Serializable; + +public class InputValidationException extends BadRequestException implements Serializable { + + private static final long serialVersionUID = 147843579458906890L; + + public InputValidationException(ErrorResponse error) { + super(Response.status(Response.Status.BAD_REQUEST).entity(error).build()); + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/NotFoundException.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/NotFoundException.java new file mode 100644 index 0000000000..a427e942b9 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/NotFoundException.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.impl.util; + +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; + +public class NotFoundException extends WebApplicationException { + + private static final long serialVersionUID = 147943572342342340L; + + public NotFoundException(ErrorResponse error) { + super(Response.status(Response.Status.NOT_FOUND).entity(error).build()); + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/RequestValidationUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/RequestValidationUtil.java new file mode 100644 index 0000000000..d6e921c0ca --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/RequestValidationUtil.java @@ -0,0 +1,356 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.impl.util; + +import org.wso2.carbon.device.mgt.jaxrs.beans.Scope; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration; +import org.wso2.carbon.device.mgt.common.notification.mgt.Notification; +import org.wso2.carbon.device.mgt.jaxrs.beans.*; + +import java.util.ArrayList; +import java.util.List; + +public class RequestValidationUtil { + + /** + * Checks if multiple criteria are specified in a conditional request. + * + * @param type Device type upon which the selection is done + * @param user Device user upon whom the selection is done + * @param roleName Role name upon which the selection is done + * @param ownership Ownership type upon which the selection is done + * @param status Enrollment status upon which the selection is done + */ + public static void validateSelectionCriteria(final String type, final String user, final String roleName, + final String ownership, final String status) { + List inputs = new ArrayList() {{ + add(type); + add(user); + add(roleName); + add(ownership); + add(status); + }}; + +// boolean hasOneSelection = false; +// for (String i : inputs) { +// if (i == null) { +// continue; +// } +// hasOneSelection = !hasOneSelection; +// if (!hasOneSelection) { +// break; +// } +// } + int count = 0; + for (String i : inputs) { + if (i == null) { + continue; + } + count++; + if (count > 1) { + break; + } + } + if (count > 1) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("The incoming request has " + + "more than one selection criteria defined through query parameters").build()); + } + + } + + + public static void validateDeviceIdentifier(String type, String id) { + boolean isErroneous = false; + ErrorResponse.ErrorResponseBuilder error = new ErrorResponse.ErrorResponseBuilder(); + if (id == null) { + isErroneous = true; + error.addErrorItem(null, "Device identifier cannot be null"); + } + if (type == null) { + isErroneous = true; + error.addErrorItem(null, "Device type cannot be null"); + } + if (isErroneous) { + throw new InputValidationException(error.setCode(400l).setMessage("Invalid device identifier").build()); + + } + } + + public static void validateStatus(String status) { + if (status == null) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage( + "Enrollment status type cannot be null").build()); + } + switch (status) { + case "ACTIVE": + case "INACTIVE": + case "UNCLAIMED": + case "UNREACHABLE": + case "SUSPENDED": + case "DISENROLLMENT_REQUESTED": + case "REMOVED": + case "BLOCKED": + case "CREATED": + return; + default: + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Invalid enrollment status type " + + "received. Valid status types are ACTIVE | INACTIVE | " + + "UNCLAIMED | UNREACHABLE | SUSPENDED | DISENROLLMENT_REQUESTED | REMOVED | " + + "BLOCKED | CREATED").build()); + } + } + + public static void validateOwnershipType(String ownership) { + if (ownership == null) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage( + "Ownership type cannot be null").build()); + } + switch (ownership) { + case "BYOD": + case "COPE": + return; + default: + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage( + "Invalid ownership type received. " + + "Valid ownership types are BYOD | COPE").build()); + } + } + + public static void validateNotificationStatus(String status) { + if (status == null) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage( + "Notification status type cannot be null").build()); + } + switch (status) { + case "NEW": + case "CHECKED": + return; + default: + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Invalid notification status type " + + "received. Valid status types are NEW | CHECKED").build()); + } + } + + public static void validateNotificationId(int id) { + if (id <= 0) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Invalid notification id. " + + "Only positive integers are accepted as valid notification Ids").build()); + } + } + + public static void validateNotification(Notification notification) { + if (notification == null) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Notification content " + + "cannot be null").build()); + } + } + + public static void validateTimestamp(String timestamp) { + if (timestamp == null || timestamp.isEmpty()) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Timestamp value " + + "cannot be null or empty").build()); + } + try { + Long.parseLong(timestamp); + } catch (NumberFormatException e) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage( + "Invalid timestamp value").build()); + } + } + + public static void validateActivityId(String activityId) { + if (activityId == null || activityId.isEmpty()) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Activity Id " + + "cannot be null or empty. It should be in the form of " + + "'[ACTIVITY][_][any-positive-integer]' instead").build()); + } + String[] splits = activityId.split("_"); + if (splits == null || splits[0] == null || splits[0].isEmpty() || !"ACTIVITY".equals(splits[0]) || + splits[1] == null || splits[0].isEmpty()) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage( + "Activity Id should be in the form of '[ACTIVITY][_][any-positive-integer]'").build()); + } + try { + Long.parseLong(splits[1]); + } catch (NumberFormatException e) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage( + "Activity Id should be in the form of '[ACTIVITY][_][any-positive-integer]'").build()); + } + } + + public static void validateApplicationInstallationContext(ApplicationWrapper installationCtx) { + int count = 0; + + if (installationCtx.getDeviceIdentifiers() != null && installationCtx.getDeviceIdentifiers().size() > 0) { + count++; + } + if (installationCtx.getUserNameList() != null && installationCtx.getUserNameList().size() > 0) { + count++; + } + if (installationCtx.getRoleNameList() != null && installationCtx.getRoleNameList().size() > 0) { + count++; + } + if (count > 1) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("The incoming request has " + + "more than one application installation criteria defined").build()); + } + } + + public static void validateApplicationUninstallationContext(ApplicationWrapper installationCtx) { + int count = 0; + + if (installationCtx.getDeviceIdentifiers() != null && installationCtx.getDeviceIdentifiers().size() > 0) { + count++; + } + if (installationCtx.getUserNameList() != null && installationCtx.getUserNameList().size() > 0) { + count++; + } + if (installationCtx.getRoleNameList() != null && installationCtx.getRoleNameList().size() > 0) { + count++; + } + if (count > 1) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("The incoming request has " + + "more than one application un-installation criteria defined").build()); + } + } + + public static void validateUpdateConfiguration(PlatformConfiguration config) { + if (config == null) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Configurations are not defined.") + .build()); + } else if (config.getConfiguration() == null || config.getConfiguration().size() == 0) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Does not contain any " + + "configuration entries.").build()); + } + } + + public static void validateDeviceIdentifiers(List deviceIdentifiers) { + if (deviceIdentifiers == null || deviceIdentifiers.size() == 0) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Device identifier list is " + + "empty.").build()); + } + } + + public static void validatePolicyDetails(PolicyWrapper policyWrapper) { + if (policyWrapper == null) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Policy is empty.").build()); + } + } + + public static void validatePolicyIds(List policyIds) { + if (policyIds == null || policyIds.size() == 0) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Policy Id list is empty.").build + ()); + } + } + + public static void validateRoleName(String roleName) { + if (roleName == null || roleName.isEmpty()) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Role name isn't valid.").build + ()); + } + } + + public static void validateUsers(List users) { + if (users == null || users.size() == 0) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("User list isn't valid.").build + ()); + } + } + + public static void validateCredentials(OldPasswordResetWrapper credentials) { + if (credentials == null || credentials.getNewPassword() == null || credentials.getOldPassword() == null) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Old or New password " + + "fields cannot be empty").build()); + } + } + + public static void validateRoleDetails(RoleInfo roleInfo) { + if (roleInfo == null) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Request body is " + + "empty").build()); + } else if (roleInfo.getRoleName() == null) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Request body is " + + "incorrect").build()); + } + } + + public static void validateScopes(List scopes) { + if (scopes == null || scopes.isEmpty()) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Scope details of the request body" + + " is incorrect or empty").build()); + } + } + + public static void validatePaginationParameters(int offset, int limit) { + if (offset < 0) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Request parameter offset is s " + + "negative value.").build()); + } + if (limit < 0) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Request parameter limit is a " + + "negative value.").build()); + } + if (limit > 100) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Request parameter limit should" + + " be less than or equal to 100.").build()); + } + + } + + public static void validateOwnerParameter(String owner) { + if (owner == null || owner.isEmpty()) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Request parameter owner should" + + " be non empty.").build()); + } + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/UnauthorizedAccessException.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/UnauthorizedAccessException.java new file mode 100644 index 0000000000..c0f05c9c57 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/UnauthorizedAccessException.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.impl.util; + +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; + +public class UnauthorizedAccessException extends WebApplicationException { + + private static final long serialVersionUID = 147943579458906890L; + + public UnauthorizedAccessException(ErrorResponse error) { + super(Response.status(Response.Status.UNAUTHORIZED).entity(error).build()); + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/UnexpectedServerErrorException.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/UnexpectedServerErrorException.java new file mode 100644 index 0000000000..b327104241 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/UnexpectedServerErrorException.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.service.impl.util; + +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; + +public class UnexpectedServerErrorException extends WebApplicationException { + + private static final long serialVersionUID = 147943579458906890L; + + public UnexpectedServerErrorException(ErrorResponse error) { + super(Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build()); + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/swagger/extension/SecurityDefinitionConfigurator.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/swagger/extension/SecurityDefinitionConfigurator.java new file mode 100644 index 0000000000..e1bafc95a2 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/swagger/extension/SecurityDefinitionConfigurator.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ +package org.wso2.carbon.device.mgt.jaxrs.swagger.extension; + +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.jaxrs.Reader; +import io.swagger.jaxrs.config.ReaderListener; +import io.swagger.models.Swagger; +import io.swagger.models.auth.OAuth2Definition; +import io.swagger.models.auth.SecuritySchemeDefinition; +import org.wso2.carbon.device.mgt.jaxrs.beans.Scope; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@SwaggerDefinition( + basePath = "/api/device-mgt/v0.9", + host = "localhost:9443" +) +public class SecurityDefinitionConfigurator implements ReaderListener { + + public static final String TOKEN_AUTH_SCHEME = "swagger_auth"; + + @Override + public void beforeScan(Reader reader, Swagger swagger) { + + } + + @Override + public void afterScan(Reader reader, Swagger swagger) { + OAuth2Definition tokenScheme = new OAuth2Definition(); + tokenScheme.setType("oauth2"); + tokenScheme.setFlow("application"); + tokenScheme.setTokenUrl("https://" + swagger.getHost() + "/oauth2/token"); + tokenScheme.setAuthorizationUrl("https://" + swagger.getHost() + "/oauth2/authorize"); + tokenScheme.addScope("write:everything", "Full access"); + + Map schemes = new HashMap<>(); + schemes.put(TOKEN_AUTH_SCHEME, tokenScheme); + + swagger.setSecurityDefinitions(schemes); + //TODO: Have to add wso2-scopes to swagger definition from here + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/Constants.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/Constants.java new file mode 100644 index 0000000000..728c461c7b --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/Constants.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.util; + +/** + * Holds the constants used by DeviceImpl Management Admin web application. + */ +public class Constants { + + public static final String USER_CLAIM_EMAIL_ADDRESS = "http://wso2.org/claims/emailaddress"; + public static final String USER_CLAIM_FIRST_NAME = "http://wso2.org/claims/givenname"; + public static final String USER_CLAIM_LAST_NAME = "http://wso2.org/claims/lastname"; + public static final String PRIMARY_USER_STORE = "PRIMARY"; + public static final String DEFAULT_STREAM_VERSION = "1.0.0"; + public static final String SCOPE = "scope"; + public static final String JDBC_USERSTOREMANAGER = "org.wso2.carbon.user.core.jdbc.JDBCUserStoreManager"; + public static final int DEFAULT_PAGE_LIMIT = 50; + + + public final class ErrorMessages { + private ErrorMessages () { throw new AssertionError(); } + + public static final String STATUS_BAD_REQUEST_MESSAGE_DEFAULT = "Bad Request"; + + } + + public final class DeviceConstants { + private DeviceConstants () { throw new AssertionError(); } + + public static final String APPLICATION_JSON = "application/json"; + public static final String HEADER_CONTENT_TYPE = "Content-Type"; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/CredentialManagementResponseBuilder.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/CredentialManagementResponseBuilder.java new file mode 100644 index 0000000000..d326802c2a --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/CredentialManagementResponseBuilder.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.beans.OldPasswordResetWrapper; +import org.wso2.carbon.device.mgt.jaxrs.beans.PasswordResetWrapper; +import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.api.UserStoreManager; + +import javax.ws.rs.core.Response; +import java.io.UnsupportedEncodingException; +import java.util.regex.Pattern; + +/** + * This class builds Credential modification related Responses + */ +public class CredentialManagementResponseBuilder { + + private static Log log = LogFactory.getLog(CredentialManagementResponseBuilder.class); + private static String PASSWORD_VALIDATION_REGEX_TAG = "PasswordJavaRegEx"; + private static String PASSWORD_VALIDATION_ERROR_MSG_TAG = "PasswordJavaRegExViolationErrorMsg"; + + /** + * Builds the response to change the password of a user + * + * @param credentials - User credentials + * @return Response Object + */ + public static Response buildChangePasswordResponse(OldPasswordResetWrapper credentials) { + String username = ""; + try { + RequestValidationUtil.validateCredentials(credentials); + if (!validateCredential(credentials.getNewPassword())) { + String errorMsg = DeviceMgtAPIUtils.getRealmService().getBootstrapRealmConfiguration() + .getUserStoreProperty(PASSWORD_VALIDATION_ERROR_MSG_TAG); + return Response.status(Response.Status.BAD_REQUEST).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(errorMsg).build()).build(); + } + + UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager(); + // this is the user who initiates the request + username = CarbonContext.getThreadLocalCarbonContext().getUsername(); + userStoreManager.updateCredential(username, credentials.getNewPassword(), + credentials.getOldPassword()); + DeviceMgtAPIUtils.getIntegrationClientService().resetUserInfo(username, + PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain()); + return Response.status(Response.Status.OK).entity("UserImpl password by username: " + + username + " was successfully changed.").build(); + } catch (UserStoreException e) { + log.error(e.getMessage(), e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(e.getMessage()).build()).build(); + } catch (UnsupportedEncodingException e) { + String msg = "Could not change the password of the user: " + username + + ". The Character Encoding is not supported."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + /** + * Builds the response to reset the password of a user + * + * @param username - Username of the user. + * @param credentials - User credentials + * @return Response Object + */ + public static Response buildResetPasswordResponse(String username, PasswordResetWrapper credentials) { + try { + UserStoreManager userStoreManager = DeviceMgtAPIUtils.getUserStoreManager(); + if (!userStoreManager.isExistingUser(username)) { + return Response.status(Response.Status.BAD_REQUEST).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage("No user found with the username " + + username).build()).build(); + } + if (credentials == null || credentials.getNewPassword() == null) { + return Response.status(Response.Status.BAD_REQUEST).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage("Password cannot be empty." + + username).build()).build(); + } + if (!validateCredential(credentials.getNewPassword())) { + String errorMsg = DeviceMgtAPIUtils.getRealmService().getBootstrapRealmConfiguration() + .getUserStoreProperty(PASSWORD_VALIDATION_ERROR_MSG_TAG); + return Response.status(Response.Status.BAD_REQUEST).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(errorMsg).build()).build(); + } + userStoreManager.updateCredentialByAdmin(username, credentials.getNewPassword()); + DeviceMgtAPIUtils.getIntegrationClientService().resetUserInfo(username, + PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain()); + return Response.status(Response.Status.OK).entity("UserImpl password by username: " + + username + " was successfully changed.").build(); + } catch (UserStoreException e) { + String msg = "Error occurred while updating the credentials of user '" + username + "'"; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (UnsupportedEncodingException e) { + String msg = "Could not change the password of the user: " + username + + ". The Character Encoding is not supported."; + log.error(msg, e); + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + private static boolean validateCredential(String password) + throws UserStoreException, UnsupportedEncodingException { + String passwordValidationRegex = DeviceMgtAPIUtils.getRealmService().getBootstrapRealmConfiguration() + .getUserStoreProperty(PASSWORD_VALIDATION_REGEX_TAG); + if (passwordValidationRegex != null) { + Pattern pattern = Pattern.compile(passwordValidationRegex); + if (pattern.matcher(password).matches()) { + return true; + } + } + return false; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java new file mode 100644 index 0000000000..cbbfaf32ce --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java @@ -0,0 +1,708 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.util; + +import org.apache.axis2.AxisFault; +import org.apache.axis2.client.Options; +import org.apache.axis2.java.security.SSLProtocolSocketFactory; +import org.apache.axis2.transport.http.HTTPConstants; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.httpclient.Header; +import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.analytics.stream.persistence.stub.EventStreamPersistenceAdminServiceStub; +import org.wso2.carbon.apimgt.integration.client.service.IntegrationClientService; +import org.wso2.carbon.base.ServerConfiguration; +import org.wso2.carbon.analytics.api.AnalyticsDataAPI; +import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.core.util.Utils; +import org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherService; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.EnrolmentInfo; +import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService; +import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry; +import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration; +import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfigurationManagementService; +import org.wso2.carbon.device.mgt.common.geo.service.GeoLocationProviderService; +import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementService; +import org.wso2.carbon.device.mgt.common.spi.DeviceTypeGeneratorService; +import org.wso2.carbon.device.mgt.core.app.mgt.ApplicationManagementProviderService; +import org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceInformationManager; +import org.wso2.carbon.device.mgt.core.search.mgt.SearchManagerService; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.EventAttributeList; +import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.InputValidationException; +import org.wso2.carbon.event.publisher.stub.EventPublisherAdminServiceStub; +import org.wso2.carbon.event.receiver.stub.EventReceiverAdminServiceStub; +import org.wso2.carbon.event.stream.stub.EventStreamAdminServiceStub; +import org.wso2.carbon.identity.jwt.client.extension.JWTClient; +import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; +import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; +import org.wso2.carbon.identity.user.store.count.AbstractCountRetrieverFactory; +import org.wso2.carbon.identity.user.store.count.UserStoreCountRetriever; +import org.wso2.carbon.identity.user.store.count.exception.UserStoreCounterException; +import org.wso2.carbon.identity.user.store.count.jdbc.JDBCCountRetrieverFactory; +import org.wso2.carbon.identity.user.store.count.jdbc.internal.InternalCountRetrieverFactory; +import org.wso2.carbon.policy.mgt.common.PolicyMonitoringTaskException; +import org.wso2.carbon.policy.mgt.core.PolicyManagerService; +import org.wso2.carbon.policy.mgt.core.task.TaskScheduleService; +import org.wso2.carbon.registry.core.service.RegistryService; +import org.wso2.carbon.user.api.AuthorizationManager; +import org.wso2.carbon.user.api.RealmConfiguration; +import org.wso2.carbon.user.api.UserRealm; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.api.UserStoreManager; +import org.wso2.carbon.user.core.jdbc.JDBCUserStoreManager; +import org.wso2.carbon.user.core.service.RealmService; + +import javax.cache.Cache; +import javax.cache.Caching; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; +import javax.ws.rs.core.MediaType; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.util.ArrayList; +import java.util.List; + +/** + * MDMAPIUtils class provides utility function used by CDM REST-API classes. + */ +public class DeviceMgtAPIUtils { + + private static final String NOTIFIER_FREQUENCY = "notifierFrequency"; + private static final String STREAM_DEFINITION_PREFIX = "iot.per.device.stream."; + private static final String DEFAULT_HTTP_PROTOCOL = "https"; + private static final String EVENT_RECIEVER_CONTEXT = "EventReceiverAdminService/"; + private static final String EVENT_PUBLISHER_CONTEXT = "EventPublisherAdminService/"; + private static final String EVENT_STREAM_CONTEXT = "EventStreamAdminService/"; + private static final String EVENT_PERSISTENCE_CONTEXT = "EventStreamPersistenceAdminService/"; + private static final String AUTHORIZATION_HEADER = "Authorization"; + private static final String AUTHORIZATION_HEADER_VALUE = "Bearer"; + public static final String DAS_PORT = "${iot.analytics.https.port}"; + public static final String DAS_HOST_NAME = "${iot.analytics.host}"; + private static final String KEY_STORE_TYPE = "JKS"; + private static final String TRUST_STORE_TYPE = "JKS"; + private static final String KEY_MANAGER_TYPE = "SunX509"; //Default Key Manager Type + private static final String TRUST_MANAGER_TYPE = "SunX509"; //Default Trust Manager Type + private static final String SSLV3 = "SSLv3"; + private static final String EVENT_CACHE_MANAGER_NAME = "mqttAuthorizationCacheManager"; + private static final String EVENT_CACHE_NAME = "mqttAuthorizationCache"; + public static final String DAS_ADMIN_SERVICE_EP = "https://" + DAS_HOST_NAME + ":" + DAS_PORT + "/services/"; + private static SSLContext sslContext; + + private static Log log = LogFactory.getLog(DeviceMgtAPIUtils.class); + private static KeyStore keyStore; + private static KeyStore trustStore; + private static char[] keyStorePassword; + + private static IntegrationClientService integrationClientService; + + static { + String keyStorePassword = ServerConfiguration.getInstance().getFirstProperty("Security.KeyStore.Password"); + String trustStorePassword = ServerConfiguration.getInstance().getFirstProperty( + "Security.TrustStore.Password"); + String keyStoreLocation = ServerConfiguration.getInstance().getFirstProperty("Security.KeyStore.Location"); + String trustStoreLocation = ServerConfiguration.getInstance().getFirstProperty( + "Security.TrustStore.Location"); + + //Call to load the keystore. + try { + loadKeyStore(keyStoreLocation, keyStorePassword); + //Call to load the TrustStore. + loadTrustStore(trustStoreLocation, trustStorePassword); + //Create the SSL context with the loaded TrustStore/keystore. + initSSLConnection(); + } catch (KeyStoreException | IOException | CertificateException | NoSuchAlgorithmException + | UnrecoverableKeyException | KeyManagementException e) { + log.error("publishing dynamic event receiver is failed due to " + e.getMessage(), e); + } + } + + public static int getNotifierFrequency(PlatformConfiguration tenantConfiguration) { + List configEntryList = tenantConfiguration.getConfiguration(); + if (configEntryList != null && !configEntryList.isEmpty()) { + for (ConfigurationEntry entry : configEntryList) { + if (NOTIFIER_FREQUENCY.equals(entry.getName())) { + if (entry.getValue() == null) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage( + "Notifier frequency cannot be null. Please specify a valid non-negative " + + "integer value to successfully set up notification frequency. " + + "Should the service be stopped, use '0' as the notification " + + "frequency.").build() + ); + } + return (int) (Double.parseDouble(entry.getValue().toString()) + 0.5d); + } + } + } + return 0; + } + + public static void scheduleTaskService(int notifierFrequency) { + TaskScheduleService taskScheduleService; + try { + taskScheduleService = getPolicyManagementService().getTaskScheduleService(); + if (taskScheduleService.isTaskScheduled()) { + taskScheduleService.updateTask(notifierFrequency); + } else { + taskScheduleService.startTask(notifierFrequency); + } + } catch (PolicyMonitoringTaskException e) { + log.error("Exception occurred while starting the Task service.", e); + } + } + + public static DeviceManagementProviderService getDeviceManagementService() { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + DeviceManagementProviderService deviceManagementProviderService = + (DeviceManagementProviderService) ctx.getOSGiService(DeviceManagementProviderService.class, null); + if (deviceManagementProviderService == null) { + String msg = "DeviceImpl Management provider service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + return deviceManagementProviderService; + } + + public static DeviceTypeGeneratorService getDeviceTypeGeneratorService() { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + DeviceTypeGeneratorService deviceTypeGeneratorService = + (DeviceTypeGeneratorService) ctx.getOSGiService(DeviceTypeGeneratorService.class, null); + if (deviceTypeGeneratorService == null) { + String msg = "DeviceTypeGeneratorService service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + return deviceTypeGeneratorService; + } + + public static boolean isValidDeviceIdentifier(DeviceIdentifier deviceIdentifier) throws DeviceManagementException { + Device device = getDeviceManagementService().getDevice(deviceIdentifier); + if (device == null || device.getDeviceIdentifier() == null || + device.getDeviceIdentifier().isEmpty() || device.getEnrolmentInfo() == null) { + return false; + } else if (EnrolmentInfo.Status.REMOVED.equals(device.getEnrolmentInfo().getStatus())) { + return false; + } + return true; + } + + + public static UserStoreCountRetriever getUserStoreCountRetrieverService() + throws UserStoreCounterException { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + List countRetrieverFactories = ctx.getOSGiServices(AbstractCountRetrieverFactory.class, null); + RealmService realmService = (RealmService) ctx.getOSGiService(RealmService.class, null); + RealmConfiguration realmConfiguration = realmService.getBootstrapRealmConfiguration(); + String userStoreType; + //Ignoring Sonar warning as getUserStoreClass() returning string name of the class. So cannot use 'instanceof'. + if (JDBCUserStoreManager.class.getName().equals(realmConfiguration.getUserStoreClass())) { + userStoreType = JDBCCountRetrieverFactory.JDBC; + } else { + userStoreType = InternalCountRetrieverFactory.INTERNAL; + } + AbstractCountRetrieverFactory countRetrieverFactory = null; + for (Object countRetrieverFactoryObj : countRetrieverFactories) { + countRetrieverFactory = (AbstractCountRetrieverFactory) countRetrieverFactoryObj; + if (userStoreType.equals(countRetrieverFactory.getCounterType())) { + break; + } + } + if (countRetrieverFactory == null) { + return null; + } + return countRetrieverFactory.buildCountRetriever(realmConfiguration); + } + + public static DeviceAccessAuthorizationService getDeviceAccessAuthorizationService() { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + DeviceAccessAuthorizationService deviceAccessAuthorizationService = + (DeviceAccessAuthorizationService) ctx.getOSGiService(DeviceAccessAuthorizationService.class, null); + if (deviceAccessAuthorizationService == null) { + String msg = "DeviceAccessAuthorization service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + return deviceAccessAuthorizationService; + } + + public static GroupManagementProviderService getGroupManagementProviderService() { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + GroupManagementProviderService groupManagementProviderService = + (GroupManagementProviderService) ctx.getOSGiService(GroupManagementProviderService.class, null); + if (groupManagementProviderService == null) { + String msg = "GroupImpl Management service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + return groupManagementProviderService; + } + + public static UserStoreManager getUserStoreManager() throws UserStoreException { + RealmService realmService; + UserStoreManager userStoreManager; + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + realmService = (RealmService) ctx.getOSGiService(RealmService.class, null); + if (realmService == null) { + String msg = "Realm service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + int tenantId = ctx.getTenantId(); + userStoreManager = realmService.getTenantUserRealm(tenantId).getUserStoreManager(); + return userStoreManager; + } + + public static RealmService getRealmService() throws UserStoreException { + RealmService realmService; + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + realmService = (RealmService) ctx.getOSGiService(RealmService.class, null); + if (realmService == null) { + String msg = "Realm service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + return realmService; + } + + public static IntegrationClientService getIntegrationClientService() { + if (integrationClientService == null) { + synchronized (DeviceMgtAPIUtils.class) { + if (integrationClientService == null) { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + integrationClientService = (IntegrationClientService) ctx.getOSGiService(IntegrationClientService.class, null); + if (integrationClientService == null) { + String msg = "IntegrationClientService is not initialized"; + log.error(msg); + throw new IllegalStateException(msg); + } + } + } + } + return integrationClientService; + } + + public static RegistryService getRegistryService() { + RegistryService registryService; + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + registryService = (RegistryService) ctx.getOSGiService(RegistryService.class, null); + if (registryService == null) { + String msg = "registry service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + return registryService; + } + + public static JWTClientManagerService getJWTClientManagerService() { + JWTClientManagerService jwtClientManagerService; + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + jwtClientManagerService = (JWTClientManagerService) ctx.getOSGiService(JWTClientManagerService.class, null); + if (jwtClientManagerService == null) { + String msg = "jwtClientManagerServicehas not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + return jwtClientManagerService; + } + + /** + * Getting the current tenant's user realm + */ + public static UserRealm getUserRealm() throws UserStoreException { + RealmService realmService; + UserRealm realm; + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + realmService = (RealmService) ctx.getOSGiService(RealmService.class, null); + + if (realmService == null) { + throw new IllegalStateException("Realm service not initialized"); + } + int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId(); + realm = realmService.getTenantUserRealm(tenantId); + return realm; + } + + public static AuthorizationManager getAuthorizationManager() throws UserStoreException { + RealmService realmService; + AuthorizationManager authorizationManager; + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + realmService = (RealmService) ctx.getOSGiService(RealmService.class, null); + if (realmService == null) { + throw new IllegalStateException("Realm service is not initialized."); + } + int tenantId = ctx.getTenantId(); + authorizationManager = realmService.getTenantUserRealm(tenantId).getAuthorizationManager(); + + return authorizationManager; + } + + public static ApplicationManagementProviderService getAppManagementService() { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + ApplicationManagementProviderService applicationManagementProviderService = + (ApplicationManagementProviderService) ctx.getOSGiService(ApplicationManagementProviderService.class, null); + if (applicationManagementProviderService == null) { + throw new IllegalStateException("AuthenticationImpl management service has not initialized."); + } + return applicationManagementProviderService; + } + + public static PolicyManagerService getPolicyManagementService() { + PolicyManagerService policyManagementService; + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + policyManagementService = + (PolicyManagerService) ctx.getOSGiService(PolicyManagerService.class, null); + if (policyManagementService == null) { + String msg = "PolicyImpl Management service not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + return policyManagementService; + } + + public static PlatformConfigurationManagementService getPlatformConfigurationManagementService() { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + PlatformConfigurationManagementService tenantConfigurationManagementService = + (PlatformConfigurationManagementService) ctx.getOSGiService( + PlatformConfigurationManagementService.class, null); + if (tenantConfigurationManagementService == null) { + throw new IllegalStateException("Tenant configuration Management service not initialized."); + } + return tenantConfigurationManagementService; + } + + public static NotificationManagementService getNotificationManagementService() { + NotificationManagementService notificationManagementService; + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + notificationManagementService = (NotificationManagementService) ctx.getOSGiService( + NotificationManagementService.class, null); + if (notificationManagementService == null) { + throw new IllegalStateException("Notification Management service not initialized."); + } + return notificationManagementService; + } + + public static DeviceInformationManager getDeviceInformationManagerService() { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + DeviceInformationManager deviceInformationManager = + (DeviceInformationManager) ctx.getOSGiService(DeviceInformationManager.class, null); + if (deviceInformationManager == null) { + throw new IllegalStateException("DeviceImpl information Manager service has not initialized."); + } + return deviceInformationManager; + } + + + public static SearchManagerService getSearchManagerService() { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + SearchManagerService searchManagerService = + (SearchManagerService) ctx.getOSGiService(SearchManagerService.class, null); + if (searchManagerService == null) { + throw new IllegalStateException("DeviceImpl search manager service is not initialized."); + } + return searchManagerService; + } + + public static GeoLocationProviderService getGeoService() { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + GeoLocationProviderService + geoService = (GeoLocationProviderService) ctx.getOSGiService(GeoLocationProviderService.class, null); + if (geoService == null) { + throw new IllegalStateException("Geo Service has not been initialized."); + } + return geoService; + } + + public static AnalyticsDataAPI getAnalyticsDataAPI() { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + AnalyticsDataAPI analyticsDataAPI = + (AnalyticsDataAPI) ctx.getOSGiService(AnalyticsDataAPI.class, null); + if (analyticsDataAPI == null) { + String msg = "Analytics api service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + return analyticsDataAPI; + } + + public static int getTenantId(String tenantDomain) throws DeviceManagementException { + RealmService realmService = + (RealmService) PrivilegedCarbonContext.getThreadLocalCarbonContext().getOSGiService(RealmService.class, null); + if (realmService == null) { + throw new IllegalStateException("Realm service has not been initialized."); + } + try { + return realmService.getTenantManager().getTenantId(tenantDomain); + } catch (UserStoreException e) { + throw new DeviceManagementException("Error occured while trying to " + + "obtain tenant id of currently logged in user"); + } + } + + public static String getAuthenticatedUser() { + PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + String username = threadLocalCarbonContext.getUsername(); + String tenantDomain = threadLocalCarbonContext.getTenantDomain(); + if (username != null && username.endsWith(tenantDomain)) { + return username.substring(0, username.lastIndexOf("@")); + } + return username; + } + + public static EventsPublisherService getEventPublisherService() { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + EventsPublisherService eventsPublisherService = + (EventsPublisherService) ctx.getOSGiService(EventsPublisherService.class, null); + if (eventsPublisherService == null) { + String msg = "Event Publisher service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + return eventsPublisherService; + } + + public static String getStreamDefinition(String deviceType, String tenantDomain) { + return STREAM_DEFINITION_PREFIX + tenantDomain + "." + deviceType.replace(" ", "."); + } + + public static EventStreamAdminServiceStub getEventStreamAdminServiceStub() + throws AxisFault, UserStoreException, JWTClientException { + EventStreamAdminServiceStub eventStreamAdminServiceStub = new EventStreamAdminServiceStub( + Utils.replaceSystemProperty(DAS_ADMIN_SERVICE_EP + EVENT_STREAM_CONTEXT)); + Options streamOptions = eventStreamAdminServiceStub._getServiceClient().getOptions(); + if (streamOptions == null) { + streamOptions = new Options(); + } + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() + .getRealmConfiguration().getAdminUserName() + "@" + tenantDomain; + JWTClient jwtClient = DeviceMgtAPIUtils.getJWTClientManagerService().getJWTClient(); + + String authValue = AUTHORIZATION_HEADER_VALUE + " " + new String(Base64.encodeBase64( + jwtClient.getJwtToken(username).getBytes())); + + List
list = new ArrayList<>(); + Header httpHeader = new Header(); + httpHeader.setName(AUTHORIZATION_HEADER); + httpHeader.setValue(authValue); + list.add(httpHeader);//"https" + streamOptions.setProperty(HTTPConstants.HTTP_HEADERS, list); + streamOptions.setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER + , new Protocol(DEFAULT_HTTP_PROTOCOL + , (ProtocolSocketFactory) new SSLProtocolSocketFactory(sslContext) + , Integer.parseInt(Utils.replaceSystemProperty(DAS_PORT)))); + eventStreamAdminServiceStub._getServiceClient().setOptions(streamOptions); + return eventStreamAdminServiceStub; + } + + public static EventReceiverAdminServiceStub getEventReceiverAdminServiceStub() + throws AxisFault, UserStoreException, JWTClientException { + EventReceiverAdminServiceStub receiverAdminServiceStub = new EventReceiverAdminServiceStub( + Utils.replaceSystemProperty(DAS_ADMIN_SERVICE_EP + EVENT_RECIEVER_CONTEXT)); + Options eventReciverOptions = receiverAdminServiceStub._getServiceClient().getOptions(); + if (eventReciverOptions == null) { + eventReciverOptions = new Options(); + } + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() + .getRealmConfiguration().getAdminUserName() + "@" + tenantDomain; + JWTClient jwtClient = DeviceMgtAPIUtils.getJWTClientManagerService().getJWTClient(); + + String authValue = AUTHORIZATION_HEADER_VALUE + " " + new String(Base64.encodeBase64( + jwtClient.getJwtToken(username).getBytes())); + + List
list = new ArrayList<>(); + Header httpHeader = new Header(); + httpHeader.setName(AUTHORIZATION_HEADER); + httpHeader.setValue(authValue); + list.add(httpHeader); + + eventReciverOptions.setProperty(HTTPConstants.HTTP_HEADERS, list); + eventReciverOptions.setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER + , new Protocol(DEFAULT_HTTP_PROTOCOL + , (ProtocolSocketFactory) new SSLProtocolSocketFactory(sslContext) + , Integer.parseInt(Utils.replaceSystemProperty(DAS_PORT)))); + + receiverAdminServiceStub._getServiceClient().setOptions(eventReciverOptions); + return receiverAdminServiceStub; + } + + public static EventPublisherAdminServiceStub getEventPublisherAdminServiceStub() + throws AxisFault, UserStoreException, JWTClientException { + EventPublisherAdminServiceStub eventPublisherAdminServiceStub = new EventPublisherAdminServiceStub( + Utils.replaceSystemProperty(DAS_ADMIN_SERVICE_EP + EVENT_PUBLISHER_CONTEXT)); + Options eventReciverOptions = eventPublisherAdminServiceStub._getServiceClient().getOptions(); + if (eventReciverOptions == null) { + eventReciverOptions = new Options(); + } + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() + .getRealmConfiguration().getAdminUserName() + "@" + tenantDomain; + JWTClient jwtClient = DeviceMgtAPIUtils.getJWTClientManagerService().getJWTClient(); + + String authValue = AUTHORIZATION_HEADER_VALUE + " " + new String(Base64.encodeBase64( + jwtClient.getJwtToken(username).getBytes())); + + List
list = new ArrayList<>(); + Header httpHeader = new Header(); + httpHeader.setName(AUTHORIZATION_HEADER); + httpHeader.setValue(authValue); + list.add(httpHeader); + + eventReciverOptions.setProperty(HTTPConstants.HTTP_HEADERS, list); + eventReciverOptions.setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER + , new Protocol(DEFAULT_HTTP_PROTOCOL + , (ProtocolSocketFactory) new SSLProtocolSocketFactory(sslContext) + , Integer.parseInt(Utils.replaceSystemProperty(DAS_PORT)))); + eventPublisherAdminServiceStub._getServiceClient().setOptions(eventReciverOptions); + return eventPublisherAdminServiceStub; + } + + public static EventStreamPersistenceAdminServiceStub getEventStreamPersistenceAdminServiceStub() + throws AxisFault, UserStoreException, JWTClientException { + EventStreamPersistenceAdminServiceStub eventStreamPersistenceAdminServiceStub + = new EventStreamPersistenceAdminServiceStub( + Utils.replaceSystemProperty(DAS_ADMIN_SERVICE_EP + EVENT_PERSISTENCE_CONTEXT)); + Options eventReciverOptions = eventStreamPersistenceAdminServiceStub._getServiceClient().getOptions(); + if (eventReciverOptions == null) { + eventReciverOptions = new Options(); + } + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() + .getRealmConfiguration().getAdminUserName() + "@" + tenantDomain; + JWTClient jwtClient = DeviceMgtAPIUtils.getJWTClientManagerService().getJWTClient(); + + String authValue = AUTHORIZATION_HEADER_VALUE + " " + new String(Base64.encodeBase64( + jwtClient.getJwtToken(username).getBytes())); + + List
list = new ArrayList<>(); + Header httpHeader = new Header(); + httpHeader.setName(AUTHORIZATION_HEADER); + httpHeader.setValue(authValue); + list.add(httpHeader); + + eventReciverOptions.setProperty(HTTPConstants.HTTP_HEADERS, list); + eventReciverOptions.setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER + , new Protocol(DEFAULT_HTTP_PROTOCOL + , (ProtocolSocketFactory) new SSLProtocolSocketFactory(sslContext) + , Integer.parseInt(Utils.replaceSystemProperty(DAS_PORT)))); + + eventStreamPersistenceAdminServiceStub._getServiceClient().setOptions(eventReciverOptions); + return eventStreamPersistenceAdminServiceStub; + } + + /** + * This method is used to create the Cache that holds the event definition of the device type.. + * + * @return Cachemanager + */ + public static synchronized Cache getDynamicEventCache() { + return Caching.getCacheManagerFactory().getCacheManager(EVENT_CACHE_MANAGER_NAME).getCache(EVENT_CACHE_NAME); + } + + /** + * Loads the keystore. + * + * @param keyStorePath - the path of the keystore + * @param ksPassword - the keystore password + */ + private static void loadKeyStore(String keyStorePath, String ksPassword) + throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException { + InputStream fis = null; + try { + keyStorePassword = ksPassword.toCharArray(); + keyStore = KeyStore.getInstance(KEY_STORE_TYPE); + fis = new FileInputStream(keyStorePath); + keyStore.load(fis, keyStorePassword); + } finally { + if (fis != null) { + fis.close(); + } + } + } + + /** + * Loads the trustore + * + * @param trustStorePath - the trustore path in the filesystem. + * @param tsPassword - the truststore password + */ + private static void loadTrustStore(String trustStorePath, String tsPassword) + throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException { + + InputStream fis = null; + try { + trustStore = KeyStore.getInstance(TRUST_STORE_TYPE); + fis = new FileInputStream(trustStorePath); + trustStore.load(fis, tsPassword.toCharArray()); + } finally { + if (fis != null) { + fis.close(); + } + } + } + + /** + * Initializes the SSL Context + */ + private static void initSSLConnection() throws NoSuchAlgorithmException, UnrecoverableKeyException, + KeyStoreException, KeyManagementException { + KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KEY_MANAGER_TYPE); + keyManagerFactory.init(keyStore, keyStorePassword); + TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TRUST_MANAGER_TYPE); + trustManagerFactory.init(trustStore); + + // Create and initialize SSLContext for HTTPS communication + sslContext = SSLContext.getInstance(SSLV3); + sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null); + SSLContext.setDefault(sslContext); + } + + + public static boolean isAdmin() throws UserStoreException { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); + UserRealm realmService = DeviceMgtAPIUtils.getRealmService().getTenantUserRealm(tenantId); + String adminRoleName = realmService.getRealmConfiguration().getAdminRoleName(); + String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + String[] roles = realmService.getUserStoreManager().getRoleListOfUser(userName); + for (String role: roles){ + if (role != null && role.equals(adminRoleName)){ + return true; + } + } + return false; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtUtil.java new file mode 100644 index 0000000000..c11fd758c9 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtUtil.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.util; + +import org.wso2.carbon.device.mgt.core.config.permission.Scope; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorListItem; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.beans.ProfileFeature; +import org.wso2.carbon.device.mgt.jaxrs.exception.BadRequestException; +import org.wso2.carbon.device.mgt.common.policy.mgt.Profile; + +import javax.validation.ConstraintViolation; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +public class DeviceMgtUtil { + + public static Profile convertProfile(org.wso2.carbon.device.mgt.jaxrs.beans.Profile mdmProfile) { + Profile profile = new Profile(); + profile.setTenantId(mdmProfile.getTenantId()); + profile.setCreatedDate(mdmProfile.getCreatedDate()); + profile.setDeviceType(mdmProfile.getDeviceType()); + + List profileFeatures = + new ArrayList(mdmProfile.getProfileFeaturesList().size()); + for (ProfileFeature mdmProfileFeature : mdmProfile.getProfileFeaturesList()) { + profileFeatures.add(convertProfileFeature(mdmProfileFeature)); + } + profile.setProfileFeaturesList(profileFeatures); + profile.setProfileId(mdmProfile.getProfileId()); + profile.setProfileName(mdmProfile.getProfileName()); + profile.setUpdatedDate(mdmProfile.getUpdatedDate()); + return profile; + } + + public static org.wso2.carbon.device.mgt.common.policy.mgt.ProfileFeature convertProfileFeature(ProfileFeature + mdmProfileFeature) { + + org.wso2.carbon.device.mgt.common.policy.mgt.ProfileFeature profileFeature = + new org.wso2.carbon.device.mgt.common.policy.mgt.ProfileFeature(); + profileFeature.setProfileId(mdmProfileFeature.getProfileId()); + profileFeature.setContent(mdmProfileFeature.getPayLoad()); + profileFeature.setDeviceType(mdmProfileFeature.getDeviceTypeId()); + profileFeature.setFeatureCode(mdmProfileFeature.getFeatureCode()); + profileFeature.setId(mdmProfileFeature.getId()); + return profileFeature; + + } + + public static List convertScopesListToAPIScopes(List scopes, String roleName) { + List convertedScopes = new ArrayList<>(); + Scope convertedScope; + for (String scope : scopes) { + convertedScope = new Scope(); + convertedScope.setKey(scope); + convertedScope.setRoles(roleName); + convertedScopes.add(convertedScope); + } + return convertedScopes; + } + + public static List convertAPIScopestoScopes(List scopes) { + List convertedScopes = new ArrayList<>(); + org.wso2.carbon.device.mgt.jaxrs.beans.Scope convertedScope; + for (Scope scope : scopes) { + convertedScope = new org.wso2.carbon.device.mgt.jaxrs.beans.Scope(); + convertedScope.setKey(scope.getKey()); + convertedScope.setName(scope.getName()); + convertedScope.setDescription(scope.getDescription()); + convertedScopes.add(convertedScope); + } + return convertedScopes; + } + + public static List convertAPIScopesToScopeKeys(List scopes) { + List convertedScopes = new ArrayList<>(); + for (Scope scope : scopes) { + convertedScopes.add(scope.getKey()); + } + return convertedScopes; + } + /** + * Returns a new BadRequestException + * + * @param description description of the exception + * @return a new BadRequestException with the specified details as a response DTO + */ + public static BadRequestException buildBadRequestException(String description) { + ErrorResponse errorResponse = getErrorResponse(Constants. + ErrorMessages.STATUS_BAD_REQUEST_MESSAGE_DEFAULT,400l, description); + return new BadRequestException(errorResponse); + } + + /** + * Returns generic ErrorResponse. + * @param message specific error message + * @param code + * @param description + * @return generic Response with error specific details. + */ + public static ErrorResponse getErrorResponse(String message, Long code, String description) { + ErrorResponse errorResponse = new ErrorResponse(); + errorResponse.setCode(code); + errorResponse.setMoreInfo(""); + errorResponse.setMessage(message); + errorResponse.setDescription(description); + return errorResponse; + } + + public static ErrorResponse getConstraintViolationErrorDTO(Set> violations) { + ErrorResponse errorResponse = new ErrorResponse(); + errorResponse.setDescription("Validation Error"); + errorResponse.setMessage("Bad Request"); + errorResponse.setCode(400l); + errorResponse.setMoreInfo(""); + List errorListItems = new ArrayList<>(); + for (ConstraintViolation violation : violations) { + ErrorListItem errorListItemDTO = new ErrorListItem(); + errorListItemDTO.setCode(400 + "_" + violation.getPropertyPath()); + errorListItemDTO.setMessage(violation.getPropertyPath() + ": " + violation.getMessage()); + errorListItems.add(errorListItemDTO); + } + errorResponse.setErrorItems(errorListItems); + return errorResponse; + } +} \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/MDMAndroidOperationUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/MDMAndroidOperationUtil.java new file mode 100644 index 0000000000..ce04cdc137 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/MDMAndroidOperationUtil.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.util; + +import org.wso2.carbon.device.mgt.jaxrs.beans.MobileApp; +import org.wso2.carbon.device.mgt.jaxrs.beans.android.AppStoreApplication; +import org.wso2.carbon.device.mgt.jaxrs.beans.android.EnterpriseApplication; +import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; +import org.wso2.carbon.device.mgt.core.operation.mgt.ProfileOperation; +import org.wso2.carbon.device.mgt.jaxrs.beans.android.WebApplication; +import org.wso2.carbon.device.mgt.jaxrs.exception.UnknownApplicationTypeException; + +/** + * + * This class contains the all the operations related to Android. + */ +public class MDMAndroidOperationUtil { + + /** + * This method is used to create Install Authentication operation. + * + * @param application MobileApp application + * @return operation + * + */ + public static Operation createInstallAppOperation(MobileApp application) throws UnknownApplicationTypeException { + + ProfileOperation operation = new ProfileOperation(); + operation.setCode(MDMAppConstants.AndroidConstants.OPCODE_INSTALL_APPLICATION); + operation.setType(Operation.Type.PROFILE); + + switch (application.getType()) { + case ENTERPRISE: + EnterpriseApplication enterpriseApplication = + new EnterpriseApplication(); + enterpriseApplication.setType(application.getType().toString()); + enterpriseApplication.setUrl(application.getLocation()); + operation.setPayLoad(enterpriseApplication.toJSON()); + break; + case PUBLIC: + AppStoreApplication appStoreApplication = + new AppStoreApplication(); + appStoreApplication.setType(application.getType().toString()); + appStoreApplication.setAppIdentifier(application.getIdentifier()); + operation.setPayLoad(appStoreApplication.toJSON()); + break; + case WEBAPP: + WebApplication webApplication = new WebApplication(); + webApplication.setUrl(application.getLocation()); + webApplication.setName(application.getName()); + webApplication.setType(application.getType().toString()); + operation.setPayLoad(webApplication.toJSON()); + break; + default: + throw new UnknownApplicationTypeException("Application type '" + application.getType() + + "' is not supported"); + } + return operation; + } + + /** + * This method is used to create Uninstall Authentication operation. + * @param application MobileApp application + * @return operation + */ + public static Operation createAppUninstallOperation(MobileApp application) throws UnknownApplicationTypeException { + + ProfileOperation operation = new ProfileOperation(); + operation.setCode(MDMAppConstants.AndroidConstants.OPCODE_UNINSTALL_APPLICATION); + operation.setType(Operation.Type.PROFILE); + + switch (application.getType()) { + case ENTERPRISE: + EnterpriseApplication enterpriseApplication = + new EnterpriseApplication(); + enterpriseApplication.setType(application.getType().toString()); + enterpriseApplication.setAppIdentifier(application.getAppIdentifier()); + operation.setPayLoad(enterpriseApplication.toJSON()); + break; + case PUBLIC: + AppStoreApplication appStoreApplication = + new AppStoreApplication(); + appStoreApplication.setType(application.getType().toString()); + appStoreApplication.setAppIdentifier(application.getAppIdentifier()); + operation.setPayLoad(appStoreApplication.toJSON()); + break; + case WEBAPP: + WebApplication webApplication = new WebApplication(); + webApplication.setUrl(application.getLocation()); + webApplication.setName(application.getName()); + webApplication.setType(application.getType().toString()); + operation.setPayLoad(webApplication.toJSON()); + break; + default: + throw new UnknownApplicationTypeException("Application type '" + application.getType() + + "' is not supported"); + } + return operation; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/MDMAppConstants.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/MDMAppConstants.java new file mode 100644 index 0000000000..32f3c4c2f1 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/MDMAppConstants.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.util; + +/** + * This class holds all the constants used for IOS and Android. + */ +public class MDMAppConstants { + + public class IOSConstants { + + private IOSConstants() { + throw new AssertionError(); + } + public static final String IS_REMOVE_APP = "isRemoveApp"; + public static final String IS_PREVENT_BACKUP = "isPreventBackup"; + public static final String I_TUNES_ID = "iTunesId"; + public static final String LABEL = "label"; + public static final String OPCODE_INSTALL_ENTERPRISE_APPLICATION = "INSTALL_ENTERPRISE_APPLICATION"; + public static final String OPCODE_INSTALL_STORE_APPLICATION = "INSTALL_STORE_APPLICATION"; + public static final String OPCODE_INSTALL_WEB_APPLICATION = "WEB_CLIP"; + public static final String OPCODE_REMOVE_APPLICATION = "REMOVE_APPLICATION"; + } + + public class AndroidConstants { + + private AndroidConstants() { + throw new AssertionError(); + } + public static final String OPCODE_INSTALL_APPLICATION = "INSTALL_APPLICATION"; + public static final String OPCODE_UNINSTALL_APPLICATION = "UNINSTALL_APPLICATION"; + } + + public class RegistryConstants { + + private RegistryConstants() { + throw new AssertionError(); + } + public static final String GENERAL_CONFIG_RESOURCE_PATH = "general"; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/MDMIOSOperationUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/MDMIOSOperationUtil.java new file mode 100644 index 0000000000..91ad342e5e --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/MDMIOSOperationUtil.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.util; + +import org.wso2.carbon.device.mgt.jaxrs.beans.MobileApp; +import org.wso2.carbon.device.mgt.jaxrs.beans.ios.AppStoreApplication; +import org.wso2.carbon.device.mgt.jaxrs.beans.ios.EnterpriseApplication; +import org.wso2.carbon.device.mgt.jaxrs.beans.ios.RemoveApplication; +import org.wso2.carbon.device.mgt.jaxrs.beans.ios.WebClip; +import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; +import org.wso2.carbon.device.mgt.core.operation.mgt.ProfileOperation; + +import java.util.Properties; + +/** + * This class contains the all the operations related to IOS. + */ +public class MDMIOSOperationUtil { + + /** + * This method is used to create Install Authentication operation. + * + * @param application MobileApp application + * @return operation + */ + public static Operation createInstallAppOperation(MobileApp application) { + + ProfileOperation operation = new ProfileOperation(); + + switch (application.getType()) { + case ENTERPRISE: + EnterpriseApplication enterpriseApplication = + new EnterpriseApplication(); + enterpriseApplication.setBundleId(application.getId()); + enterpriseApplication.setIdentifier(application.getIdentifier()); + enterpriseApplication.setManifestURL(application.getLocation()); + + Properties properties = application.getProperties(); + enterpriseApplication.setPreventBackupOfAppData((Boolean) properties. + get(MDMAppConstants.IOSConstants.IS_PREVENT_BACKUP)); + enterpriseApplication.setRemoveAppUponMDMProfileRemoval((Boolean) properties. + get(MDMAppConstants.IOSConstants.IS_REMOVE_APP)); + operation.setCode(MDMAppConstants.IOSConstants.OPCODE_INSTALL_ENTERPRISE_APPLICATION); + operation.setPayLoad(enterpriseApplication.toJSON()); + operation.setType(Operation.Type.COMMAND); + break; + case PUBLIC: + AppStoreApplication appStoreApplication = + new AppStoreApplication(); + appStoreApplication.setRemoveAppUponMDMProfileRemoval((Boolean) application.getProperties(). + get(MDMAppConstants.IOSConstants.IS_REMOVE_APP)); + appStoreApplication.setIdentifier(application.getIdentifier()); + appStoreApplication.setPreventBackupOfAppData((Boolean) application.getProperties(). + get(MDMAppConstants.IOSConstants.IS_PREVENT_BACKUP)); + appStoreApplication.setBundleId(application.getId()); + appStoreApplication.setiTunesStoreID((Integer) application.getProperties(). + get(MDMAppConstants.IOSConstants.I_TUNES_ID)); + operation.setCode(MDMAppConstants.IOSConstants.OPCODE_INSTALL_STORE_APPLICATION); + operation.setType(Operation.Type.COMMAND); + operation.setPayLoad(appStoreApplication.toJSON()); + break; + case WEBAPP: + WebClip webClip = new WebClip(); + webClip.setIcon(application.getIconImage()); + webClip.setIsRemovable(application.getProperties(). + getProperty(MDMAppConstants.IOSConstants.IS_REMOVE_APP)); + webClip.setLabel(application.getProperties(). + getProperty(MDMAppConstants.IOSConstants.LABEL)); + webClip.setURL(application.getLocation()); + + operation.setCode(MDMAppConstants.IOSConstants.OPCODE_INSTALL_WEB_APPLICATION); + operation.setType(Operation.Type.PROFILE); + operation.setPayLoad(webClip.toJSON()); + break; + } + return operation; + } + + public static Operation createAppUninstallOperation(MobileApp application) { + + ProfileOperation operation = new ProfileOperation(); + operation.setCode(MDMAppConstants.IOSConstants.OPCODE_REMOVE_APPLICATION); + operation.setType(Operation.Type.PROFILE); + + RemoveApplication removeApplication = + new RemoveApplication(); + removeApplication.setBundleId(application.getIdentifier()); + operation.setPayLoad(removeApplication.toJSON()); + + return operation; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/ResponsePayload.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/ResponsePayload.java new file mode 100644 index 0000000000..b7ecc5571a --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/ResponsePayload.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.util; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +public class ResponsePayload { + + private int statusCode; + private String messageFromServer; + private Object responseContent; + + @XmlElement + public int getStatusCode() { + return statusCode; + } + + public void setStatusCode(int statusCode) { + this.statusCode = statusCode; + } + + @XmlElement + public String getMessageFromServer() { + return messageFromServer; + } + + public void setMessageFromServer(String messageFromServer) { + this.messageFromServer = messageFromServer; + } + + @XmlElement + public Object getResponseContent() { + return responseContent; + } + + public void setResponseContent(Object responseContent) { + this.responseContent = responseContent; + } + + private ResponsePayloadBuilder getBuilder() { + return new ResponsePayloadBuilder(); + } + + public static ResponsePayloadBuilder statusCode(int statusCode) { + ResponsePayload message = new ResponsePayload(); + return message.getBuilder().statusCode(statusCode); + } + + public static ResponsePayloadBuilder messageFromServer(String messageFromServer) { + ResponsePayload message = new ResponsePayload(); + return message.getBuilder().messageFromServer(messageFromServer); + } + + public static ResponsePayloadBuilder responseContent(String responseContent) { + ResponsePayload message = new ResponsePayload(); + return message.getBuilder().responseContent(responseContent); + } + + public class ResponsePayloadBuilder { + + private int statusCode; + private String messageFromServer; + private Object responseContent; + + public ResponsePayloadBuilder statusCode(int statusCode) { + this.statusCode = statusCode; + return this; + } + + public ResponsePayloadBuilder messageFromServer(String messageFromServer) { + this.messageFromServer = messageFromServer; + return this; + } + + public ResponsePayloadBuilder responseContent(String responseContent) { + this.responseContent = responseContent; + return this; + } + + public ResponsePayload build() { + ResponsePayload payload = new ResponsePayload(); + payload.setStatusCode(statusCode); + payload.setMessageFromServer(messageFromServer); + payload.setResponseContent(responseContent); + return payload; + } + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/SetReferenceTransformer.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/SetReferenceTransformer.java new file mode 100644 index 0000000000..f90e8c8a3f --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/SetReferenceTransformer.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.util; + +import java.util.ArrayList; +import java.util.List; +import java.util.TreeSet; + +public class SetReferenceTransformer{ + private List objectsToRemove; + private List objectsToAdd; + + /** + * Use the Set theory to find the objects to delete and objects to add + + The difference of objects in existingSet and newSet needed to be deleted + + new roles to add = newSet - The intersection of roles in existingSet and newSet + * @param currentList + * @param nextList + */ + public void transform(List currentList, List nextList){ + TreeSet existingSet = new TreeSet(currentList); + TreeSet newSet = new TreeSet(nextList); + + existingSet.removeAll(newSet); + + objectsToRemove = new ArrayList(existingSet); + + // Clearing and re-initializing the set + existingSet = new TreeSet(currentList); + + newSet.removeAll(existingSet); + objectsToAdd = new ArrayList(newSet); + } + + public List getObjectsToRemove() { + return objectsToRemove; + } + + public List getObjectsToAdd() { + return objectsToAdd; + } +} \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/webapp/META-INF/permissions.xml b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/webapp/META-INF/permissions.xml new file mode 100644 index 0000000000..befabcd097 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/webapp/META-INF/permissions.xml @@ -0,0 +1,420 @@ + + + + + + + + + Device Management + /device-mgt + / + GET + + + + Device Management Admin + /device-mgt/admin + / + GET + + + Devices + /device-mgt/devices + / + GET + + + + List devices + /device-mgt/devices/List + /devices + GET + + + Search devices + /device-mgt/devices/Search + /devices/search-devices + POST + + + View device + /device-mgt/devices/View + /devices/*/* + GET + + + View device info + /device-mgt/devices/View + /devices/*/*/info + GET + + + View device applications + /device-mgt/devices/View-Applications + /devices/*/*/applications + GET + + + View device effective-policy + /device-mgt/devices/View-Active-Policy + /devices/*/*/effective-policy + GET + + + View devices feature + /device-mgt/devices/View-Features + /devices/*/*/features + GET + + + View device operations + /device-mgt/devices/View-Operations + /devices/*/*/operations + GET + + + View Compliance Data + /device-mgt/devices/View-Compliance-Data + /devices/*/*/compliance-data + GET + + + List all devices + /device-mgt/devices/Admin-View + /admin/devices + GET + + + Verify device authorization + /device-mgt/devices + /admin/authorization + POST + + + View device types + /device-mgt/devices/Admin-DeviceType-View + /admin/device-types + GET + + + + Policies + /device-mgt/policies + / + GET + + + + List policies + /device-mgt/policies/List + /policies + GET + + + Add Policy + /device-mgt/policies/Add + /policies + POST + + + Activate policy + /device-mgt/policies/Activate-Policy + /policies/activate-policy + PUT + + + Deactivate Policy + /device-mgt/policies/Deactivate-Policy + /policies/deactivate-policy + PUT + + + Remove Policy + /device-mgt/policies/Remove + /policies/remove-policy + POST + + + View Policy + /device-mgt/policies/View + /policies/* + GET + + + Update Policy + /device-mgt/policies/Update + /policies/* + PUT + + + Update Policy + /device-mgt/policies/Update + /policies/apply-changes + PUT + + + Update Policy + /device-mgt/policies/Change-Priority + /policies/priorities + PUT + + + + Notifications + /device-mgt/notifications + / + GET + + + + View notifications + /device-mgt/notifications/View + /notifications + GET + + + Mark checked notifications + /device-mgt/notifications/View + /notifications/*/mark-checked + PUT + + + + Users + /device-mgt/users + / + GET + + + + List users + /device-mgt/users/List + /users + GET + + + Add user + /device-mgt/users/Add + /users + POST + + + List users + /device-mgt/users/Search + /users/search/usernames + GET + + + Remove user + /device-mgt/users/Remove + /users/* + DELETE + + + View user + /device-mgt/users/View + /users/* + GET + + + Update user + /device-mgt/users/Update + /users/* + PUT + + + Update user credentials + /device-mgt/users/Change-Password + /users/*/credentials + PUT + + + View assigned role + /device-mgt/roles/Assigned-Roles + /users/*/roles + GET + + + Change any user credentials + /device-mgt/users/Change-Password-Any + /admin/users/*/credentials + POST + + + Send invitation mail + /device-mgt/users/Send-invitations + /users/send-invitation + POST + + + + Roles + /device-mgt/roles + / + GET + + + + List roles + /device-mgt/roles/List + /roles + GET + + + Add role + /device-mgt/roles/Add + /roles + POST + + + Remove role + /device-mgt/roles/Remove + /roles/* + DELETE + + + View role + /device-mgt/roles/View + /roles/* + GET + + + Update role + /device-mgt/roles/Update + /roles/* + PUT + + + View role permissions + /device-mgt/roles/View-Permission + /roles/*/permissions + GET + + + Add Users to role + /device-mgt/roles/Add-Users + /roles/*/users + PUT + + + + Configurations + /device-mgt/general-configs + / + GET + + + + View configuration + /device-mgt/general-configuration/View + /configuration + GET + + + Update configuration + /device-mgt/general-configuration/Update + /configuration + PUT + + + + Activities + /device-mgt/activities + / + GET + + + + View Activities + /device-mgt/devices/owning/view + /activities + GET + + + View Activity Details + /device-mgt/devices/owning/view + /activities/* + GET + + + + Applications + /device-mgt/applications + / + GET + + + + Install Applications + /device-mgt/application/Install + /admin/applications/install-application + POST + + + Uninstall-Applications + /device-mgt/application/Uninstall + /admin/applications/uninstall-application + POST + + + + + + Device Management User + /device-mgt/user + / + GET + + + User Devices + /device-mgt/user/devices + / + GET + + + User Policies + /device-mgt/user/policies + / + GET + + + User Notifications + /device-mgt/user/notifications + / + GET + + + User Operations + /device-mgt/user/operations + / + GET + + + + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/webapp/META-INF/webapp-classloading.xml b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/webapp/META-INF/webapp-classloading.xml new file mode 100644 index 0000000000..ed2ed21624 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/webapp/META-INF/webapp-classloading.xml @@ -0,0 +1,35 @@ + + + + + + + + + false + + + CXF,Carbon + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/webapp/WEB-INF/cxf-servlet.xml b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/webapp/WEB-INF/cxf-servlet.xml new file mode 100644 index 0000000000..550da9fb27 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/webapp/WEB-INF/cxf-servlet.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/webapp/WEB-INF/web.xml b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..b23f60be4c --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,119 @@ + + + + Admin-Webapp + + JAX-WS/JAX-RS Device Management Endpoint + JAX-WS/JAX-RS Servlet + CXFServlet + + org.apache.cxf.transport.servlet.CXFServlet + + + + swagger.security.filter + ApiAuthorizationFilterImpl + + 1 + + + CXFServlet + /* + + + 60 + + + + doAuthentication + true + + + + + managed-api-enabled + true + + + managed-api-owner + admin + + + isSharedWithAllTenants + true + + + + + + DeviceMgt-Admin + /* + + + CONFIDENTIAL + + + + + ApiOriginFilter + org.wso2.carbon.device.mgt.jaxrs.ApiOriginFilter + + + + HttpHeaderSecurityFilter + org.apache.catalina.filters.HttpHeaderSecurityFilter + + hstsEnabled + false + + + + + ContentTypeBasedCachePreventionFilter + org.wso2.carbon.ui.filters.cache.ContentTypeBasedCachePreventionFilter + + patterns + text/html" ,application/json" ,text/plain + + + filterAction + enforce + + + httpHeaders + Cache-Control: no-store, no-cache, must-revalidate, private + + + + + HttpHeaderSecurityFilter + /* + + + + ContentTypeBasedCachePreventionFilter + /* + + + + ApiOriginFilter + /* + + + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/ConfigurationServiceImplTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/ConfigurationServiceImplTest.java new file mode 100644 index 0000000000..5a4b0cd13b --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/ConfigurationServiceImplTest.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ + +package org.wso2.carbon.device.mgt.jaxrs.service.impl; + +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; +import org.testng.Assert; +import org.testng.IObjectFactory; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.ObjectFactory; +import org.testng.annotations.Test; +import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry; +import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException; +import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration; +import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfigurationManagementService; +import org.wso2.carbon.device.mgt.jaxrs.service.api.ConfigurationManagementService; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; +import org.wso2.carbon.policy.mgt.core.util.PolicyManagerUtil; + +import javax.ws.rs.core.Response; +import java.util.ArrayList; +import java.util.List; + +/** + * This is a test class for {@link ConfigurationServiceImpl}. + */ +@PowerMockIgnore("javax.ws.rs.*") +@SuppressStaticInitializationFor({"org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils", + "org.wso2.carbon.context.CarbonContext"}) +@PrepareForTest({DeviceMgtAPIUtils.class, PolicyManagerUtil.class}) +public class ConfigurationServiceImplTest { + private ConfigurationManagementService configurationManagementService; + private PlatformConfigurationManagementService platformConfigurationManagementService; + private PlatformConfiguration platformConfiguration; + + @ObjectFactory + public IObjectFactory getObjectFactory() { + return new org.powermock.modules.testng.PowerMockObjectFactory(); + } + + @BeforeClass + public void init() { + configurationManagementService = new ConfigurationServiceImpl(); + platformConfigurationManagementService = Mockito.mock(PlatformConfigurationManagementService.class); + platformConfiguration = new PlatformConfiguration(); + platformConfiguration.setType("test"); + } + + @Test(description = "This method tests the getConfiguration method of ConfigurationManagementService under valid " + + "conditions") + public void testGetConfigurationWithSuccessConditions() throws ConfigurationManagementException { + PowerMockito.stub(PowerMockito.method(PolicyManagerUtil.class, "getMonitoringFrequency")).toReturn(60); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getPlatformConfigurationManagementService")) + .toReturn(platformConfigurationManagementService); + Mockito.doReturn(platformConfiguration).when(platformConfigurationManagementService) + .getConfiguration(Mockito.any()); + Response response = configurationManagementService.getConfiguration("test"); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "getConfiguration request " + "failed with valid parameters"); + + List configurationEntryList = new ArrayList<>(); + ConfigurationEntry configurationEntry = new ConfigurationEntry(); + configurationEntry.setContentType("String"); + configurationEntry.setName("test"); + configurationEntry.setValue("test"); + configurationEntryList.add(configurationEntry); + platformConfiguration.setConfiguration(configurationEntryList); + Mockito.reset(platformConfigurationManagementService); + Mockito.doReturn(platformConfiguration).when(platformConfigurationManagementService) + .getConfiguration(Mockito.any()); + response = configurationManagementService.getConfiguration("test"); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "getConfiguration request " + "failed with valid parameters"); + } + + @Test(description = "This method tests the getConfiguration method under negative conditions") + public void testGetConfigurationUnderNegativeConditions() throws ConfigurationManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getPlatformConfigurationManagementService")) + .toReturn(platformConfigurationManagementService); + Mockito.reset(platformConfigurationManagementService); + Mockito.doThrow(new ConfigurationManagementException()).when(platformConfigurationManagementService) + .getConfiguration(Mockito.any()); + Response response = configurationManagementService.getConfiguration("test"); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "getConfiguration request " + "succeeded under negative conditions"); + } + + @Test(description = "This method tests the updateConfiguration method under valid conditions.", dependsOnMethods + = {"testGetConfigurationWithSuccessConditions"}) + public void testUpdateConfigurationUnderValidConditions() throws ConfigurationManagementException { + Mockito.reset(platformConfigurationManagementService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getPlatformConfigurationManagementService")) + .toReturn(platformConfigurationManagementService); + PowerMockito + .stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getNotifierFrequency", PlatformConfiguration.class)) + .toReturn(60); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "scheduleTaskService", int.class)) + .toReturn(null); + Mockito.doReturn(platformConfiguration).when(platformConfigurationManagementService) + .getConfiguration(Mockito.any()); + Mockito.doReturn(true).when(platformConfigurationManagementService) + .saveConfiguration(Mockito.any(), Mockito.any()); + Response response = configurationManagementService.updateConfiguration(platformConfiguration); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "updateConfiguration request failed with valid parameters"); + } + + @Test(description = "This method tests the updateConfiguration method under negative conditions.", + dependsOnMethods = {"testGetConfigurationWithSuccessConditions"}) + public void testUpdateConfigurationUnderNegativeConditions() throws ConfigurationManagementException { + Mockito.reset(platformConfigurationManagementService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getPlatformConfigurationManagementService")) + .toReturn(platformConfigurationManagementService); + Mockito.doThrow(new ConfigurationManagementException()).when(platformConfigurationManagementService) + .saveConfiguration(Mockito.any(), Mockito.any()); + Response response = configurationManagementService.updateConfiguration(platformConfiguration); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "updateConfiguration request succeeded with in-valid parameters"); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceTest.java new file mode 100644 index 0000000000..efd573b11f --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceTest.java @@ -0,0 +1,1102 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ +package org.wso2.carbon.device.mgt.jaxrs.service.impl; + +import org.apache.axis2.AxisFault; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; +import org.testng.Assert; +import org.testng.IObjectFactory; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.ObjectFactory; +import org.testng.annotations.Test; +import org.wso2.carbon.base.MultitenantConstants; +import org.wso2.carbon.caching.impl.CacheImpl; +import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.analytics.data.publisher.exception.DataPublisherConfigurationException; +import org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherService; +import org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherServiceImpl; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.EnrolmentInfo; +import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException; +import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService; +import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; +import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException; +import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.PolicyComplianceException; +import org.wso2.carbon.device.mgt.core.authorization.DeviceAccessAuthorizationServiceImpl; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderServiceImpl; +import org.wso2.carbon.device.mgt.jaxrs.service.api.DeviceAgentService; +import org.wso2.carbon.device.mgt.jaxrs.service.api.admin.DeviceTypeManagementAdminService; +import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.DeviceMgtAPITestHelper; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; +import org.wso2.carbon.event.stream.stub.EventStreamAdminServiceStub; +import org.wso2.carbon.event.stream.stub.types.EventStreamAttributeDto; +import org.wso2.carbon.event.stream.stub.types.EventStreamDefinitionDto; +import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; +import org.wso2.carbon.policy.mgt.core.PolicyManagerService; +import org.wso2.carbon.policy.mgt.core.PolicyManagerServiceImpl; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.utils.CarbonUtils; + +import javax.cache.CacheManager; +import javax.ws.rs.core.Response; +import java.rmi.RemoteException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.mockito.MockitoAnnotations.initMocks; + +/** + * This class holds the unit tests for the class {@link DeviceAgentServiceImpl} + */ +@PowerMockIgnore("javax.ws.rs.*") +@SuppressStaticInitializationFor({"org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils", + "org.wso2.carbon.context.CarbonContext", "org.wso2.carbon.context.internal.CarbonContextDataHolder"}) +@PrepareForTest({DeviceMgtAPIUtils.class, DeviceManagementProviderService.class, + DeviceAccessAuthorizationService.class, EventStreamAdminServiceStub.class, PrivilegedCarbonContext.class, + CarbonContext.class, CarbonUtils.class}) +public class DeviceAgentServiceTest { + + private static final Log log = LogFactory.getLog(DeviceTypeManagementAdminService.class); + private DeviceManagementProviderService deviceManagementProviderService; + private DeviceAgentService deviceAgentService; + private EventStreamAdminServiceStub eventStreamAdminServiceStub; + private PrivilegedCarbonContext privilegedCarbonContext; + private CarbonContext carbonContext; + private CacheManager cacheManager; + private DeviceAccessAuthorizationService deviceAccessAuthorizationService; + private static final String TEST_DEVICE_TYPE = "TEST-DEVICE-TYPE"; + private static final String TEST_DEVICE_IDENTIFIER = "11222334455"; + private static final String AUTHENTICATED_USER = "admin"; + private static final String MONITOR_OPERATION = "POLICY_MONITOR"; + private static Device demoDevice; + + @ObjectFactory + public IObjectFactory getObjectFactory() { + return new org.powermock.modules.testng.PowerMockObjectFactory(); + } + + @BeforeClass + public void init() { + log.info("Initializing DeviceAgent tests"); + initMocks(this); + this.deviceManagementProviderService = Mockito + .mock(DeviceManagementProviderServiceImpl.class, Mockito.RETURNS_MOCKS); + this.deviceAgentService = new DeviceAgentServiceImpl(); + this.deviceAccessAuthorizationService = Mockito.mock(DeviceAccessAuthorizationServiceImpl.class, + Mockito.RETURNS_MOCKS); + this.privilegedCarbonContext = Mockito.mock(PrivilegedCarbonContext.class, Mockito.RETURNS_MOCKS); + this.carbonContext = Mockito.mock(CarbonContext.class, Mockito.RETURNS_MOCKS); + this.eventStreamAdminServiceStub = Mockito.mock(EventStreamAdminServiceStub.class, Mockito.RETURNS_MOCKS); + demoDevice = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + this.cacheManager = Mockito.mock(CacheManager.class, Mockito.RETURNS_MOCKS); + } + + @Test(description = "Test device Enrollment when the device is null") + public void testEnrollDeviceWithNullDevice() { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Response response = this.deviceAgentService.enrollDevice(null); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "The response status should be 400"); + } + + @Test(description = "Test device enrollment when device type is null.") + public void testEnrollDeviceWithNullDeviceType() { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Device device = DeviceMgtAPITestHelper.generateDummyDevice(null, TEST_DEVICE_IDENTIFIER); + Response response = this.deviceAgentService.enrollDevice(device); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "The response status should be 400"); + } + + @Test(description = "Test device enrollment of a device with null device identifier.") + public void testEnrollNewDeviceWithNullDeviceIdentifier() { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Device device = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, null); + Response response = this.deviceAgentService.enrollDevice(device); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "The response status should be 400"); + } + + @Test(description = "Test an already enrolled device") + public void testEnrollExistingDevice() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(demoDevice); + Device device = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(device); + Response response = this.deviceAgentService.enrollDevice(device); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "The response status should be 400"); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Test the device enrollment success scenario.") + public void testEnrollDeviceSuccess() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getAuthenticatedUser")) + .toReturn(AUTHENTICATED_USER); + EnrolmentInfo enrolmentInfo = demoDevice.getEnrolmentInfo(); + enrolmentInfo.setStatus(EnrolmentInfo.Status.INACTIVE); + demoDevice.setEnrolmentInfo(enrolmentInfo); + Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(demoDevice); + Response response = this.deviceAgentService.enrollDevice(demoDevice); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "The response status should be 200"); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Test the device enrollment with device management exception.") + public void testEnrollDeviceWithDeviceManagementException() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getAuthenticatedUser")) + .toReturn(AUTHENTICATED_USER); + Device device = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + EnrolmentInfo enrolmentInfo = device.getEnrolmentInfo(); + enrolmentInfo.setStatus(EnrolmentInfo.Status.INACTIVE); + device.setEnrolmentInfo(enrolmentInfo); + Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(device); + Mockito.when(this.deviceManagementProviderService.enrollDevice(Mockito.any())) + .thenThrow(new DeviceManagementException()); + Response response = this.deviceAgentService.enrollDevice(device); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Test dis-enrolling the device success scenario.") + public void testDisEnrollDeviceSuccess() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(this.deviceManagementProviderService.disenrollDevice(Mockito.any())).thenReturn(true); + Response response = deviceAgentService.disEnrollDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "The response status should be 200"); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Test dis-enrolling non existing device.") + public void testDisEnrollWithNonExistingDevice() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Response response = deviceAgentService.disEnrollDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.NO_CONTENT.getStatusCode(), + "The response status should be 204"); + } + + @Test(description = "Test dis-enrolling device where device management exception is thrown.") + public void testDisEnrollingDeviceWithDeviceManagementException() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(this.deviceManagementProviderService.disenrollDevice(Mockito.any())).thenThrow(new + DeviceManagementException()); + Response response = deviceAgentService.disEnrollDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Test device update scenario with device management exception.") + public void testUpdateDeviceWithDeviceManagementException() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenThrow(new + DeviceManagementException()); + Device testDevice = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Response response = deviceAgentService.updateDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER, testDevice); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Test update device scenario when the device is null.") + public void testUpdateDeviceWithNoDevice() { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Response response = deviceAgentService.updateDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER, null); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "The response status should be 400"); + } + + @Test(description = "Test the update device scenario when there is no enrolled device.") + public void testUpdateDeviceWithNonExistingDevice() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(null); + Device testDevice = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Response response = deviceAgentService.updateDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER, testDevice); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode(), + "The response status should be 404"); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Test update device with device access authorization exception.") + public void testEnrollDeviceWithDeviceAccessAuthorizationException() throws DeviceManagementException, + DeviceAccessAuthorizationException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, + "getDeviceAccessAuthorizationService")).toReturn(this.deviceAccessAuthorizationService); + Device testDevice = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(testDevice); + Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class))) + .thenThrow(new DeviceAccessAuthorizationException()); + Response response = deviceAgentService.updateDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER, testDevice); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + Mockito.reset(this.deviceManagementProviderService); + Mockito.reset(this.deviceAccessAuthorizationService); + } + + @Test(description = "Test update device when user does not have device access permission.") + public void testUpdateDeviceWithNoDeviceAccessPermission() throws DeviceManagementException, + DeviceAccessAuthorizationException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, + "getDeviceAccessAuthorizationService")).toReturn(this.deviceAccessAuthorizationService); + Device testDevice = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(testDevice); + Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class))) + .thenReturn(false); + Response response = deviceAgentService.updateDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER, testDevice); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.UNAUTHORIZED.getStatusCode(), + "The response status should be 401"); + Mockito.reset(this.deviceManagementProviderService); + Mockito.reset(this.deviceAccessAuthorizationService); + } + + @Test(description = "Test update device when device modification is unsuccessful.") + public void testUpdateDeviceWithUnsuccessfulDeviceModification() throws DeviceManagementException, + DeviceAccessAuthorizationException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, + "getDeviceAccessAuthorizationService")).toReturn(this.deviceAccessAuthorizationService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, + "getAuthenticatedUser")).toReturn(AUTHENTICATED_USER); + Device testDevice = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(testDevice); + Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class))) + .thenReturn(true); + Mockito.when(this.deviceManagementProviderService.modifyEnrollment(Mockito.any())).thenReturn(false); + Response response = deviceAgentService.updateDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER, testDevice); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.NOT_MODIFIED.getStatusCode(), + "The response status should be 304"); + Mockito.reset(this.deviceManagementProviderService); + Mockito.reset(this.deviceAccessAuthorizationService); + } + + @Test(description = "Test updating device when modify enrollment throws exception") + public void testUpdateDeviceWithModifyEnrollmentFailure() throws DeviceManagementException, + DeviceAccessAuthorizationException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, + "getDeviceAccessAuthorizationService")).toReturn(this.deviceAccessAuthorizationService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, + "getAuthenticatedUser")).toReturn(AUTHENTICATED_USER); + Device testDevice = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(testDevice); + Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class))) + .thenReturn(true); + Mockito.when(this.deviceManagementProviderService.modifyEnrollment(Mockito.any())) + .thenThrow(new DeviceManagementException()); + Response response = deviceAgentService.updateDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER, testDevice); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + Mockito.reset(this.deviceManagementProviderService); + Mockito.reset(this.deviceAccessAuthorizationService); + } + + @Test(description = "Test updating device success scenario.") + public void testUpdateDeviceSuccess() throws DeviceManagementException, DeviceAccessAuthorizationException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, + "getDeviceAccessAuthorizationService")).toReturn(this.deviceAccessAuthorizationService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, + "getAuthenticatedUser")).toReturn(AUTHENTICATED_USER); + Device testDevice = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(testDevice); + Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class))) + .thenReturn(true); + Mockito.when(this.deviceManagementProviderService.modifyEnrollment(Mockito.any())).thenReturn((true)); + Response response = deviceAgentService.updateDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER, testDevice); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.ACCEPTED.getStatusCode(), + "The response status should be 202"); + Mockito.reset(this.deviceManagementProviderService); + Mockito.reset(this.deviceAccessAuthorizationService); + } + + @Test(description = "Test publish events with null payload.") + public void testPublishEventsWithNullPayload() { + PowerMockito.stub(PowerMockito.method(PrivilegedCarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(this.privilegedCarbonContext); + Mockito.when(this.privilegedCarbonContext.getTenantDomain()) + .thenReturn(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME); + Map payload = null; + Response response = this.deviceAgentService.publishEvents(payload, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "The response status should be 400"); + List payloadList = null; + Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE, + TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response2, "Response should not be null"); + Assert.assertEquals(response2.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "The response status should be 400"); + } + + @Test(description = "Test publish events with no device access authorization.") + public void testPublishEventsWithoutAuthorization() throws DeviceAccessAuthorizationException { + PowerMockito.stub(PowerMockito.method(PrivilegedCarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(this.privilegedCarbonContext); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, + "getDeviceAccessAuthorizationService")).toReturn(this.deviceAccessAuthorizationService); + Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class))) + .thenReturn(false); + Mockito.when(this.privilegedCarbonContext.getTenantDomain()) + .thenReturn(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME); + Map payload = new HashMap<>(); + Response response = this.deviceAgentService.publishEvents(payload, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.UNAUTHORIZED.getStatusCode(), + "The response status should be 401"); + List payloadList = new ArrayList<>(); + Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE, + TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response2, "Response should not be null"); + Assert.assertEquals(response2.getStatus(), Response.Status.UNAUTHORIZED.getStatusCode(), + "The response status should be 401"); + Mockito.reset(this.deviceAccessAuthorizationService); + } + + @Test(description = "Test publish events when device access authorization exception is thrown.") + public void testPublishEventsWithDeviceAccessAuthorizationException() throws DeviceAccessAuthorizationException { + PowerMockito.stub(PowerMockito.method(PrivilegedCarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(this.privilegedCarbonContext); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, + "getDeviceAccessAuthorizationService")).toReturn(this.deviceAccessAuthorizationService); + Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class))) + .thenThrow(new DeviceAccessAuthorizationException()); + Mockito.when(this.privilegedCarbonContext.getTenantDomain()) + .thenReturn(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME); + Map payload = new HashMap<>(); + Response response = this.deviceAgentService.publishEvents(payload, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + List payloadList = new ArrayList<>(); + Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE, + TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response2, "Response should not be null"); + Assert.assertEquals(response2.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + Mockito.reset(this.deviceAccessAuthorizationService); + } + + @Test(description = "Test event publishing when the event stream dao is null.") + public void testEventPublishWithNullEventAttributesAndNullEventStreamDefDAO() + throws DeviceAccessAuthorizationException, RemoteException { + PowerMockito.stub(PowerMockito.method(PrivilegedCarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(this.privilegedCarbonContext); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, + "getDeviceAccessAuthorizationService")).toReturn(this.deviceAccessAuthorizationService); + Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class))) + .thenReturn(true); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getEventStreamAdminServiceStub")) + .toReturn(this.eventStreamAdminServiceStub); + Mockito.when(this.eventStreamAdminServiceStub.getStreamDefinitionDto(Mockito.anyString())).thenReturn(null); + Map payload = new HashMap<>(); + CacheImpl cache = Mockito.mock(CacheImpl.class); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDynamicEventCache")) + .toReturn(cache); + Response response = this.deviceAgentService.publishEvents(payload, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "The response status should be 400"); + List payloadList = new ArrayList<>(); + Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE, + TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response2, "Response should not be null"); + Assert.assertEquals(response2.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "The response status should be 400"); + Mockito.reset(eventStreamAdminServiceStub); + } + + @Test(description = "Test the error scenario of Publishing Events with null event attributes.") + public void testEventPublishWithEventAttributesNULLAndPublishEventsFailure() throws + DeviceAccessAuthorizationException, RemoteException { + PowerMockito.stub(PowerMockito.method(PrivilegedCarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(this.privilegedCarbonContext); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, + "getDeviceAccessAuthorizationService")).toReturn(this.deviceAccessAuthorizationService); + Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class))) + .thenReturn(true); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getEventStreamAdminServiceStub")) + .toReturn(this.eventStreamAdminServiceStub); + EventStreamAttributeDto eventStreamAttributeDto = Mockito.mock(EventStreamAttributeDto.class, + Mockito.RETURNS_MOCKS); + EventStreamDefinitionDto eventStreamDefinitionDto = Mockito.mock(EventStreamDefinitionDto.class, + Mockito.RETURNS_MOCKS); + Mockito.when(this.eventStreamAdminServiceStub.getStreamDefinitionDto(Mockito.anyString())) + .thenReturn(eventStreamDefinitionDto); + Mockito.when(eventStreamDefinitionDto.getPayloadData()).thenReturn(new EventStreamAttributeDto[]{}); + EventsPublisherService eventPublisherService = Mockito.mock(EventsPublisherServiceImpl.class, + Mockito.RETURNS_MOCKS); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getEventPublisherService")) + .toReturn(eventPublisherService); + Map payload = new HashMap<>(); + CacheImpl cache = Mockito.mock(CacheImpl.class); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDynamicEventCache")) + .toReturn(cache); + Response response = this.deviceAgentService.publishEvents(payload, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + List payloadList = new ArrayList<>(); + Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE, + TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response2, "Response should not be null"); + Assert.assertEquals(response2.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + } + + @Test(description = "Test Event publishing success scenario.") + public void testEventPublishWithEventAttributesNULLAndPublishEventsSuccess() + throws DeviceAccessAuthorizationException, RemoteException, DataPublisherConfigurationException { + PowerMockito.stub(PowerMockito.method(PrivilegedCarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(this.privilegedCarbonContext); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, + "getDeviceAccessAuthorizationService")).toReturn(this.deviceAccessAuthorizationService); + Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class))) + .thenReturn(true); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getEventStreamAdminServiceStub")) + .toReturn(this.eventStreamAdminServiceStub); + EventStreamAttributeDto eventStreamAttributeDto = Mockito.mock(EventStreamAttributeDto.class, + Mockito.RETURNS_MOCKS); + EventStreamDefinitionDto eventStreamDefinitionDto = Mockito.mock(EventStreamDefinitionDto.class, + Mockito.RETURNS_MOCKS); + Mockito.when(this.eventStreamAdminServiceStub.getStreamDefinitionDto(Mockito.anyString())) + .thenReturn(eventStreamDefinitionDto); + Mockito.when(eventStreamDefinitionDto.getPayloadData()).thenReturn(new EventStreamAttributeDto[]{}); + EventsPublisherService eventPublisherService = Mockito.mock(EventsPublisherServiceImpl.class, + Mockito.RETURNS_MOCKS); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getEventPublisherService")) + .toReturn(eventPublisherService); + Mockito.when(eventPublisherService.publishEvent(Mockito.anyString(), Mockito.anyString(), Mockito.any(), + Mockito.any(), Mockito.any())).thenReturn(true); + Map payload = new HashMap<>(); + CacheImpl cache = Mockito.mock(CacheImpl.class); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDynamicEventCache")) + .toReturn(cache); + Response response = this.deviceAgentService.publishEvents(payload, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "The response status should be 200"); + List payloadList = new ArrayList<>(); + Response response2 = this.deviceAgentService.publishEvents(payloadList, + TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response2, "Response should not be null"); + Assert.assertEquals(response2.getStatus(), Response.Status.OK.getStatusCode(), + "The response status should be 200"); + } + + @Test(description = "Test event publishing when PublishEvents throws DataPublisherConfigurationException.") + public void testPublishEventsDataPublisherConfigurationException() throws DeviceAccessAuthorizationException, + RemoteException, DataPublisherConfigurationException { + PowerMockito.stub(PowerMockito.method(PrivilegedCarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(this.privilegedCarbonContext); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, + "getDeviceAccessAuthorizationService")).toReturn(this.deviceAccessAuthorizationService); + Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class))) + .thenReturn(true); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getEventStreamAdminServiceStub")) + .toReturn(this.eventStreamAdminServiceStub); + EventStreamAttributeDto eventStreamAttributeDto = Mockito.mock(EventStreamAttributeDto.class, + Mockito.RETURNS_MOCKS); + EventStreamDefinitionDto eventStreamDefinitionDto = Mockito.mock(EventStreamDefinitionDto.class, + Mockito.RETURNS_MOCKS); + Mockito.when(this.eventStreamAdminServiceStub.getStreamDefinitionDto(Mockito.anyString())) + .thenReturn(eventStreamDefinitionDto); + Mockito.when(eventStreamDefinitionDto.getPayloadData()).thenReturn(new EventStreamAttributeDto[]{}); + EventsPublisherService eventPublisherService = Mockito.mock(EventsPublisherServiceImpl.class, + Mockito.RETURNS_MOCKS); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getEventPublisherService")) + .toReturn(eventPublisherService); + Mockito.when(eventPublisherService.publishEvent(Mockito.anyString(), Mockito.anyString(), Mockito.any(), + Mockito.any(), Mockito.any())).thenThrow( + new DataPublisherConfigurationException("meta data[0] should have the device Id field")); + Map payload = new HashMap<>(); + CacheImpl cache = Mockito.mock(CacheImpl.class); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDynamicEventCache")) + .toReturn(cache); + Response response = this.deviceAgentService.publishEvents(payload, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + List payloadList = new ArrayList<>(); + Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE, + TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response2, "Response should not be null"); + Assert.assertEquals(response2.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + } + + @Test(description = "Test Publish events with Axis Fault.") + public void testPublishEventsWithAxisFault() throws DeviceAccessAuthorizationException { + PowerMockito.stub(PowerMockito.method(PrivilegedCarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(this.privilegedCarbonContext); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, + "getDeviceAccessAuthorizationService")).toReturn(this.deviceAccessAuthorizationService); + Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class))) + .thenReturn(true); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getEventStreamAdminServiceStub")) + .toThrow(new AxisFault("")); + Map payload = new HashMap<>(); + CacheImpl cache = Mockito.mock(CacheImpl.class); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDynamicEventCache")) + .toReturn(cache); + Response response = this.deviceAgentService.publishEvents(payload, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + List payloadList = new ArrayList<>(); + Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE, + TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response2, "Response should not be null"); + Assert.assertEquals(response2.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + } + + @Test(description = "Test Publishing events when EventStreamAdminService throws Remote exception.") + public void testPublishEventsWithRemoteException() throws DeviceAccessAuthorizationException { + PowerMockito.stub(PowerMockito.method(PrivilegedCarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(this.privilegedCarbonContext); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, + "getDeviceAccessAuthorizationService")).toReturn(this.deviceAccessAuthorizationService); + Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class))) + .thenReturn(true); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getEventStreamAdminServiceStub")) + .toThrow(new RemoteException()); + Map payload = new HashMap<>(); + CacheImpl cache = Mockito.mock(CacheImpl.class); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDynamicEventCache")) + .toReturn(cache); + + Response response = this.deviceAgentService.publishEvents(payload, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + + List payloadList = new ArrayList<>(); + Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE, + TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response2, "Response should not be null"); + Assert.assertEquals(response2.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + } + + @Test(description = "Test Publishing events when EventStreamAdminService throws JWT exception.") + public void testPublishEventsWithJWTException() throws DeviceAccessAuthorizationException { + PowerMockito.stub(PowerMockito.method(PrivilegedCarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(this.privilegedCarbonContext); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, + "getDeviceAccessAuthorizationService")).toReturn(this.deviceAccessAuthorizationService); + Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class))) + .thenReturn(true); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getEventStreamAdminServiceStub")) + .toThrow(new JWTClientException()); + Map payload = new HashMap<>(); + CacheImpl cache = Mockito.mock(CacheImpl.class); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDynamicEventCache")) + .toReturn(cache); + + Response response = this.deviceAgentService.publishEvents(payload, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + + List payloadList = new ArrayList<>(); + Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE, + TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response2, "Response should not be null"); + Assert.assertEquals(response2.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + } + + @Test(description = "Test Publishing events when EventStreamAdminService throws User Store exception.") + public void testPublishEventsWithUserStoreException() throws DeviceAccessAuthorizationException { + PowerMockito.stub(PowerMockito.method(PrivilegedCarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(this.privilegedCarbonContext); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, + "getDeviceAccessAuthorizationService")).toReturn(this.deviceAccessAuthorizationService); + Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class))) + .thenReturn(true); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getEventStreamAdminServiceStub")) + .toThrow(new UserStoreException()); + Map payload = new HashMap<>(); + CacheImpl cache = Mockito.mock(CacheImpl.class); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDynamicEventCache")) + .toReturn(cache); + + Response response = this.deviceAgentService.publishEvents(payload, TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + + List payloadList = new ArrayList<>(); + Response response2 = this.deviceAgentService.publishEvents(payloadList, TEST_DEVICE_TYPE, + TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response2, "Response should not be null"); + Assert.assertEquals(response2.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + } + + @Test(description = "Test the get pending operation method which return empty device type list.") + public void testGetPendingOperationsWithNoDeviceType() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()) + .thenReturn(new ArrayList() { + }); + Response response = this.deviceAgentService.getPendingOperations(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "The response status should be 400"); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Test the get pending operation method with invalid device identifier.") + public void testGetPendingOperationsWithInvalidDeviceIdentifier() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "isValidDeviceIdentifier")) + .toReturn(false); + List deviceTypes = new ArrayList<>(); + deviceTypes.add(TEST_DEVICE_TYPE); + Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes); + Response response = this.deviceAgentService.getPendingOperations(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.NO_CONTENT.getStatusCode(), + "The response status should be 204"); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Test the get pending operations success scenario.") + public void testGetPendingOperationsSuccess() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "isValidDeviceIdentifier")) + .toReturn(true); + List deviceTypes = new ArrayList<>(); + deviceTypes.add(TEST_DEVICE_TYPE); + Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes); + Response response = this.deviceAgentService.getPendingOperations(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertNotNull(response.getEntity(), "Response entity should not be null."); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "The response status should be 200"); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Test the scenario when get pending operations throw OperationManagementException.") + public void testGetPendingOperationsWithOperationManagementException() throws DeviceManagementException, + OperationManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "isValidDeviceIdentifier")) + .toReturn(true); + List deviceTypes = new ArrayList<>(); + deviceTypes.add(TEST_DEVICE_TYPE); + Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes); + Mockito.when(this.deviceManagementProviderService.getPendingOperations(Mockito.any())).thenThrow(new + OperationManagementException()); + Response response = this.deviceAgentService.getPendingOperations(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertNotNull(response.getEntity(), "Response entity should not be null."); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Test the scenario when getAvailableDeviceTypes throw DeviceManagementException.") + public void testGetPendingOperationsWithDeviceManagementException() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "isValidDeviceIdentifier")) + .toReturn(true); + Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()) + .thenThrow(new DeviceManagementException()); + Response response = this.deviceAgentService.getPendingOperations(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertNotNull(response.getEntity(), "Response entity should not be null."); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Test get next pending operation with device type is invalid.") + public void getNextPendingOperationWithInvalidDeviceType() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()) + .thenReturn(new ArrayList() {}); + Response response = this.deviceAgentService.getNextPendingOperation(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "The response status should be 400"); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Test get next pending operation with invalid device identifier.") + public void getNextPendingOperationWithInvalidDeviceIdentifier() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "isValidDeviceIdentifier")) + .toReturn(false); + List deviceTypes = new ArrayList<>(); + deviceTypes.add(TEST_DEVICE_TYPE); + Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes); + Response response = this.deviceAgentService.getNextPendingOperation(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "The response status should be 400"); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Test the getNextPendingOperation success scenario.") + public void testGetNextPendingOperationSuccess() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "isValidDeviceIdentifier")) + .toReturn(true); + List deviceTypes = new ArrayList<>(); + deviceTypes.add(TEST_DEVICE_TYPE); + Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes); + Response response = this.deviceAgentService.getNextPendingOperation(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertNotNull(response.getEntity(), "Response entity should not be null."); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "The response status should be 200"); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Test get next pending operation with operation management exception.") + public void getNextPendingOperationWithOperationManagementException() throws DeviceManagementException, + OperationManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "isValidDeviceIdentifier")) + .toReturn(true); + List deviceTypes = new ArrayList<>(); + deviceTypes.add(TEST_DEVICE_TYPE); + Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes); + Mockito.when(this.deviceManagementProviderService.getNextPendingOperation(Mockito.any())).thenThrow( + new OperationManagementException()); + Response response = this.deviceAgentService.getNextPendingOperation(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertNotNull(response.getEntity(), "Response entity should not be null."); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Test the get next pending operation method with device management exception.") + public void getNextPendingOperationWithDeviceManagementException() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "isValidDeviceIdentifier")) + .toReturn(true); + Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()) + .thenThrow(new DeviceManagementException()); + Response response = this.deviceAgentService.getNextPendingOperation(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER); + Assert.assertNotNull(response, "Response should not be null"); + Assert.assertNotNull(response.getEntity(), "Response entity should not be null."); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Test update operation method with invalid device type.") + public void testUpdateOperationWithInvalidDeviceType() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()) + .thenReturn(new ArrayList() {}); + Operation operation = new Operation(); + Response response = this.deviceAgentService.updateOperation(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER, + operation); + Assert.assertNotNull(response, "The response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "The response status should be 400"); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Test update operation when operation is null.") + public void testUpdateOperationWithNullOperation() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + List deviceTypes = new ArrayList<>(); + deviceTypes.add(TEST_DEVICE_TYPE); + Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes); + Response response = this.deviceAgentService.updateOperation(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER, + null); + Assert.assertNotNull(response, "The response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "The response status should be 400"); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Test update operation method with invalid device identifier.") + public void testUpdateOperationWithInvalidDeviceIdentifier() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "isValidDeviceIdentifier")) + .toReturn(false); + Operation operation = new Operation(); + List deviceTypes = new ArrayList<>(); + deviceTypes.add(TEST_DEVICE_TYPE); + Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes); + Response response = this.deviceAgentService.updateOperation(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER, + operation); + Assert.assertNotNull(response, "The response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "The response status should be 400"); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Test update operation success scenario.") + public void testUpdateOperationSuccess() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "isValidDeviceIdentifier")) + .toReturn(true); + Operation operation = new Operation(); + List deviceTypes = new ArrayList<>(); + deviceTypes.add(TEST_DEVICE_TYPE); + Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes); + Response response = this.deviceAgentService.updateOperation(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER, + operation); + Assert.assertNotNull(response, "The response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "The response status should be 200"); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Test the update Operation method with Policy Monitoring Operation.") + public void testUpdateOperationSuccessWithPolicyMonitorOperation() throws DeviceManagementException, + PolicyComplianceException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "isValidDeviceIdentifier")) + .toReturn(true); + PolicyManagerService policyManagementService = Mockito.mock(PolicyManagerServiceImpl.class, Mockito + .RETURNS_MOCKS); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getPolicyManagementService")) + .toReturn(policyManagementService); + Mockito.when(policyManagementService.checkCompliance(Mockito.any(), Mockito.any())).thenReturn(true); + + Operation operation = new Operation(); + operation.setCode(MONITOR_OPERATION); + operation.setStatus(Operation.Status.PENDING); + operation.setPayLoad(null); + List deviceTypes = new ArrayList<>(); + deviceTypes.add(TEST_DEVICE_TYPE); + Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes); + Response response = this.deviceAgentService.updateOperation(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER, + operation); + Assert.assertNotNull(response, "The response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "The response status should be 200"); + } + + @Test(description = "Test Update Operation with Operation Management Exception.") + public void testUpdateOperationWithOperationManagementException() throws DeviceManagementException, + OperationManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "isValidDeviceIdentifier")) + .toReturn(true); + + Operation operation = new Operation(); + List deviceTypes = new ArrayList<>(); + deviceTypes.add(TEST_DEVICE_TYPE); + Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes); + Mockito.doThrow(new OperationManagementException()).when(this.deviceManagementProviderService) + .updateOperation(Mockito.any(), Mockito.any()); + Response response = this.deviceAgentService.updateOperation(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER, + operation); + Assert.assertNotNull(response, "The response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Test Update operation with Device Management exception.") + public void testUpdateOperationWithDeviceManagementException() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "isValidDeviceIdentifier")) + .toReturn(true); + + Operation operation = new Operation(); + List deviceTypes = new ArrayList<>(); + deviceTypes.add(TEST_DEVICE_TYPE); + Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()) + .thenThrow(new DeviceManagementException()); + Response response = this.deviceAgentService.updateOperation(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER, + operation); + Assert.assertNotNull(response, "The response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Test update operation with Policy Compliance operation.") + public void testUpdateOperationWithPolicyComplianceException() throws PolicyComplianceException, + DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "isValidDeviceIdentifier")) + .toReturn(true); + PolicyManagerService policyManagementService = Mockito.mock(PolicyManagerServiceImpl.class, Mockito + .RETURNS_MOCKS); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getPolicyManagementService")) + .toReturn(policyManagementService); + Mockito.when(policyManagementService.checkCompliance(Mockito.any(), Mockito.any())) + .thenThrow(new PolicyComplianceException()); + + Operation operation = new Operation(); + operation.setCode(MONITOR_OPERATION); + operation.setStatus(Operation.Status.PENDING); + operation.setPayLoad(null); + List deviceTypes = new ArrayList<>(); + deviceTypes.add(TEST_DEVICE_TYPE); + Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes); + Response response = this.deviceAgentService.updateOperation(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER, + operation); + Assert.assertNotNull(response, "The response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + } + + @Test(description = "Test get operations with null operation status.") + public void getOperationsWithStatusNull() { + Response response = this.deviceAgentService.getOperationsByDeviceAndStatus(TEST_DEVICE_TYPE, + TEST_DEVICE_IDENTIFIER, null); + Assert.assertNotNull(response, "The response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "The response status should be 400"); + } + + @Test(description = "Test get operations with invalid device types.") + public void getOperationWithInvalidDeviceType() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()) + .thenReturn(new ArrayList() {}); + Response response = this.deviceAgentService.getOperationsByDeviceAndStatus(TEST_DEVICE_TYPE, + TEST_DEVICE_IDENTIFIER, Operation.Status.COMPLETED); + Assert.assertNotNull(response, "The response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "The response status should be 400"); + } + + @Test(description = "Test get operations success scenario.") + public void testGetOperationSuccess() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + List deviceTypes = new ArrayList<>(); + deviceTypes.add(TEST_DEVICE_TYPE); + Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes); + Response response = this.deviceAgentService.getOperationsByDeviceAndStatus(TEST_DEVICE_TYPE, + TEST_DEVICE_IDENTIFIER, Operation.Status.COMPLETED); + Assert.assertNotNull(response, "The response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "The response status should be 200"); + } + + @Test(description = "Test the get operation method with operation management exception.") + public void testGetOperationWithOperationManagementException() throws DeviceManagementException, + OperationManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + List deviceTypes = new ArrayList<>(); + deviceTypes.add(TEST_DEVICE_TYPE); + Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenReturn(deviceTypes); + Mockito.when(this.deviceManagementProviderService.getOperationsByDeviceAndStatus(Mockito.any(), Mockito.any())) + .thenThrow(new OperationManagementException()); + Response response = this.deviceAgentService.getOperationsByDeviceAndStatus(TEST_DEVICE_TYPE, + TEST_DEVICE_IDENTIFIER, Operation.Status.COMPLETED); + Assert.assertNotNull(response, "The response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Test the get operation method with device management exception.") + public void testGetOperationsWithDeviceManagementException() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + List deviceTypes = new ArrayList<>(); + deviceTypes.add(TEST_DEVICE_TYPE); + Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()) + .thenThrow(new DeviceManagementException()); + Response response = this.deviceAgentService.getOperationsByDeviceAndStatus(TEST_DEVICE_TYPE, + TEST_DEVICE_IDENTIFIER, Operation.Status.COMPLETED); + Assert.assertNotNull(response, "The response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + Mockito.reset(this.deviceManagementProviderService); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java new file mode 100644 index 0000000000..e1935904ae --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java @@ -0,0 +1,610 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.service.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; +import org.testng.Assert; +import org.testng.IObjectFactory; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.ObjectFactory; +import org.testng.annotations.Test; +import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.EnrolmentInfo; +import org.wso2.carbon.device.mgt.common.PaginationRequest; +import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException; +import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException; +import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService; +import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException; +import org.wso2.carbon.device.mgt.common.search.SearchContext; +import org.wso2.carbon.device.mgt.core.app.mgt.ApplicationManagementProviderService; +import org.wso2.carbon.device.mgt.core.authorization.DeviceAccessAuthorizationServiceImpl; +import org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceDetailsMgtException; +import org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceInformationManager; +import org.wso2.carbon.device.mgt.core.device.details.mgt.impl.DeviceInformationManagerImpl; +import org.wso2.carbon.device.mgt.core.search.mgt.SearchManagerService; +import org.wso2.carbon.device.mgt.core.search.mgt.SearchMgtException; +import org.wso2.carbon.device.mgt.core.search.mgt.impl.SearchManagerServiceImpl; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderServiceImpl; +import org.wso2.carbon.device.mgt.jaxrs.service.api.DeviceManagementService; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; +import org.wso2.carbon.policy.mgt.common.PolicyManagementException; +import org.wso2.carbon.policy.mgt.core.PolicyManagerService; +import org.wso2.carbon.utils.multitenancy.MultitenantUtils; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.UUID; +import javax.ws.rs.core.Response; + +import static org.mockito.MockitoAnnotations.initMocks; + +/** + * This class includes unit tests for testing the functionality of {@link DeviceManagementServiceImpl} + */ +@PowerMockIgnore("javax.ws.rs.*") +@SuppressStaticInitializationFor({"org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils", + "org.wso2.carbon.context.CarbonContext"}) +@PrepareForTest({DeviceMgtAPIUtils.class, MultitenantUtils.class, CarbonContext.class}) +public class DeviceManagementServiceImplTest { + + private static final Log log = LogFactory.getLog(DeviceManagementServiceImplTest.class); + private static final String TEST_DEVICE_TYPE = "TEST-DEVICE-TYPE"; + private static final String TEST_DEVICE_NAME = "TEST-DEVICE"; + private static final String DEFAULT_USERNAME = "admin"; + private static final String TENANT_AWARE_USERNAME = "admin@carbon.super"; + private static final String DEFAULT_ROLE = "admin"; + private static final String DEFAULT_OWNERSHIP = "BYOD"; + private static final String DEFAULT_STATUS = "ACTIVE"; + private static final String DEFAULT_DATE_FORMAT = "EEE, d MMM yyyy HH:mm:ss Z"; + private DeviceManagementService deviceManagementService; + private DeviceAccessAuthorizationService deviceAccessAuthorizationService; + private DeviceManagementProviderService deviceManagementProviderService; + + @ObjectFactory + public IObjectFactory getObjectFactory() { + return new org.powermock.modules.testng.PowerMockObjectFactory(); + } + + @BeforeClass + public void init() { + log.info("Initializing DeviceManagementServiceImpl tests"); + initMocks(this); + this.deviceManagementProviderService = Mockito + .mock(DeviceManagementProviderServiceImpl.class, Mockito.RETURNS_MOCKS); + this.deviceManagementService = new DeviceManagementServiceImpl(); + this.deviceAccessAuthorizationService = Mockito.mock(DeviceAccessAuthorizationServiceImpl.class); + } + + @Test(description = "Testing if the device is enrolled when the device is enrolled.") + public void testIsEnrolledWhenDeviceIsEnrolled() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(this.deviceManagementProviderService.isEnrolled(Mockito.any(DeviceIdentifier.class))) + .thenReturn(true); + Response response = this.deviceManagementService.isEnrolled(TEST_DEVICE_TYPE, UUID.randomUUID().toString()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Testing if the device is enrolled when the device is not enrolled.", + dependsOnMethods = "testIsEnrolledWhenDeviceIsEnrolled") + public void testIsEnrolledWhenDeviceIsNotEnrolled() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(this.deviceManagementProviderService.isEnrolled(Mockito.any(DeviceIdentifier.class))) + .thenReturn(false); + Response response = this.deviceManagementService.isEnrolled(TEST_DEVICE_TYPE, UUID.randomUUID().toString()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getStatus(), Response.Status.NO_CONTENT.getStatusCode()); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Testing if the device enrolled api when exception occurred.", + dependsOnMethods = "testIsEnrolledWhenDeviceIsNotEnrolled") + public void testIsEnrolledError() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(this.deviceManagementProviderService.isEnrolled(Mockito.any(DeviceIdentifier.class))) + .thenThrow(new DeviceManagementException()); + Response response = this.deviceManagementService.isEnrolled(TEST_DEVICE_TYPE, UUID.randomUUID().toString()); + Assert.assertNotNull(response); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Testing get devices when request exists both name and role.") + public void testGetDevicesWhenBothNameAndRoleAvailable() { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceAccessAuthorizationService")) + .toReturn(this.deviceAccessAuthorizationService); + Response response = this.deviceManagementService + .getDevices(TEST_DEVICE_NAME, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, + DEFAULT_STATUS, 1, null, null, 10, 5); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode()); + } + + @Test(description = "Testing get devices with correct request.") + public void testGetDevices() { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceAccessAuthorizationService")) + .toReturn(this.deviceAccessAuthorizationService); + PowerMockito.stub(PowerMockito.method(MultitenantUtils.class, "getTenantAwareUsername")) + .toReturn(TENANT_AWARE_USERNAME); + PowerMockito.stub(PowerMockito.method(CarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(Mockito.mock(CarbonContext.class, Mockito.RETURNS_MOCKS)); + + Response response = this.deviceManagementService + .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, + DEFAULT_STATUS, 1, null, null, 10, 5); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); + response = this.deviceManagementService + .getDevices(TEST_DEVICE_NAME, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, null, DEFAULT_OWNERSHIP, + DEFAULT_STATUS, 1, null, null, 10, 5); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); + response = this.deviceManagementService + .getDevices(TEST_DEVICE_NAME, TEST_DEVICE_TYPE, null, null, null, DEFAULT_OWNERSHIP, + DEFAULT_STATUS, 1, null, null, 10, 5); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); + response = this.deviceManagementService + .getDevices(TEST_DEVICE_NAME, TEST_DEVICE_TYPE, null, null, null, DEFAULT_OWNERSHIP, + DEFAULT_STATUS, 1, null, null, 10, 5); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); + } + + @Test(description = "Testing get devices when DeviceAccessAuthorizationService is not available") + public void testGetDevicesWithErroneousDeviceAccessAuthorizationService() { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceAccessAuthorizationService")) + .toReturn(null); + Response response = this.deviceManagementService + .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, + DEFAULT_STATUS, 1, null, null, 10, 5); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + } + + @Test(description = "Testing get devices when user is the device admin") + public void testGetDevicesWhenUserIsAdmin() throws DeviceAccessAuthorizationException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceAccessAuthorizationService")) + .toReturn(this.deviceAccessAuthorizationService); + PowerMockito.stub(PowerMockito.method(MultitenantUtils.class, "getTenantAwareUsername")) + .toReturn(TENANT_AWARE_USERNAME); + PowerMockito.stub(PowerMockito.method(CarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(Mockito.mock(CarbonContext.class, Mockito.RETURNS_MOCKS)); + Mockito.when(deviceAccessAuthorizationService.isDeviceAdminUser()).thenReturn(true); + + Response response = this.deviceManagementService + .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, + DEFAULT_STATUS, 1, null, null, 10, 5); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); + response = this.deviceManagementService + .getDevices(null, TEST_DEVICE_TYPE, null, DEFAULT_USERNAME, DEFAULT_ROLE, DEFAULT_OWNERSHIP, + DEFAULT_STATUS, 1, null, null, 10, 5); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); + } + + @Test(description = "Testing get devices when user is unauthorized.") + public void testGetDevicesWhenUserIsUnauthorized() throws Exception { + PowerMockito.spy(MultitenantUtils.class); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceAccessAuthorizationService")) + .toReturn(this.deviceAccessAuthorizationService); + PowerMockito.stub(PowerMockito.method(CarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(Mockito.mock(CarbonContext.class, Mockito.RETURNS_MOCKS)); + PowerMockito.doReturn(TENANT_AWARE_USERNAME) + .when(MultitenantUtils.class, "getTenantAwareUsername", DEFAULT_USERNAME); + PowerMockito.doReturn("newuser@carbon.super").when(MultitenantUtils.class, "getTenantAwareUsername", "newuser"); + Mockito.when(this.deviceAccessAuthorizationService.isDeviceAdminUser()).thenReturn(false); + + Response response = this.deviceManagementService + .getDevices(null, TEST_DEVICE_TYPE, "newuser", null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, DEFAULT_STATUS, 1, + null, null, 10, 5); + Assert.assertEquals(response.getStatus(), Response.Status.UNAUTHORIZED.getStatusCode()); + Mockito.reset(this.deviceAccessAuthorizationService); + } + + @Test(description = "Testing get devices with IF-Modified-Since") + public void testGetDevicesWithModifiedSince() { + String ifModifiedSince = new SimpleDateFormat(DEFAULT_DATE_FORMAT).format(new Date()); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceAccessAuthorizationService")) + .toReturn(this.deviceAccessAuthorizationService); + PowerMockito.stub(PowerMockito.method(MultitenantUtils.class, "getTenantAwareUsername")) + .toReturn(TENANT_AWARE_USERNAME); + PowerMockito.stub(PowerMockito.method(CarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(Mockito.mock(CarbonContext.class, Mockito.RETURNS_MOCKS)); + + Response response = this.deviceManagementService + .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, + DEFAULT_STATUS, 1, null, ifModifiedSince, 10, 5); + Assert.assertEquals(response.getStatus(), Response.Status.NOT_MODIFIED.getStatusCode()); + response = this.deviceManagementService + .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, + DEFAULT_STATUS, 1, null, ifModifiedSince, 10, 5); + Assert.assertEquals(response.getStatus(), Response.Status.NOT_MODIFIED.getStatusCode()); + response = this.deviceManagementService + .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, + DEFAULT_STATUS, 1, null, "ErrorModifiedSince", 10, 5); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode()); + } + + @Test(description = "Testing get devices with Since") + public void testGetDevicesWithSince() { + String since = new SimpleDateFormat(DEFAULT_DATE_FORMAT).format(new Date()); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceAccessAuthorizationService")) + .toReturn(this.deviceAccessAuthorizationService); + PowerMockito.stub(PowerMockito.method(MultitenantUtils.class, "getTenantAwareUsername")) + .toReturn(TENANT_AWARE_USERNAME); + PowerMockito.stub(PowerMockito.method(CarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(Mockito.mock(CarbonContext.class, Mockito.RETURNS_MOCKS)); + + Response response = this.deviceManagementService + .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, + DEFAULT_STATUS, 1, since, null, 10, 5); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); + response = this.deviceManagementService + .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, + DEFAULT_STATUS, 1, since, null, 10, 5); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); + response = this.deviceManagementService + .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, + DEFAULT_STATUS, 1, "ErrorSince", null, 10, 5); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode()); + } + + @Test(description = "Testing get devices when unable to retrieve devices") + public void testGetDeviceServerErrorWhenGettingDeviceList() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceAccessAuthorizationService")) + .toReturn(this.deviceAccessAuthorizationService); + PowerMockito.stub(PowerMockito.method(MultitenantUtils.class, "getTenantAwareUsername")) + .toReturn(TENANT_AWARE_USERNAME); + PowerMockito.stub(PowerMockito.method(CarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(Mockito.mock(CarbonContext.class, Mockito.RETURNS_MOCKS)); + Mockito.when(this.deviceManagementProviderService + .getAllDevices(Mockito.any(PaginationRequest.class))).thenThrow(new DeviceManagementException()); + + Response response = this.deviceManagementService + .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, + DEFAULT_STATUS, 1, null, null, 10, 5); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Testing get devices when unable to check if the user is the admin user") + public void testGetDevicesServerErrorWhenCheckingAdminUser() throws DeviceAccessAuthorizationException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceAccessAuthorizationService")) + .toReturn(this.deviceAccessAuthorizationService); + PowerMockito.stub(PowerMockito.method(MultitenantUtils.class, "getTenantAwareUsername")) + .toReturn(TENANT_AWARE_USERNAME); + PowerMockito.stub(PowerMockito.method(CarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(Mockito.mock(CarbonContext.class, Mockito.RETURNS_MOCKS)); + Mockito.when(this.deviceAccessAuthorizationService.isDeviceAdminUser()) + .thenThrow(new DeviceAccessAuthorizationException()); + + Response response = this.deviceManagementService + .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, + DEFAULT_STATUS, 1, null, null, 10, 5); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + Mockito.reset(this.deviceAccessAuthorizationService); + } + + @Test(description = "Testing get devices with correct request") + public void testGetDeviceTypesByUser() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(CarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(Mockito.mock(CarbonContext.class, Mockito.RETURNS_MOCKS)); + + Response response = this.deviceManagementService.getDeviceByUser(true, 10, 5); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); + response = this.deviceManagementService.getDeviceByUser(false, 10, 5); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); + } + + @Test(description = "Testing get devices with correct request when unable to get devices.") + public void testGetDeviceTypesByUserException() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(CarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(Mockito.mock(CarbonContext.class, Mockito.RETURNS_MOCKS)); + Mockito.when(this.deviceManagementProviderService.getDevicesOfUser(Mockito.any(PaginationRequest.class))) + .thenThrow(new DeviceManagementException()); + + Response response = this.deviceManagementService.getDeviceByUser(true, 10, 5); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + } + + @Test(description = "Testing delete device with correct request.") + public void testDeleteDevice() { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Response response = this.deviceManagementService.deleteDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString()); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); + } + + @Test(description = "Testing delete unavailable device.") + public void testDeleteUnavailableDevice() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(this.deviceManagementProviderService + .getDevice(Mockito.any(DeviceIdentifier.class), Mockito.anyBoolean())).thenReturn(null); + Response response = this.deviceManagementService.deleteDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString()); + Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode()); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Testing delete device when unable to delete device.") + public void testDeleteDeviceException() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(this.deviceManagementProviderService.disenrollDevice(Mockito.any(DeviceIdentifier.class))) + .thenThrow(new DeviceManagementException()); + Response response = this.deviceManagementService.deleteDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString()); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode()); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Testing getting device location") + public void testGetDeviceLocation() { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceInformationManagerService")). + toReturn(Mockito.mock(DeviceInformationManagerImpl.class, Mockito.RETURNS_MOCKS)); + Response response = this.deviceManagementService + .getDeviceLocation(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), null); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); + } + + @Test(description = "Testing getting device location when unable to retrieve location") + public void testGetDeviceLocationException() throws DeviceDetailsMgtException { + DeviceInformationManager deviceInformationManager = Mockito + .mock(DeviceInformationManagerImpl.class, Mockito.RETURNS_MOCKS); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceInformationManagerService")). + toReturn(deviceInformationManager); + Mockito.when(deviceInformationManager.getDeviceLocation(Mockito.any(DeviceIdentifier.class))) + .thenThrow(new DeviceDetailsMgtException()); + Response response = this.deviceManagementService + .getDeviceLocation(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), null); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + } + + @Test(description = "Testing getting device information") + public void testGetDeviceInformation() { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceInformationManagerService")). + toReturn(Mockito.mock(DeviceInformationManagerImpl.class, Mockito.RETURNS_MOCKS)); + Response response = this.deviceManagementService + .getDeviceInformation(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), null); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); + } + + @Test(description = "Testing getting device information when unable to retrieve information") + public void testGetDeviceInformationException() throws DeviceDetailsMgtException { + DeviceInformationManager deviceInformationManager = Mockito + .mock(DeviceInformationManagerImpl.class, Mockito.RETURNS_MOCKS); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceInformationManagerService")). + toReturn(deviceInformationManager); + Mockito.when(deviceInformationManager.getDeviceInfo(Mockito.any(DeviceIdentifier.class))) + .thenThrow(new DeviceDetailsMgtException()); + Response response = this.deviceManagementService + .getDeviceInformation(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), null); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + } + + @Test(description = "Testing getting device features") + public void testGetFeaturesOfDevice() { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Response response = this.deviceManagementService + .getFeaturesOfDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), null); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); + } + + @Test(description = "Testing getting device features when feature manager is not registered for the device type") + public void testGetFeaturesOfDeviceWhenFeatureManagerIsNotRegistered() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(this.deviceManagementProviderService.getFeatureManager(Mockito.anyString())).thenReturn(null); + Response response = this.deviceManagementService + .getFeaturesOfDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), null); + Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode()); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Testing getting device features when unable to get the feature manager") + public void testGetFeaturesException() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(this.deviceManagementProviderService.getFeatureManager(Mockito.anyString())) + .thenThrow(new DeviceManagementException()); + Response response = this.deviceManagementService + .getFeaturesOfDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), null); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Testing search devices") + public void testSearchDevices() { + SearchManagerService searchManagerService = Mockito.mock(SearchManagerServiceImpl.class, Mockito.RETURNS_MOCKS); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getSearchManagerService")) + .toReturn(searchManagerService); + Response response = this.deviceManagementService + .searchDevices(10, 5, new SearchContext()); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "Expects to return HTTP 200 when the search is successful"); + } + + @Test(description = "Testing search devices when unable to search devices") + public void testSearchDevicesException() throws SearchMgtException { + SearchManagerService searchManagerService = Mockito.mock(SearchManagerServiceImpl.class, Mockito.RETURNS_MOCKS); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getSearchManagerService")) + .toReturn(searchManagerService); + Mockito.when(searchManagerService.search(Mockito.any(SearchContext.class))).thenThrow(new SearchMgtException()); + Response response = this.deviceManagementService + .searchDevices(10, 5, new SearchContext()); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "Expects HTTP 500 when an exception occurred while searching the device"); + } + + @Test(description = "Testing getting installed applications of a device") + public void testGetInstalledApplications() { + ApplicationManagementProviderService applicationManagementProviderService = Mockito + .mock(ApplicationManagementProviderService.class, Mockito.RETURNS_MOCKS); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getAppManagementService")) + .toReturn(applicationManagementProviderService); + Response response = this.deviceManagementService + .getInstalledApplications(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), "", 10, 5); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "Expects to return HTTP 200 when the application list is retrieved successfully."); + } + + @Test(description = "Testing getting installed applications of a device when unable to fetch applications") + public void testGetInstalledApplicationsException() throws ApplicationManagementException { + ApplicationManagementProviderService applicationManagementProviderService = Mockito + .mock(ApplicationManagementProviderService.class, Mockito.RETURNS_MOCKS); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getAppManagementService")) + .toReturn(applicationManagementProviderService); + Mockito.when( + applicationManagementProviderService.getApplicationListForDevice(Mockito.any(DeviceIdentifier.class))) + .thenThrow(new ApplicationManagementException()); + Response response = this.deviceManagementService + .getInstalledApplications(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), "", 10, 5); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "Expects HTTP 500 when an exception occurred while retrieving application list of the device"); + } + + @Test(description = "Testing getting operation list of a device") + public void testGetDeviceOperations() { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(CarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(Mockito.mock(CarbonContext.class, Mockito.RETURNS_MOCKS)); + Mockito.when(CarbonContext.getThreadLocalCarbonContext().getUsername()).thenReturn(DEFAULT_USERNAME); + Response response = this.deviceManagementService + .getDeviceOperations(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), "", 10, 5); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "Expects to return HTTP 200 when the operation is retrieved successfully."); + } + + @Test(description = "Testing getting operation list of a device when unable to retrieve operations") + public void testGetDeviceOperationsException() throws OperationManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(CarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(Mockito.mock(CarbonContext.class, Mockito.RETURNS_MOCKS)); + Mockito.when(CarbonContext.getThreadLocalCarbonContext().getUsername()).thenReturn(DEFAULT_USERNAME); + Mockito.when(this.deviceManagementProviderService.getOperations(Mockito.any(DeviceIdentifier.class), + Mockito.any(PaginationRequest.class))).thenThrow(new OperationManagementException()); + Response response = this.deviceManagementService + .getDeviceOperations(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), "", 10, 5); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "Expects to return HTTP 500 when an exception occurred while retrieving operation list of the device"); + } + + @Test(description = "Testing getting effective policy of a device") + public void testGetEffectivePolicyOfDevice() throws PolicyManagementException { + PolicyManagerService policyManagerService = Mockito.mock(PolicyManagerService.class, Mockito.RETURNS_MOCKS); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getPolicyManagementService")) + .toReturn(policyManagerService); + Response response = this.deviceManagementService + .getEffectivePolicyOfDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), null); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "Expects to return HTTP 200 when retrieving effective policy is successful"); + } + + @Test(description = "Testing getting effective policy of a device when unable to retrieve effective policy") + public void testGetEffectivePolicyOfDeviceException() throws PolicyManagementException { + PolicyManagerService policyManagerService = Mockito.mock(PolicyManagerService.class, Mockito.RETURNS_MOCKS); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getPolicyManagementService")) + .toReturn(policyManagerService); + Mockito.when(policyManagerService.getAppliedPolicyToDevice(Mockito.any(DeviceIdentifier.class))) + .thenThrow(new PolicyManagementException()); + Response response = this.deviceManagementService + .getEffectivePolicyOfDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), null); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "Expects to return HTTP 500 when an exception occurred while getting effective policy of the device"); + } + + @Test(description = "Testing changing device status") + public void testChangeDeviceStatus() { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Response response = this.deviceManagementService + .changeDeviceStatus(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), EnrolmentInfo.Status.INACTIVE); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); + } + + @Test(description = "Testing changing device status when device does not exist") + public void testChangeDeviceStatusWhenDeviceNotExists() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(this.deviceManagementProviderService + .getDevice(Mockito.any(DeviceIdentifier.class), Mockito.anyBoolean())).thenReturn(null); + Response response = this.deviceManagementService + .changeDeviceStatus(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), EnrolmentInfo.Status.INACTIVE); + Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode()); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Testing changing device status when device cannot be retrieved") + public void testChangeDeviceStatusException() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(this.deviceManagementProviderService + .getDevice(Mockito.any(DeviceIdentifier.class), Mockito.anyBoolean())) + .thenThrow(new DeviceManagementException()); + Response response = this.deviceManagementService + .changeDeviceStatus(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), EnrolmentInfo.Status.ACTIVE); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode()); + Mockito.reset(this.deviceManagementProviderService); + } + + @Test(description = "Testing changing device status when unable to change device status") + public void testChangeDeviceStatusWhenUnableToChangeStatus() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(this.deviceManagementProviderService + .changeDeviceStatus(Mockito.any(DeviceIdentifier.class), Mockito.any())) + .thenThrow(new DeviceManagementException()); + Response response = this.deviceManagementService + .changeDeviceStatus(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), EnrolmentInfo.Status.ACTIVE); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode()); + Mockito.reset(this.deviceManagementProviderService); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementAdminServiceTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementAdminServiceTest.java new file mode 100644 index 0000000000..0d275ea52d --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementAdminServiceTest.java @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ + +package org.wso2.carbon.device.mgt.jaxrs.service.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; +import org.testng.Assert; +import org.testng.IObjectFactory; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.ObjectFactory; +import org.testng.annotations.Test; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.spi.DeviceTypeGeneratorService; +import org.wso2.carbon.device.mgt.core.dto.DeviceType; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderServiceImpl; +import org.wso2.carbon.device.mgt.extensions.device.type.template.DeviceTypeGeneratorServiceImpl; +import org.wso2.carbon.device.mgt.jaxrs.service.api.admin.DeviceTypeManagementAdminService; +import org.wso2.carbon.device.mgt.jaxrs.service.impl.admin.DeviceTypeManagementAdminServiceImpl; +import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.DeviceMgtAPITestHelper; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; + +import javax.ws.rs.core.Response; + +import static org.mockito.MockitoAnnotations.initMocks; + +/** + * This class holds the unit tests for the class {@link DeviceTypeManagementAdminService} + */ +@PowerMockIgnore("javax.ws.rs.*") +@SuppressStaticInitializationFor({"org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils"}) +@PrepareForTest({DeviceMgtAPIUtils.class, DeviceManagementProviderService.class}) +public class DeviceTypeManagementAdminServiceTest { + + private static final Log log = LogFactory.getLog(DeviceTypeManagementAdminService.class); + private static final String TEST_DEVICE_TYPE = "TEST-DEVICE-TYPE"; + private static final String TEST_DEVICE_TYPE_1 = "DUMMY-DEVICE-TYPE-1"; + private static final String TEST_DEVICE_TYPE_2 = "DUMMY DEVICE TYPE"; + private static final int TEST_DEVICE_TYPE_ID = 12345; + private static final int TEST_DEVICE_TYPE_ID_1 = 123452; + private static final int TEST_DEVICE_TYPE_ID_2 = 121233452; + private DeviceTypeManagementAdminService deviceTypeManagementAdminService; + private DeviceManagementProviderService deviceManagementProviderService; + private DeviceTypeGeneratorService deviceTypeGeneratorService; + + @ObjectFactory + public IObjectFactory getObjectFactory() { + return new org.powermock.modules.testng.PowerMockObjectFactory(); + } + + @BeforeClass + public void init() throws DeviceManagementException { + log.info("Initializing DeviceTypeManagementAdmin tests"); + initMocks(this); + this.deviceManagementProviderService = Mockito + .mock(DeviceManagementProviderServiceImpl.class, Mockito.RETURNS_MOCKS); + this.deviceTypeGeneratorService = Mockito.mock(DeviceTypeGeneratorServiceImpl.class, Mockito.RETURNS_MOCKS); + this.deviceTypeManagementAdminService = new DeviceTypeManagementAdminServiceImpl(); + } + + @Test(description = "Test get all the device types.") + public void testGetDeviceTypes() { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Response response = this.deviceTypeManagementAdminService.getDeviceTypes(); + Assert.assertNotNull(response, "The response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "The Response status code should be 200."); + } + + @Test(description = "Test the error scenario of getting all the device types.") + public void testGetDeviceTypesError() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(deviceManagementProviderService.getDeviceTypes()).thenThrow(new DeviceManagementException()); + Response response = this.deviceTypeManagementAdminService.getDeviceTypes(); + Assert.assertNotNull(response, "The response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The expected status code is 500."); + Mockito.reset(deviceManagementProviderService); + } + + @Test(description = "Test the new device type creation scenario.") + public void testAddDeviceTypeWithExistingName() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + DeviceType deviceType = DeviceMgtAPITestHelper.getDummyDeviceType(TEST_DEVICE_TYPE_1, TEST_DEVICE_TYPE_ID_1); + Response response = this.deviceTypeManagementAdminService.addDeviceType(deviceType); + Assert.assertNotNull(response, "The response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.CONFLICT.getStatusCode(), + "The Response Status code should be 409."); + } + + @Test(description = "Test the new device type creation scenario when device type name is unqualified.") + public void testAddDeviceTypeWithUnqualifiedName() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(deviceManagementProviderService.getDeviceType(Mockito.anyString())).thenReturn(null); + DeviceType deviceType = DeviceMgtAPITestHelper.getDummyDeviceType(TEST_DEVICE_TYPE_2, TEST_DEVICE_TYPE_ID_2); + Response response = this.deviceTypeManagementAdminService.addDeviceType(deviceType); + Assert.assertNotNull(response, "The response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "The Response Status code should be 400."); + Mockito.reset(deviceManagementProviderService); + } + + @Test(description = "Test creating a new device type success scenario.") + public void testAddDeviceType() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceTypeGeneratorService")) + .toReturn(this.deviceTypeGeneratorService); + Mockito.when(deviceManagementProviderService.getDeviceType(Mockito.anyString())).thenReturn(null); + DeviceType deviceType = DeviceMgtAPITestHelper.getDummyDeviceType(TEST_DEVICE_TYPE, TEST_DEVICE_TYPE_ID); + Response response = this.deviceTypeManagementAdminService.addDeviceType(deviceType); + Assert.assertNotNull(response, "The response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "The Response Status code should be 200."); + Mockito.reset(deviceManagementProviderService); + } + + @Test(description = "Test the create device type scenario when the device type is null.") + public void testAddDeviceTypeWithNoDeviceType() { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Response response = this.deviceTypeManagementAdminService.addDeviceType(null); + Assert.assertNotNull(response, "The response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "The Response Status code should be 409."); + } + + @Test(description = "Test the device type creation scenario with Device Management exception.") + public void testAddDeviceTypeWithException() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(this.deviceManagementProviderService.getDeviceType(Mockito.anyString())).thenThrow(new + DeviceManagementException()); + DeviceType deviceType = DeviceMgtAPITestHelper.getDummyDeviceType(TEST_DEVICE_TYPE, TEST_DEVICE_TYPE_ID); + Response response = this.deviceTypeManagementAdminService.addDeviceType(deviceType); + Assert.assertNotNull(response, "The response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The Response Status code should be 500."); + Mockito.reset(deviceManagementProviderService); + } + + @Test(description = "Test the update device type scenario.") + public void testUpdateDeviceType() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceTypeGeneratorService")) + .toReturn(this.deviceTypeGeneratorService); + DeviceType deviceType = DeviceMgtAPITestHelper.getDummyDeviceType(TEST_DEVICE_TYPE, TEST_DEVICE_TYPE_ID); + Response response = this.deviceTypeManagementAdminService.updateDeviceType(deviceType); + Assert.assertNotNull(response, "The response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "The Response Status code should be 200."); + } + + @Test(description = "Test the update device type scenario.") + public void testUpdateNonExistingDeviceType() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceTypeGeneratorService")) + .toReturn(this.deviceTypeGeneratorService); + Mockito.when(deviceManagementProviderService.getDeviceType(Mockito.anyString())).thenReturn(null); + DeviceType deviceType = DeviceMgtAPITestHelper.getDummyDeviceType(TEST_DEVICE_TYPE, TEST_DEVICE_TYPE_ID); + Response response = this.deviceTypeManagementAdminService.updateDeviceType(deviceType); + Assert.assertNotNull(response, "The response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "The Response Status code should be 400."); + Mockito.reset(deviceManagementProviderService); + } + + @Test(description = "Test update device Type when device type is null") + public void testUpdateDeviceTypeWithNullDeviceType() { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Response response = this.deviceTypeManagementAdminService.updateDeviceType(null); + Assert.assertNotNull(response, "The response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "The Response Status code should be 400."); + Mockito.reset(deviceManagementProviderService); + } + + @Test(description = "Test update device Type with DeviceManagementException") + public void testUpdateDeviceTypeWithException() throws DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(this.deviceManagementProviderService.getDeviceType(Mockito.anyString())) + .thenThrow(new DeviceManagementException()); + DeviceType deviceType = DeviceMgtAPITestHelper.getDummyDeviceType(TEST_DEVICE_TYPE, TEST_DEVICE_TYPE_ID); + Response response = this.deviceTypeManagementAdminService.updateDeviceType(deviceType); + Assert.assertNotNull(response, "The response should not be null"); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The Response Status code should be 500."); + Mockito.reset(deviceManagementProviderService); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceTest.java new file mode 100644 index 0000000000..9629afb07a --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceTest.java @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ +package org.wso2.carbon.device.mgt.jaxrs.service.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; +import org.testng.Assert; +import org.testng.IObjectFactory; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.ObjectFactory; +import org.testng.annotations.Test; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.FeatureManager; +import org.wso2.carbon.device.mgt.core.dto.DeviceType; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderServiceImpl; +import org.wso2.carbon.device.mgt.jaxrs.service.api.DeviceTypeManagementService; +import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.DeviceMgtAPITestHelper; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; + +import javax.ws.rs.core.Response; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.List; + +import static org.mockito.MockitoAnnotations.initMocks; + +/** + * This class holds the unit tests for the class {@link DeviceTypeManagementService} + */ +@PowerMockIgnore("javax.ws.rs.*") +@SuppressStaticInitializationFor({"org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils"}) +@PrepareForTest({DeviceMgtAPIUtils.class, DeviceManagementProviderService.class}) +public class DeviceTypeManagementServiceTest { + + private static final Log log = LogFactory.getLog(DeviceManagementServiceImplTest.class); + private static final String TEST_DEVICE_TYPE = "TEST-DEVICE-TYPE"; + private static final int TEST_DEVICE_TYPE_ID = 12345; + private static final String MODIFIED_SINCE = "1234503934242"; + private DeviceTypeManagementService deviceTypeManagementService; + private DeviceManagementProviderService deviceManagementProviderService; + + @ObjectFactory + public IObjectFactory getObjectFactory() { + return new org.powermock.modules.testng.PowerMockObjectFactory(); + } + + @BeforeClass + public void init() throws DeviceManagementException { + log.info("Initializing DeviceTypeManagement tests"); + initMocks(this); + this.deviceManagementProviderService = Mockito + .mock(DeviceManagementProviderServiceImpl.class, Mockito.RETURNS_MOCKS); + this.deviceTypeManagementService = new DeviceTypeManagementServiceImpl(); + } + + @Test(description = "Testing for existing device types.") + public void testExistingDeviceType() throws Exception { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Response response = this.deviceTypeManagementService.getDeviceTypes(""); + Assert.assertNotNull(response, "The response object is null."); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "The response states should be 200."); + } + + @Test(description = "Testing get existing device types error") + public void testExistingDeviceTypesError() throws Exception { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(this.deviceManagementProviderService.getDeviceTypes()).thenThrow(new DeviceManagementException()); + Response response = this.deviceTypeManagementService.getDeviceTypes(); + Assert.assertNotNull(response, "The response object is null."); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500."); + Mockito.reset(deviceManagementProviderService); + } + + @Test(description = "Testing get existing device types error") + public void testExistingDeviceTypesModifiedError() throws Exception { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenThrow(new + DeviceManagementException()); + Response response = this.deviceTypeManagementService.getDeviceTypes(MODIFIED_SINCE); + Assert.assertNotNull(response, "The response object is null."); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500."); + Mockito.reset(deviceManagementProviderService); + } + + @Test(description = "Test case to retrieve the Features of specified device type.") + public void testGetDeviceTypeFeatures() throws Exception { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Response response = this.deviceTypeManagementService.getFeatures(TEST_DEVICE_TYPE, MODIFIED_SINCE); + Assert.assertNotNull(response, "The response object is null."); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "The response status should be 200."); + } + + @Test(description = "Test case to test the error scenario when retrieving the Features of specified device type.") + public void testGetDeviceTypeFeaturesError() throws Exception { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + FeatureManager featureManager = Mockito.mock(FeatureManager.class); + Mockito.when(this.deviceManagementProviderService.getFeatureManager(Mockito.anyString())).thenReturn + (featureManager); + Mockito.when((featureManager).getFeatures()).thenThrow(new DeviceManagementException()); + Response response = this.deviceTypeManagementService.getFeatures(TEST_DEVICE_TYPE, MODIFIED_SINCE); + Assert.assertNotNull(response, "The response object is null."); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500."); + Mockito.reset(deviceManagementProviderService); + Mockito.reset(featureManager); + } + + @Test(description = "Test getting device type features when feature manager is null.") + public void testGetDeviceTypeFeaturesWithNoFeatureManager() throws Exception { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(this.deviceManagementProviderService.getFeatureManager(Mockito.anyString())).thenReturn(null); + Response response = this.deviceTypeManagementService.getFeatures(TEST_DEVICE_TYPE, MODIFIED_SINCE); + Assert.assertNotNull(response, "The response object is null."); + Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode(), + "The response status should be 404."); + Mockito.reset(deviceManagementProviderService); + } + + @Test(description = "Test to get all the device types.") + public void testGetDeviceTypes() throws Exception { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Response response = this.deviceTypeManagementService.getDeviceTypes(); + Assert.assertNotNull(response, "The response object is null."); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "The response status should be 200."); + } + + @Test(description = "Test to get all the device types.") + public void testGetDeviceTypesWithDeviceTypes() throws Exception { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + List deviceTypes = DeviceMgtAPITestHelper.getDummyDeviceTypeList(5); + Mockito.when(this.deviceManagementProviderService.getDeviceTypes()).thenReturn(deviceTypes); + Response response = this.deviceTypeManagementService.getDeviceTypes(); + Assert.assertNotNull(response, "The response object is null."); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "The response state should be 200"); + Mockito.reset(deviceManagementProviderService); + } + + @Test(description = "Test to get all the device types for the given name") + public void testGetDeviceTypeByName() throws Exception { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Response response = this.deviceTypeManagementService.getDeviceTypeByName(TEST_DEVICE_TYPE); + Assert.assertNotNull(response, "The response object is null."); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "The response status should be 200."); + } + + @Test(description = "Test the scenario when there are no device types for the given name.") + public void testGetDeviceTypeByNameError() throws Exception { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(this.deviceManagementProviderService.getDeviceType(Mockito.anyString())).thenReturn(null); + Response response = this.deviceTypeManagementService.getDeviceTypeByName(TEST_DEVICE_TYPE); + Assert.assertNotNull(response, "The response object is null."); + Assert.assertEquals(response.getStatus(), Response.Status.NO_CONTENT.getStatusCode(), + "The response status should be 204."); + Mockito.reset(deviceManagementProviderService); + } + + @Test(description = "Test the scenario when there are no device types for the given name.") + public void testGetDeviceTypeByNameException() throws Exception { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.when(this.deviceManagementProviderService.getDeviceType(Mockito.anyString())) + .thenThrow(new DeviceManagementException()); + Response response = this.deviceTypeManagementService.getDeviceTypeByName(TEST_DEVICE_TYPE); + Assert.assertNotNull(response, "The response object is null."); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "The response status should be 500"); + Mockito.reset(deviceManagementProviderService); + } + + @Test(description = "Test to get all the device types when given name is null") + public void testGetDeviceTypeByNameBadRequest() throws Exception { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Response response = this.deviceTypeManagementService.getDeviceTypeByName(null); + Assert.assertNotNull(response, "The response object is null."); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "The response status should be 400"); + } + + @Test(description = "Test to clear the sensitive metadata information of device type") + public void testClearMetaEntryInfo() throws NoSuchMethodException, InvocationTargetException, + IllegalAccessException { + Method clearMetaEntryInfo = DeviceTypeManagementServiceImpl.class.getDeclaredMethod("clearMetaEntryInfo", + DeviceType.class); + clearMetaEntryInfo.setAccessible(true); + DeviceType deviceType = DeviceMgtAPITestHelper.getDummyDeviceType(TEST_DEVICE_TYPE, TEST_DEVICE_TYPE_ID); + DeviceType returned = (DeviceType) clearMetaEntryInfo.invoke(this.deviceTypeManagementService, deviceType); + Assert.assertNotNull(returned.getDeviceTypeMetaDefinition(), "The response object is null."); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GeoLocationBasedServiceImplTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GeoLocationBasedServiceImplTest.java new file mode 100644 index 0000000000..be7209a8e9 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GeoLocationBasedServiceImplTest.java @@ -0,0 +1,60 @@ +package org.wso2.carbon.device.mgt.jaxrs.service.impl; + + +import org.mockito.Mockito; +import org.testng.Assert; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.core.geo.GeoCluster; +import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.device.mgt.jaxrs.service.api.GeoLocationBasedService; + +import javax.ws.rs.core.Response; +import java.util.ArrayList; +import java.util.List; + +public class GeoLocationBasedServiceImplTest { + private DeviceManagementProviderService deviceManagementProviderService; + private PrivilegedCarbonContext context; + private GeoLocationBasedService geoLocationBasedService; + + @BeforeClass + public void init() { + deviceManagementProviderService = Mockito.mock(DeviceManagementProviderService.class); + geoLocationBasedService = new GeoLocationBasedServiceImpl(); + context = Mockito.mock(PrivilegedCarbonContext.class); + Mockito.doReturn("admin").when(context).getUsername(); + } + + @Test(description = "This method tests the behaviour of getGeoDeviceLocations when there are no devices" + + "in the given map boundaries") + public void testGetGeoDeviceLocations1() throws DeviceManagementException { + Mockito.doReturn(new ArrayList()).when(deviceManagementProviderService) + .findGeoClusters(Mockito.any(GeoCoordinate.class), Mockito.any(GeoCoordinate.class), Mockito.anyInt()); + Response response = geoLocationBasedService.getGeoDeviceLocations(0.4, 15, 75.6, + 90.1, 6); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "getGeoDeviceLocations request failed with valid parameters"); + } + + @Test(description = "This method tests the behaviour of getGeoDeviceLocations when there are devices" + + "in the given map boundaries") + public void testGetGeoDeviceLocations2() throws DeviceManagementException { + List geoClusters = new ArrayList<>(); + geoClusters.add(new GeoCluster(new GeoCoordinate(1.5, 80.7), + new GeoCoordinate(1.1, 79.5), new GeoCoordinate(1.9, 82.1), 3, + "tb32", "aegtew234", "android")); + geoClusters.add(new GeoCluster(new GeoCoordinate(10.2, 86.1), + new GeoCoordinate(9.8, 84.7), new GeoCoordinate(11.1, 88.1), 4, + "t1gd", "swerty12s", "android")); + Mockito.doReturn(geoClusters).when(deviceManagementProviderService) + .findGeoClusters(Mockito.any(GeoCoordinate.class), Mockito.any(GeoCoordinate.class), Mockito.anyInt()); + Response response = geoLocationBasedService.getGeoDeviceLocations(0.4, 15, 75.6, + 90.1, 6); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "getGeoDeviceLocations request failed with valid parameters"); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImplTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImplTest.java new file mode 100644 index 0000000000..d3c42b794a --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImplTest.java @@ -0,0 +1,397 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ + +package org.wso2.carbon.device.mgt.jaxrs.service.impl; + +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; +import org.testng.Assert; +import org.testng.IObjectFactory; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.ObjectFactory; +import org.testng.annotations.Test; +import org.wso2.carbon.CarbonConstants; +import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceNotFoundException; +import org.wso2.carbon.device.mgt.common.GroupPaginationRequest; +import org.wso2.carbon.device.mgt.common.PaginationResult; +import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup; +import org.wso2.carbon.device.mgt.common.group.mgt.GroupAlreadyExistException; +import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException; +import org.wso2.carbon.device.mgt.common.group.mgt.GroupNotExistException; +import org.wso2.carbon.device.mgt.common.group.mgt.RoleDoesNotExistException; +import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService; +import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceToGroupsAssignment; +import org.wso2.carbon.device.mgt.jaxrs.service.api.GroupManagementService; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; + +import javax.ws.rs.core.Response; +import java.util.ArrayList; +import java.util.List; + +/** + * This is a test case for {@link GroupManagementServiceImpl}. + */ +@PowerMockIgnore({"javax.ws.rs.*", "javax.xml.parsers"}) +@SuppressStaticInitializationFor({"org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils", + "org.wso2.carbon.context.PrivilegedCarbonContext"}) +@PrepareForTest({DeviceMgtAPIUtils.class, CarbonContext.class}) +public class GroupManagementServiceImplTest { + private GroupManagementService groupManagementService; + private GroupManagementProviderService groupManagementProviderService; + private PrivilegedCarbonContext context; + + @ObjectFactory + public IObjectFactory getObjectFactory() { + return new org.powermock.modules.testng.PowerMockObjectFactory(); + } + + @BeforeClass + public void init() { + groupManagementService = new GroupManagementServiceImpl(); + groupManagementProviderService = Mockito.mock(GroupManagementProviderService.class); + context = Mockito.mock(PrivilegedCarbonContext.class); + Mockito.doReturn("admin").when(context).getUsername(); + } + + @Test(description = "This method tests the behaviour of getGroups under valid conditions") + public void testGetGroups() throws GroupManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getGroupManagementProviderService")) + .toReturn(groupManagementProviderService); + PowerMockito.stub(PowerMockito.method(PrivilegedCarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(context); + PaginationResult paginationResult = new PaginationResult(); + Mockito.doReturn(paginationResult).when(groupManagementProviderService) + .getGroups(Mockito.anyString(), Mockito.any(GroupPaginationRequest.class)); + Response response = groupManagementService.getGroups("test", "admin", 0, 10); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "GetGroups request failed with valid parameters"); + + Mockito.reset(groupManagementProviderService); + List deviceGroupList = new ArrayList<>(); + deviceGroupList.add(new DeviceGroup("test")); + paginationResult.setData(deviceGroupList); + paginationResult.setRecordsTotal(1); + Mockito.doReturn(paginationResult).when(groupManagementProviderService) + .getGroups(Mockito.anyString(), Mockito.any(GroupPaginationRequest.class)); + response = groupManagementService.getGroups("test", "admin", 0, 10); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "GetGroups request failed with valid parameters"); + } + + @Test(description = "This method tests the behaviour of getGroups method under negative circumstances", + dependsOnMethods = {"testGetGroups"}) + public void testGetGroupUnderNegativeConditions() throws GroupManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getGroupManagementProviderService")) + .toReturn(groupManagementProviderService); + PowerMockito.stub(PowerMockito.method(PrivilegedCarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(context); + Mockito.reset(groupManagementProviderService); + Mockito.doThrow(new GroupManagementException()).when(groupManagementProviderService) + .getGroups(Mockito.anyString(), Mockito.any(GroupPaginationRequest.class)); + Response response = groupManagementService.getGroups("test", "admin", 0, 10); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "GetGroups request succeeded with in-valid parameters"); + } + + @Test(description = "This method tests the behaviour of getGroupCount method under valid conditions and invalid " + + "conditions") + public void testGetGroupCount() throws GroupManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getGroupManagementProviderService")) + .toReturn(groupManagementProviderService); + PowerMockito.stub(PowerMockito.method(PrivilegedCarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(context); + Mockito.doReturn(2).when(groupManagementProviderService).getGroupCount(Mockito.anyString()); + Response response = groupManagementService.getGroupCount(); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "GetGroupCount request failed with valid parameters"); + Mockito.reset(groupManagementProviderService); + Mockito.doThrow(new GroupManagementException()).when(groupManagementProviderService) + .getGroupCount(Mockito.anyString()); + response = groupManagementService.getGroupCount(); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "GetGroupCount request succeeded with in-valid parameters"); + } + + @Test(description = "This method tests the behaviour of createGroup method under valid and invalid scenarios") + public void testCreateGroup() throws GroupManagementException, GroupAlreadyExistException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getGroupManagementProviderService")) + .toReturn(groupManagementProviderService); + PowerMockito.stub(PowerMockito.method(PrivilegedCarbonContext.class, "getThreadLocalCarbonContext")) + .toReturn(context); + Response response = groupManagementService.createGroup(null); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "createGroup request succeeded with the group equals to null"); + Mockito.doNothing().when(groupManagementProviderService) + .createGroup(Mockito.any(), Mockito.any(), Mockito.any()); + response = groupManagementService.createGroup(new DeviceGroup()); + Assert.assertEquals(response.getStatus(), Response.Status.CREATED.getStatusCode(), + "createGroup request failed for a request with valid parameters"); + Mockito.reset(groupManagementProviderService); + Mockito.doThrow(new GroupManagementException()).when(groupManagementProviderService) + .createGroup(Mockito.any(), Mockito.any(), Mockito.any()); + response = groupManagementService.createGroup(new DeviceGroup()); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "createGroup request succeeded for a request with in-valid parameters"); + Mockito.reset(groupManagementProviderService); + Mockito.doThrow(new GroupAlreadyExistException()).when(groupManagementProviderService) + .createGroup(Mockito.any(), Mockito.any(), Mockito.any()); + response = groupManagementService.createGroup(new DeviceGroup()); + Assert.assertEquals(response.getStatus(), Response.Status.CONFLICT.getStatusCode(), + "createGroup request succeeded for a request with in-valid parameters"); + } + + @Test(description = "This method tests the functionality of getGroup method under various conditions") + public void testGetGroup() throws GroupManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getGroupManagementProviderService")) + .toReturn(groupManagementProviderService); + Mockito.doReturn(new DeviceGroup()).when(groupManagementProviderService).getGroup(1); + Mockito.doReturn(null).when(groupManagementProviderService).getGroup(2); + Mockito.doThrow(new GroupManagementException()).when(groupManagementProviderService).getGroup(3); + Response response = groupManagementService.getGroup(1); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "getGroup request failed for a request with valid parameters"); + response = groupManagementService.getGroup(2); + Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode(), + "getGroup request returned a group for a non-existing group"); + response = groupManagementService.getGroup(3); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "getGroup request returned a group for a in-valid request"); + } + + @Test(description = "This method tests the functionality of updateGroup method under various conditions") + public void testUpdateGroup() throws GroupManagementException, GroupNotExistException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getGroupManagementProviderService")) + .toReturn(groupManagementProviderService); + DeviceGroup deviceGroup = new DeviceGroup(); + deviceGroup.setGroupId(1); + Mockito.doNothing().when(groupManagementProviderService).updateGroup(deviceGroup, 1); + Mockito.doThrow(new GroupManagementException()).when(groupManagementProviderService) + .updateGroup(deviceGroup, 2); + Mockito.doThrow(new GroupNotExistException()).when(groupManagementProviderService).updateGroup(deviceGroup, 3); + Response response = groupManagementService.updateGroup(1, deviceGroup); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "update request failed for a request with valid parameters"); + response = groupManagementService.updateGroup(2, deviceGroup); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "update request succeeded for a in-valid request"); + response = groupManagementService.updateGroup(3, deviceGroup); + Assert.assertEquals(response.getStatus(), Response.Status.CONFLICT.getStatusCode(), + "update request succeeded for a in-valid request"); + response = groupManagementService.updateGroup(4, null); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "update request succeeded for a in-valid request"); + } + + @Test(description = "This method tests the functionality of deleteGroup method under various scenarios") + public void testDeleteGroup() throws GroupManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getGroupManagementProviderService")) + .toReturn(groupManagementProviderService); + Mockito.doReturn(true).when(groupManagementProviderService).deleteGroup(1); + Mockito.doReturn(false).when(groupManagementProviderService).deleteGroup(2); + Mockito.doThrow(new GroupManagementException()).when(groupManagementProviderService).deleteGroup(3); + Response response = groupManagementService.deleteGroup(1); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "delete group request failed for a request with valid parameters"); + response = groupManagementService.deleteGroup(2); + Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode(), + "Non-existing group was successfully deleted"); + response = groupManagementService.deleteGroup(3); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "Deletion succeeded with an erroneous condition."); + } + + @Test(description = "This method tests the functionality of manageGroupSharing under various conditions") + public void testManageGroupSharing() throws GroupManagementException, RoleDoesNotExistException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getGroupManagementProviderService")) + .toReturn(groupManagementProviderService); + Mockito.doNothing().when(groupManagementProviderService).manageGroupSharing(1, null); + Mockito.doThrow(new GroupManagementException("test")).when(groupManagementProviderService) + .manageGroupSharing(2, null); + Mockito.doThrow(new RoleDoesNotExistException()).when(groupManagementProviderService) + .manageGroupSharing(3, null); + Response response = groupManagementService.manageGroupSharing(1, null); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "managegroupSharing request failed for a request with valid parameters"); + response = groupManagementService.manageGroupSharing(2, null); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "managegroupSharing request succeeded for a request with in-valid parameters"); + response = groupManagementService.manageGroupSharing(3, null); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "managegroupSharing request succeeded for a request with in-valid parameters"); + } + + @Test(description = "This method tests the functionality of getGroupRoles under various conditions") + public void testGetGroupRoles() throws GroupManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getGroupManagementProviderService")) + .toReturn(groupManagementProviderService); + Mockito.doReturn(new ArrayList()).when(groupManagementProviderService).getRoles(1); + Mockito.doReturn(null).when(groupManagementProviderService).getRoles(2); + Mockito.doThrow(new GroupManagementException()).when(groupManagementProviderService).getRoles(3); + Response response = groupManagementService.getRolesOfGroup(1); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "getRolesOfGroup request failed for a request with valid parameters"); + response = groupManagementService.getRolesOfGroup(2); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "getRolesOfGroup request failed for a request with valid parameters"); + response = groupManagementService.getRolesOfGroup(3); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "getRolesOfGroup request failed for a request with in-valid parameters"); + } + + @Test(description = "This method tests the getDevicesOfGroup under various conditions") + public void testGetDevicesOfGroup() throws GroupManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getGroupManagementProviderService")) + .toReturn(groupManagementProviderService); + Mockito.doReturn(1).when(groupManagementProviderService).getDeviceCount(Mockito.anyInt()); + Mockito.doReturn(new ArrayList()).when(groupManagementProviderService).getDevices(1, 0, 10); + Mockito.doReturn(null).when(groupManagementProviderService).getDevices(2, 0, 10); + Mockito.doThrow(new GroupManagementException()).when(groupManagementProviderService).getDevices(3, 0, 10); + Response response = groupManagementService.getDevicesOfGroup(1, 0, 10); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "getDevicesOfGroup request failed for a request with valid parameters"); + response = groupManagementService.getDevicesOfGroup(2, 0, 10); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "getDevicesOfGroup request failed for a request with valid parameters"); + response = groupManagementService.getDevicesOfGroup(3, 0, 10); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "getDevicesOfGroup request succeded for a request with in-valid parameters"); + } + + @Test(description = "This method tests the getDeviceCountOfGroup function under various different conditions.") + public void testGetDeviceCountOfGroup() throws GroupManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getGroupManagementProviderService")) + .toReturn(groupManagementProviderService); + Mockito.doReturn(1).when(groupManagementProviderService).getDeviceCount(1); + Mockito.doThrow(new GroupManagementException()).when(groupManagementProviderService).getDeviceCount(2); + Response response = groupManagementService.getDeviceCountOfGroup(1); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "getDeviceCountOfGroup request failed for a request with valid parameters"); + response = groupManagementService.getDeviceCountOfGroup(2); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "getDeviceCountOfGroup request succeded for a request with in-valid parameters"); + } + + @Test(description = "This method tests the addDevicesToGroup method under various conditions.") + public void testAddDevicesToGroup() throws GroupManagementException, DeviceNotFoundException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getGroupManagementProviderService")) + .toReturn(groupManagementProviderService); + List deviceIdentifiers = new ArrayList<>(); + Mockito.doNothing().when(groupManagementProviderService).addDevices(1, deviceIdentifiers); + Mockito.doThrow(new GroupManagementException()).when(groupManagementProviderService).addDevices(2, + deviceIdentifiers); + Mockito.doThrow(new DeviceNotFoundException()).when(groupManagementProviderService).addDevices(3, + deviceIdentifiers); + Response response = groupManagementService.addDevicesToGroup(1, deviceIdentifiers); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "addDevicesToGroup request failed for a request with valid parameters"); + response = groupManagementService.addDevicesToGroup(2, deviceIdentifiers); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "addDevicesToGroup request succeded for a request with in-valid parameters"); + response = groupManagementService.addDevicesToGroup(3, deviceIdentifiers); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "addDevicesToGroup request succeded for a request with in-valid parameters"); + } + + @Test(description = "This method tests the removeDevicesFromGroup method under various conditions.") + public void testRemoveDevicesFromGroup() throws GroupManagementException, DeviceNotFoundException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getGroupManagementProviderService")) + .toReturn(groupManagementProviderService); + List deviceIdentifiers = new ArrayList<>(); + Mockito.doNothing().when(groupManagementProviderService).removeDevice(1, deviceIdentifiers); + Mockito.doThrow(new GroupManagementException()).when(groupManagementProviderService).removeDevice(2, + deviceIdentifiers); + Mockito.doThrow(new DeviceNotFoundException()).when(groupManagementProviderService).removeDevice(3, + deviceIdentifiers); + Response response = groupManagementService.removeDevicesFromGroup(1, deviceIdentifiers); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "removeDevicesFromGroup request failed for a request with valid parameters"); + response = groupManagementService.removeDevicesFromGroup(2, deviceIdentifiers); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "removeDevicesFromGroup request succeeded for a request with in-valid parameters"); + response = groupManagementService.removeDevicesFromGroup(3, deviceIdentifiers); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "removeDevicesFromGroup request succeeded for a request with in-valid parameters"); + } + + @Test(description = "This method tests the getGroups with device id and device type under different conditions") + public void testGetGroupsWithDeviceId() throws GroupManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getGroupManagementProviderService")) + .toReturn(groupManagementProviderService); + DeviceIdentifier deviceIdentifier = new DeviceIdentifier("test", "android"); + Mockito.doReturn(new ArrayList()).when(groupManagementProviderService).getGroups(deviceIdentifier); + Response response = groupManagementService.getGroups("test", "android"); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "getGroups request failed with valid parameters"); + Mockito.reset(groupManagementProviderService); + Mockito.doThrow(new GroupManagementException()).when(groupManagementProviderService) + .getGroups(Mockito.any(DeviceIdentifier.class)); + response = groupManagementService.getGroups("test", "android2"); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "getGroups request succeeded with in-valid parameters"); + } + + @Test(description = "This method tests updateDeviceAssigningToGroups under different conditions.") + public void testUpdateDeviceAssigningToGroups() throws GroupManagementException, DeviceNotFoundException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getGroupManagementProviderService")) + .toReturn(groupManagementProviderService); + Mockito.reset(groupManagementProviderService); + DeviceToGroupsAssignment deviceToGroupsAssignment = new DeviceToGroupsAssignment(); + List groupIds = new ArrayList<>(); + groupIds.add(1); + groupIds.add(2); + deviceToGroupsAssignment.setDeviceGroupIds(groupIds); + deviceToGroupsAssignment.setDeviceIdentifier(new DeviceIdentifier("test", "android")); + List deviceGroups = new ArrayList<>(); + DeviceGroup deviceGroup = new DeviceGroup(); + deviceGroup.setGroupId(1); + deviceGroups.add(deviceGroup); + deviceGroup = new DeviceGroup(); + deviceGroup.setGroupId(3); + deviceGroup.setOwner(CarbonConstants.REGISTRY_SYSTEM_USERNAME); + deviceGroups.add(deviceGroup); + deviceGroup = new DeviceGroup(); + deviceGroup.setGroupId(4); + deviceGroup.setOwner("test"); + deviceGroups.add(deviceGroup); + Mockito.doReturn(deviceGroups).when(groupManagementProviderService) + .getGroups(Mockito.any(DeviceIdentifier.class)); + Mockito.doNothing().when(groupManagementProviderService).addDevices(Mockito.anyInt(), Mockito.any()); + Mockito.doNothing().when(groupManagementProviderService).removeDevice(Mockito.anyInt(), Mockito.any()); + Response response = groupManagementService.updateDeviceAssigningToGroups(deviceToGroupsAssignment); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "updateDeviceAssigningToGroups request failed with valid parameters"); + Mockito.doThrow(new DeviceNotFoundException()).when(groupManagementProviderService) + .removeDevice(Mockito.anyInt(), Mockito.any()); + response = groupManagementService.updateDeviceAssigningToGroups(deviceToGroupsAssignment); + Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(), + "updateDeviceAssigningToGroups request succeeded with in-valid parameters"); + Mockito.doThrow(new GroupManagementException()).when(groupManagementProviderService) + .getGroups(Mockito.any(DeviceIdentifier.class)); + response = groupManagementService.updateDeviceAssigningToGroups(deviceToGroupsAssignment); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "updateDeviceAssigningToGroups request succeeded with in-valid parameters"); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/NotificationManagementServiceImplTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/NotificationManagementServiceImplTest.java new file mode 100644 index 0000000000..92e321745f --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/NotificationManagementServiceImplTest.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ + +package org.wso2.carbon.device.mgt.jaxrs.service.impl; + +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; +import org.testng.Assert; +import org.testng.IObjectFactory; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.ObjectFactory; +import org.testng.annotations.Test; +import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.device.mgt.common.PaginationResult; +import org.wso2.carbon.device.mgt.common.notification.mgt.Notification; +import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementException; +import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementService; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.utils.multitenancy.MultitenantUtils; +import javax.ws.rs.core.Response; +import java.util.ArrayList; +import java.util.List; + +import static org.mockito.MockitoAnnotations.initMocks; + +/** + * This is a test class for {@link NotificationManagementServiceImpl}. + */ +@PowerMockIgnore("javax.ws.rs.*") +@SuppressStaticInitializationFor({"org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils", + "org.wso2.carbon.context.CarbonContext"}) +@PrepareForTest({DeviceMgtAPIUtils.class, MultitenantUtils.class, CarbonContext.class}) +public class NotificationManagementServiceImplTest { + private NotificationManagementService notificationManagementService; + private org.wso2.carbon.device.mgt.jaxrs.service.api.NotificationManagementService notificationManagement; + + @ObjectFactory + public IObjectFactory getObjectFactory() { + return new org.powermock.modules.testng.PowerMockObjectFactory(); + } + + @BeforeClass + public void setup() throws UserStoreException, NotificationManagementException { + initMocks(this); + notificationManagementService = Mockito.mock(NotificationManagementService.class); + PaginationResult paginationResult = new PaginationResult(); + List notifications = new ArrayList<>(); + notifications.add(new Notification()); + paginationResult.setData(notifications); + paginationResult.setRecordsTotal(1); + Mockito.doReturn(paginationResult).when(notificationManagementService).getAllNotifications(Mockito.any()); + Mockito.doReturn(paginationResult).when(notificationManagementService) + .getNotificationsByStatus(Mockito.any(), Mockito.any()); + notificationManagement = new NotificationManagementServiceImpl(); + } + + @Test(description = "This method tests the behaviour of getNotifications method under different conditions") + public void testGetNotifications() throws NotificationManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getNotificationManagementService")) + .toReturn(this.notificationManagementService); + Response response = notificationManagement.getNotifications("NEW", "test", 0, 10); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), "Notification retrieval failed"); + response = notificationManagement.getNotifications(null, "test", 0, 10); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), "Notification retrieval failed"); + Mockito.reset(this.notificationManagementService); + Mockito.doThrow(new NotificationManagementException()).when(notificationManagementService) + .getAllNotifications(Mockito.any()); + response = notificationManagement.getNotifications(null, "test", 0, 10); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "Notification retrieval succeeded with issues in NotificationManagement OSGI service"); + Mockito.reset(this.notificationManagementService); + } + + @Test(description = "This method tests the behaviour of updateNotificationStatus method under different conditions") + public void testUpdateNotificationStatus() throws NotificationManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getNotificationManagementService")) + .toReturn(this.notificationManagementService); + Mockito.doReturn(true).when(notificationManagementService) + .updateNotificationStatus(1, Notification.Status.CHECKED); + Mockito.doThrow(NotificationManagementException.class).when(notificationManagementService) + .updateNotificationStatus(2, Notification.Status.CHECKED); + Mockito.doReturn(true).when(notificationManagementService) + .updateNotificationStatus(3, Notification.Status.CHECKED); + Mockito.doReturn(new Notification()).when(notificationManagementService).getNotification(1); + Mockito.doThrow(new NotificationManagementException()).when(notificationManagementService).getNotification(3); + Response response = notificationManagement.updateNotificationStatus(1); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "Notification status update failed under correct conditions"); + response = notificationManagement.updateNotificationStatus(2); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "Notification status update succeeded under erroneous conditions"); + response = notificationManagement.updateNotificationStatus(3); + Assert.assertEquals(response.getEntity(), + "Notification updated successfully. But the retrial of the updated " + "notification failed", + "Notification status update succeeded under erroneous conditions"); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImplTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImplTest.java new file mode 100644 index 0000000000..bcee738b6e --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImplTest.java @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + * + */ + +package org.wso2.carbon.device.mgt.jaxrs.service.impl; + +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; +import org.testng.Assert; +import org.testng.IObjectFactory; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.ObjectFactory; +import org.testng.annotations.Test; +import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderServiceImpl; +import org.wso2.carbon.device.mgt.jaxrs.beans.BasicUserInfo; +import org.wso2.carbon.device.mgt.jaxrs.beans.EnrollmentInvitation; +import org.wso2.carbon.device.mgt.jaxrs.beans.UserInfo; +import org.wso2.carbon.device.mgt.jaxrs.service.api.UserManagementService; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; +import org.wso2.carbon.user.api.RealmConfiguration; +import org.wso2.carbon.user.api.UserRealm; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.api.UserStoreManager; +import org.wso2.carbon.utils.multitenancy.MultitenantUtils; + +import javax.ws.rs.core.Response; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +import static org.mockito.MockitoAnnotations.initMocks; + +/** + * This is a test case for {@link UserManagementService}. + */ +@PowerMockIgnore("javax.ws.rs.*") +@SuppressStaticInitializationFor({"org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils", + "org.wso2.carbon.context.CarbonContext"}) +@PrepareForTest({DeviceMgtAPIUtils.class, MultitenantUtils.class, CarbonContext.class}) +public class UserManagementServiceImplTest { + private UserStoreManager userStoreManager; + private UserManagementService userManagementService; + private DeviceManagementProviderService deviceManagementProviderService; + private static final String DEFAULT_DEVICE_USER = "Internal/devicemgt-user"; + private UserRealm userRealm; + private EnrollmentInvitation enrollmentInvitation; + private List userList; + private static final String TEST_USERNAME = "test"; + private static final String TEST2_USERNAME = "test2"; + private static final String TEST3_USERNAME = "test3"; + + @ObjectFactory + public IObjectFactory getObjectFactory() { + return new org.powermock.modules.testng.PowerMockObjectFactory(); + } + + @BeforeClass + public void setup() throws UserStoreException { + initMocks(this); + userManagementService = new UserManagementServiceImpl(); + userStoreManager = Mockito.mock(UserStoreManager.class, Mockito.RETURNS_MOCKS); + deviceManagementProviderService = Mockito + .mock(DeviceManagementProviderServiceImpl.class, Mockito.CALLS_REAL_METHODS); + userRealm = Mockito.mock(UserRealm.class); + RealmConfiguration realmConfiguration = Mockito.mock(RealmConfiguration.class); + Mockito.doReturn(null).when(realmConfiguration).getSecondaryRealmConfig(); + Mockito.doReturn(realmConfiguration).when(userRealm).getRealmConfiguration(); + enrollmentInvitation = new EnrollmentInvitation(); + List recipients = new ArrayList<>(); + recipients.add(TEST_USERNAME); + enrollmentInvitation.setDeviceType("android"); + enrollmentInvitation.setRecipients(recipients); + userList = new ArrayList<>(); + userList.add(TEST_USERNAME); + } + + @Test(description = "This method tests the addUser method of UserManagementService") + public void testAddUser() throws UserStoreException, ConfigurationManagementException, DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager")) + .toReturn(this.userStoreManager); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.doReturn(true).when(userStoreManager).isExistingUser("admin"); + Mockito.doAnswer(new Answer() { + private int count = 0; + + public Object answer(InvocationOnMock invocation) { + if (count == 0) { + count++; + return false; + } else { + return true; + } + } + }).when(userStoreManager).isExistingUser(TEST_USERNAME); + + Mockito.doReturn("test@test.com").when(userStoreManager) + .getUserClaimValue(TEST_USERNAME, Constants.USER_CLAIM_EMAIL_ADDRESS, null); + Mockito.doReturn(TEST_USERNAME).when(userStoreManager) + .getUserClaimValue(TEST_USERNAME, Constants.USER_CLAIM_FIRST_NAME, null); + Mockito.doReturn(TEST_USERNAME).when(userStoreManager) + .getUserClaimValue(TEST_USERNAME, Constants.USER_CLAIM_LAST_NAME, null); + Mockito.doNothing().when(userStoreManager) + .addUser(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()); + UserInfo userInfo = new UserInfo(); + userInfo.setUsername("admin"); + Response response = userManagementService.addUser(userInfo); + Assert.assertEquals(response.getStatus(), Response.Status.CONFLICT.getStatusCode(), + "Same user can be added " + "twice"); + userInfo = getUserInfo(); + Mockito.doReturn(true).when(userStoreManager).isExistingRole(DEFAULT_DEVICE_USER); + Mockito.doNothing().when(deviceManagementProviderService).sendRegistrationEmail(Mockito.any()); + response = userManagementService.addUser(userInfo); + Assert.assertEquals(response.getStatus(), Response.Status.CREATED.getStatusCode(), "User addition failed"); + } + + @Test(description = "This method tests the getUser method of UserManagementService", dependsOnMethods = + "testAddUser") + public void testGetUser() throws UserStoreException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager")) + .toReturn(this.userStoreManager); + Response response = userManagementService.getUser(TEST_USERNAME, null, null); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), "User retrieval failed"); + BasicUserInfo userInfo = (BasicUserInfo) response.getEntity(); + Assert.assertEquals(userInfo.getFirstname(), TEST_USERNAME, + "Retrieved user object is different from the original one " + "saved"); + + Mockito.doReturn(false).when(userStoreManager).isExistingUser(TEST2_USERNAME); + response = userManagementService.getUser(TEST2_USERNAME, null, null); + Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode(), + "Non-existing user was retrieved successfully"); + } + + @Test(description = "This method tests the updateUser method of UserManagementService", dependsOnMethods = + {"testGetUser"}) + public void testUpdateUser() throws UserStoreException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager")) + .toReturn(this.userStoreManager); + Response response = userManagementService.updateUser(TEST2_USERNAME, null, null); + Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode(), + "Non-existing user was successfully updated"); + String[] roles = { "Internal/everyone", DEFAULT_DEVICE_USER }; + Mockito.doReturn(roles).when(userStoreManager).getRoleListOfUser(TEST_USERNAME); + Mockito.doNothing().when(userStoreManager).updateRoleListOfUser(Mockito.any(), Mockito.any(), Mockito.any()); + Mockito.doNothing().when(userStoreManager).setUserClaimValues(Mockito.any(), Mockito.any(), Mockito.any()); + response = userManagementService.updateUser(TEST_USERNAME, null, getUserInfo()); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), "Updating the user info failed"); + } + + + @Test(description = "This method tests the getRolesOfUser method of UserManagementService", dependsOnMethods = + {"testUpdateUser"}) + public void testGetRolesOfUser() { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager")) + .toReturn(this.userStoreManager); + Response response = userManagementService.getRolesOfUser(TEST2_USERNAME, null); + Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode(), + "Roles of a non-existing user was successfully retrieved"); + response = userManagementService.getRolesOfUser(TEST_USERNAME, null); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "Retrieval of roles of a existing user failed."); + } + + @Test(description = "This method tests the IsUserExists method of UserManagementService", dependsOnMethods = + {"testGetRolesOfUser"}) + public void testIsUserExists() { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager")) + .toReturn(this.userStoreManager); + Response response = userManagementService.isUserExists(TEST2_USERNAME); + boolean responseEntity = (boolean) response.getEntity(); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "Check for existence of user failed"); + Assert.assertFalse(responseEntity, "Non-existing user is identified as already existing user"); + response = userManagementService.isUserExists(TEST_USERNAME); + responseEntity = (boolean) response.getEntity(); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "Check for existence of user failed"); + Assert.assertTrue(responseEntity, "Existing user is identified as non-existing user"); + } + + @Test(description = "This method tests the send invitation method of UserManagementService", dependsOnMethods = + {"testIsUserExists"}) + public void testSendInvitation() throws ConfigurationManagementException, DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager")) + .toReturn(this.userStoreManager); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.doNothing().when(deviceManagementProviderService).sendEnrolmentInvitation(Mockito.any(), Mockito.any()); + Response response = userManagementService.inviteExistingUsersToEnrollDevice(userList); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "Inviting existing users to enroll device failed"); + } + + @Test(description = "This method tests the getUserNames method of UserManagementService", dependsOnMethods = + {"testSendInvitation"}) + public void testGetUserNames() throws UserStoreException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager")) + .toReturn(this.userStoreManager); + Mockito.doReturn(new String[] { TEST_USERNAME }).when(userStoreManager) + .listUsers(Mockito.anyString(), Mockito.anyInt()); + Response response = userManagementService.getUserNames(TEST_USERNAME, null, "00", 0, 0); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "Getting user names is failed for a valid request"); + + } + + @Test(description = "This method tests the getUsers method of UserManagementService", + dependsOnMethods = {"testGetUserNames"}) + public void testGetUsers() { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager")) + .toReturn(userStoreManager); + Response response = userManagementService.getUsers(null, "00", 0, 10); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), "GetUsers request failed"); + } + + @Test(description = "This method tests the inviteToEnrollDevice method of UserManagementService", + dependsOnMethods = "testGetUsers") + public void testInviteToEnrollDevice() { + URL resourceUrl = ClassLoader.getSystemResource("testng.xml"); + System.setProperty("carbon.home", resourceUrl.getPath()); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager")) + .toReturn(this.userStoreManager); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getAuthenticatedUser")).toReturn(TEST_USERNAME); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + EnrollmentInvitation enrollmentInvitation = new EnrollmentInvitation(); + List recipients = new ArrayList<>(); + recipients.add(TEST_USERNAME); + enrollmentInvitation.setDeviceType("android"); + enrollmentInvitation.setRecipients(recipients); + Response response = userManagementService.inviteToEnrollDevice(enrollmentInvitation); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "Inviting users to enroll device failed"); + } + + @Test(description = "This method tests the removeUser method of UserManagementService", dependsOnMethods = + "testInviteToEnrollDevice") + public void testRemoveUser() throws DeviceManagementException, UserStoreException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager")) + .toReturn(this.userStoreManager); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.doReturn(true).when(deviceManagementProviderService).setStatus(Mockito.anyString(), Mockito.any()); + Mockito.doNothing().when(userStoreManager).deleteUser(Mockito.anyString()); + Response response = userManagementService.removeUser(TEST_USERNAME, null); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), + "Cannot remove user, the request failed"); + response = userManagementService.removeUser(TEST2_USERNAME, null); + Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode(), + "Successfully removed non-existing user"); + } + + @Test(description = "This method tests the behaviour of getUserCount method of UserManagementService", + dependsOnMethods = {"testRemoveUser"}) + public void testGetUserCount() throws UserStoreException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserRealm")).toReturn(userRealm); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreCountRetrieverService")) + .toReturn(null); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager")) + .toReturn(this.userStoreManager); + Response response = userManagementService.getUserCount(); + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), "User count retrieval failed"); + } + + @Test(description = "This method tests the behaviour of methods when there is an issue with " + + "DeviceManagementProviderService", dependsOnMethods = {"testGetUserCount"}) + public void testNegativeScenarios1() throws ConfigurationManagementException, DeviceManagementException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager")) + .toReturn(this.userStoreManager); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getAuthenticatedUser")).toReturn(TEST_USERNAME); + Mockito.reset(deviceManagementProviderService); + Mockito.doThrow(new DeviceManagementException()).when(deviceManagementProviderService) + .sendEnrolmentInvitation(Mockito.any(), Mockito.any()); + Response response = userManagementService.inviteExistingUsersToEnrollDevice(userList); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "Invite existing users to enroll device succeeded under erroneous conditions"); + response = userManagementService.inviteToEnrollDevice(enrollmentInvitation); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "Invite existing users to enroll device succeeded under erroneous conditions"); + } + + @Test(description = "This method tests the behaviour of the different methods when there is an issue is " + + "userStoreManager", dependsOnMethods = {"testNegativeScenarios1"}) + public void testNegativeScenarios2() throws UserStoreException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager")) + .toReturn(this.userStoreManager); + Mockito.doThrow(new UserStoreException()).when(userStoreManager).isExistingUser(TEST3_USERNAME); + Response response = userManagementService.getUser(TEST3_USERNAME, null, null); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "Response returned successful for a user retrieval with problematic inputs"); + UserInfo userInfo = new UserInfo(); + userInfo.setUsername(TEST3_USERNAME); + response = userManagementService.addUser(userInfo); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "Response returned successful for a user addition with problematic inputs"); + response = userManagementService.updateUser(TEST3_USERNAME, null, userInfo); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "Response returned successful for a user updating request with problematic inputs"); + response = userManagementService.removeUser(TEST3_USERNAME, null); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "Response returned successful for a user removal request with problematic inputs"); + response = userManagementService.getRolesOfUser(TEST3_USERNAME, null); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "Response returned successful for a user role retrieval request with problematic inputs"); + response = userManagementService.isUserExists(TEST3_USERNAME); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "Response returned successful for checking existence of user under problematic conditions"); + } + + @Test(description = "This method tests the behaviour of various methods when there is an issue with UserStore " + + "Manager", dependsOnMethods = {"testNegativeScenarios2"}) + public void testNegativeScenarios3() throws UserStoreException { + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreManager")) + .toReturn(this.userStoreManager); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserRealm")).toReturn(userRealm); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getUserStoreCountRetrieverService")) + .toReturn(null); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getAuthenticatedUser")).toReturn(TEST_USERNAME); + PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) + .toReturn(this.deviceManagementProviderService); + Mockito.reset(this.userStoreManager); + Mockito.doThrow(new UserStoreException()).when(userStoreManager) + .getUserClaimValue(Mockito.any(), Mockito.any(), Mockito.any()); + Mockito.doThrow(new UserStoreException()).when(userStoreManager) + .listUsers(Mockito.anyString(), Mockito.anyInt()); + Response response = userManagementService.getUsers(TEST_USERNAME, "00", 0, 10); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "Response returned successful for a users retrieval request."); + response = userManagementService.getUserCount(); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "Response returned successful for a user count retrieval request."); + response = userManagementService.getUserNames(TEST_USERNAME, null, "00", 0, 10); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "Response returned successful for a user count retrieval request."); + response = userManagementService.inviteToEnrollDevice(enrollmentInvitation); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "Invite existing users to enroll device succeeded under erroneous conditions"); + response = userManagementService.inviteExistingUsersToEnrollDevice(userList); + Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + "Invite existing users to enroll device succeeded under erroneous conditions"); + } + + /** + * To get the user info of a user + * + * @return UserInfo of the User. + */ + private UserInfo getUserInfo() { + UserInfo userInfo = new UserInfo(); + userInfo.setUsername(TEST_USERNAME); + userInfo.setFirstname(TEST_USERNAME); + userInfo.setLastname(TEST_USERNAME); + userInfo.setEmailAddress("test@test.com"); + return userInfo; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/DeviceMgtAPITestHelper.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/DeviceMgtAPITestHelper.java new file mode 100644 index 0000000000..f1f0d1628d --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/DeviceMgtAPITestHelper.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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. + */ +package org.wso2.carbon.device.mgt.jaxrs.service.impl.util; + +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.EnrolmentInfo; +import org.wso2.carbon.device.mgt.common.device.details.DeviceInfo; +import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig; +import org.wso2.carbon.device.mgt.common.type.mgt.DeviceTypeMetaDefinition; +import org.wso2.carbon.device.mgt.core.dto.DeviceType; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * Helper class for Device Management API test cases. + */ +public class DeviceMgtAPITestHelper { + + private static final String DEVICE_TYPE_DESCRIPTION = "Dummy Description"; + public static final String DEVICE_TYPE = "TEST_DEVICE_TYPE"; + public static final String DEVICE_NAME = "TEST_DEVICE"; + public final static String OWNER = "admin"; + + /** + * Creates a Device Type with given name and given id. + * If the name is null, the TEST_DEVICE_TYPE will be used as the name. + * + * @param name : Name of the device type. + * @param deviceTypeId : The Id of the device type. + * @return DeviceType + */ + public static DeviceType getDummyDeviceType(String name, int deviceTypeId) { + DeviceType deviceType = new DeviceType(); + deviceType.setId(deviceTypeId); + deviceType.setName(name != null ? name : DEVICE_TYPE); + + DeviceTypeMetaDefinition deviceTypeMetaDefinition = new DeviceTypeMetaDefinition(); + deviceTypeMetaDefinition.setClaimable(true); + deviceTypeMetaDefinition.setDescription(DEVICE_TYPE_DESCRIPTION); + + PushNotificationConfig pushNotificationConfig = + new PushNotificationConfig(name, true, null); + deviceTypeMetaDefinition.setPushNotificationConfig(pushNotificationConfig); + + deviceType.setDeviceTypeMetaDefinition(deviceTypeMetaDefinition); + return deviceType; + } + + /** + * Generates a list of device types. + * + * @param count: The number of device types that is needed. + * @return List : A list of device types. + */ + public static List getDummyDeviceTypeList(int count) { + List deviceTypes = new ArrayList<>(); + + for (int i = 0; i < count; i++) { + DeviceType deviceType = getDummyDeviceType(DEVICE_TYPE + count, count); + deviceTypes.add(deviceType); + } + + return deviceTypes; + } + + public static Device generateDummyDevice(String deviceType, String identifier) { + Device device = new Device(); + device.setEnrolmentInfo(generateEnrollmentInfo(new Date().getTime(), new Date().getTime(), OWNER, EnrolmentInfo + .OwnerShip.BYOD, EnrolmentInfo.Status.ACTIVE)); + device.setDescription("Test Description"); + device.setDeviceIdentifier(identifier); + device.setType(deviceType); + device.setDeviceInfo(generateDeviceInfo()); + device.setName(DEVICE_NAME); + device.setFeatures(new ArrayList<>()); + device.setProperties(new ArrayList<>()); + return device; + } + + public static EnrolmentInfo generateEnrollmentInfo(long dateOfEnrollment, long dateOfLastUpdate, + String owner, EnrolmentInfo.OwnerShip ownership, + EnrolmentInfo.Status status) { + EnrolmentInfo enrolmentInfo = new EnrolmentInfo(); + enrolmentInfo.setDateOfEnrolment(dateOfEnrollment); + enrolmentInfo.setDateOfLastUpdate(dateOfLastUpdate); + enrolmentInfo.setOwner(owner); + enrolmentInfo.setOwnership(ownership); + enrolmentInfo.setStatus(status); + return enrolmentInfo; + } + + public static DeviceInfo generateDeviceInfo() { + DeviceInfo deviceInfo = new DeviceInfo(); + deviceInfo.setDeviceModel("DUMMY_MODEL"); + deviceInfo.setVendor("WSO2"); + deviceInfo.setOsVersion("OREO"); + deviceInfo.setOsBuildDate("24-05-2017"); + deviceInfo.setBatteryLevel(25.0); + deviceInfo.setInternalTotalMemory(1.5); + deviceInfo.setInternalAvailableMemory(2.5); + deviceInfo.setExternalTotalMemory(16.76); + deviceInfo.setExternalAvailableMemory(4.56); + deviceInfo.setConnectionType("CON_TYPE"); + deviceInfo.setSsid("SSID"); + deviceInfo.setCpuUsage(23.5); + deviceInfo.setTotalRAMMemory(1.5); + deviceInfo.setAvailableRAMMemory(2.33); + deviceInfo.setPluggedIn(true); + return deviceInfo; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/resources/log4j.properties b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/resources/log4j.properties new file mode 100644 index 0000000000..e415fd607d --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/resources/log4j.properties @@ -0,0 +1,34 @@ +# +# Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +# +# WSO2 Inc. licenses this file to you 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. +# + +# +# This is the log4j configuration file used by WSO2 Carbon +# +# IMPORTANT : Please do not remove or change the names of any +# of the Appender defined here. The layout pattern & log file +# can be changed using the WSO2 Carbon Management Console, and those +# settings will override the settings in this file. +# + +log4j.rootLogger=DEBUG, STD_OUT + +# Redirect log messages to console +log4j.appender.STD_OUT=org.apache.log4j.ConsoleAppender +log4j.appender.STD_OUT.Target=System.out +log4j.appender.STD_OUT.layout=org.apache.log4j.PatternLayout +log4j.appender.STD_OUT.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/resources/testng.xml b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/resources/testng.xml new file mode 100644 index 0000000000..8eef632459 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/resources/testng.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/components/device-mgt/pom.xml b/components/device-mgt/pom.xml index dd5aaad4d2..721d76356f 100644 --- a/components/device-mgt/pom.xml +++ b/components/device-mgt/pom.xml @@ -38,6 +38,7 @@ org.wso2.carbon.device.mgt.extensions org.wso2.carbon.device.mgt.ui org.wso2.carbon.device.mgt.api + org.wso2.carbon.device.mgt.v09.api org.wso2.carbon.device.mgt.analytics.data.publisher org.wso2.carbon.device.mgt.url.printer diff --git a/features/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api.feature/pom.xml b/features/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api.feature/pom.xml new file mode 100644 index 0000000000..f8d317e945 --- /dev/null +++ b/features/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api.feature/pom.xml @@ -0,0 +1,123 @@ + + + + + + + org.wso2.carbon.devicemgt + certificate-mgt-feature + 3.0.185-SNAPSHOT + ../pom.xml + + + 4.0.0 + org.wso2.carbon.certificate.mgt.cert.admin.v09.api.feature + pom + WSO2 Carbon - Admin Certificate Management v0.9 API Feature + http://wso2.org + This feature contains the v0.9 APIs required for Admin Certificate Management. + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy + package + + copy + + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.certificate.mgt.cert.admin.v09.api + + ${project.version} + war + true + + ${project.build.directory}/maven-shared-archive-resources/webapps + + api#certificate-mgt#v0.9.war + + + + + + + + org.apache.maven.plugins + maven-resources-plugin + + + copy-resources + generate-resources + + copy-resources + + + src/main/resources + + + resources + + build.properties + p2.inf + + + + + + + + + org.wso2.maven + carbon-p2-plugin + + + p2-feature-generation + package + + p2-feature-gen + + + org.wso2.carbon.certificate.mgt.cert.admin.v09.api + ../../../features/etc/feature.properties + + + + org.wso2.carbon.p2.category.type:server + + org.eclipse.equinox.p2.type.group:false + + + + + + + + + + + diff --git a/features/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api.feature/src/main/resources/build.properties b/features/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api.feature/src/main/resources/build.properties new file mode 100644 index 0000000000..9c86577d76 --- /dev/null +++ b/features/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api.feature/src/main/resources/build.properties @@ -0,0 +1 @@ +custom = true diff --git a/features/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api.feature/src/main/resources/p2.inf b/features/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api.feature/src/main/resources/p2.inf new file mode 100644 index 0000000000..702771b5ec --- /dev/null +++ b/features/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api.feature/src/main/resources/p2.inf @@ -0,0 +1,2 @@ +instructions.configure = \ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.certificate.mgt.cert.admin.v09.api_${feature.version}/webapps/api#certificate-mgt#v0.9.war,target:${installFolder}/../../deployment/server/webapps/api#certificate-mgt#v0.9.war,overwrite:true);\ \ No newline at end of file diff --git a/features/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api.feature/pom.xml b/features/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api.feature/pom.xml new file mode 100644 index 0000000000..4985c884c8 --- /dev/null +++ b/features/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api.feature/pom.xml @@ -0,0 +1,123 @@ + + + + + + + org.wso2.carbon.devicemgt + certificate-mgt-feature + 3.0.185-SNAPSHOT + ../pom.xml + + + 4.0.0 + org.wso2.carbon.certificate.mgt.v09.api.feature + pom + WSO2 Carbon - Certificate Management v0.9 API Feature + http://wso2.org + This feature contains the v0.9 APIs required for Certificate Management. + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy + package + + copy + + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.certificate.mgt.v09.api + + ${project.version} + war + true + + ${project.build.directory}/maven-shared-archive-resources/webapps + + api#scep-mgt#v0.9.war + + + + + + + + org.apache.maven.plugins + maven-resources-plugin + + + copy-resources + generate-resources + + copy-resources + + + src/main/resources + + + resources + + build.properties + p2.inf + + + + + + + + + org.wso2.maven + carbon-p2-plugin + + + p2-feature-generation + package + + p2-feature-gen + + + org.wso2.carbon.certificate.mgt.v09.api + ../../../features/etc/feature.properties + + + + org.wso2.carbon.p2.category.type:server + + org.eclipse.equinox.p2.type.group:false + + + + + + + + + + + diff --git a/features/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api.feature/src/main/resources/build.properties b/features/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api.feature/src/main/resources/build.properties new file mode 100644 index 0000000000..9c86577d76 --- /dev/null +++ b/features/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api.feature/src/main/resources/build.properties @@ -0,0 +1 @@ +custom = true diff --git a/features/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api.feature/src/main/resources/p2.inf b/features/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api.feature/src/main/resources/p2.inf new file mode 100644 index 0000000000..cf6df69050 --- /dev/null +++ b/features/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api.feature/src/main/resources/p2.inf @@ -0,0 +1,2 @@ +instructions.configure = \ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.certificate.mgt.v09.api_${feature.version}/webapps/api#scep-mgt#v0.9.war,target:${installFolder}/../../deployment/server/webapps/api#scep-mgt#v0.9.war,overwrite:true);\ \ No newline at end of file diff --git a/features/certificate-mgt/pom.xml b/features/certificate-mgt/pom.xml index 304fabed8f..c3c27c3769 100644 --- a/features/certificate-mgt/pom.xml +++ b/features/certificate-mgt/pom.xml @@ -37,7 +37,9 @@ org.wso2.carbon.certificate.mgt.server.feature org.wso2.carbon.certificate.mgt.api.feature + org.wso2.carbon.certificate.mgt.v09.api.feature org.wso2.carbon.certificate.mgt.cert.admin.api.feature + org.wso2.carbon.certificate.mgt.cert.admin.v09.api.feature diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.server.feature/pom.xml b/features/device-mgt/org.wso2.carbon.device.mgt.server.feature/pom.xml index 3743150152..3a71520fbf 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.server.feature/pom.xml +++ b/features/device-mgt/org.wso2.carbon.device.mgt.server.feature/pom.xml @@ -45,6 +45,11 @@ org.wso2.carbon.device.mgt.api.feature zip + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.v09.api.feature + zip + org.wso2.carbon.devicemgt org.wso2.carbon.device.mgt.url.printer @@ -113,6 +118,9 @@ org.wso2.carbon.devicemgt:org.wso2.carbon.device.mgt.api.feature:${carbon.device.mgt.version} + + org.wso2.carbon.devicemgt:org.wso2.carbon.device.mgt.v09.api.feature:${carbon.device.mgt.version} + diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.v09.api.feature/pom.xml b/features/device-mgt/org.wso2.carbon.device.mgt.v09.api.feature/pom.xml new file mode 100644 index 0000000000..02c4046c8b --- /dev/null +++ b/features/device-mgt/org.wso2.carbon.device.mgt.v09.api.feature/pom.xml @@ -0,0 +1,122 @@ + + + + + + + org.wso2.carbon.devicemgt + device-mgt-feature + 3.0.185-SNAPSHOT + ../pom.xml + + + 4.0.0 + org.wso2.carbon.device.mgt.v09.api.feature + pom + WSO2 Carbon - Device Management v0.9 API Feature + http://wso2.org + This feature contains the v0.9 APIs required for Device Management console UI + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy + package + + copy + + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.v09.api + + ${project.version} + war + true + + ${project.build.directory}/maven-shared-archive-resources/webapps + + api#device-mgt#v0.9.war + + + + + + + + org.apache.maven.plugins + maven-resources-plugin + + + copy-resources + generate-resources + + copy-resources + + + src/main/resources + + + resources + + build.properties + p2.inf + + + + + + + + + org.wso2.maven + carbon-p2-plugin + + + p2-feature-generation + package + + p2-feature-gen + + + org.wso2.carbon.device.mgt.v09.api + ../../../features/etc/feature.properties + + + + org.wso2.carbon.p2.category.type:server + + org.eclipse.equinox.p2.type.group:false + + + + + + + + + + diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.v09.api.feature/src/main/resources/build.properties b/features/device-mgt/org.wso2.carbon.device.mgt.v09.api.feature/src/main/resources/build.properties new file mode 100644 index 0000000000..9c86577d76 --- /dev/null +++ b/features/device-mgt/org.wso2.carbon.device.mgt.v09.api.feature/src/main/resources/build.properties @@ -0,0 +1 @@ +custom = true diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.v09.api.feature/src/main/resources/p2.inf b/features/device-mgt/org.wso2.carbon.device.mgt.v09.api.feature/src/main/resources/p2.inf new file mode 100644 index 0000000000..ada11f0367 --- /dev/null +++ b/features/device-mgt/org.wso2.carbon.device.mgt.v09.api.feature/src/main/resources/p2.inf @@ -0,0 +1,3 @@ +instructions.configure = \ +org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/server/webapps/);\ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.v09.api_${feature.version}/webapps/api#device-mgt#v0.9.war,target:${installFolder}/../../deployment/server/webapps/api#device-mgt#v0.9.war,overwrite:true);\ \ No newline at end of file diff --git a/features/device-mgt/pom.xml b/features/device-mgt/pom.xml index 951a74fe3a..8bb7d840d8 100644 --- a/features/device-mgt/pom.xml +++ b/features/device-mgt/pom.xml @@ -37,6 +37,7 @@ org.wso2.carbon.device.mgt.server.feature org.wso2.carbon.device.mgt.ui.feature org.wso2.carbon.device.mgt.api.feature + org.wso2.carbon.device.mgt.v09.api.feature org.wso2.carbon.device.mgt.feature org.wso2.carbon.device.mgt.extensions.feature org.wso2.carbon.device.mgt.analytics.data.publisher.feature diff --git a/pom.xml b/pom.xml index 6cc01db112..47d5627da1 100644 --- a/pom.xml +++ b/pom.xml @@ -253,6 +253,12 @@ zip ${carbon.device.mgt.version} + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.v09.api.feature + zip + ${carbon.device.mgt.version} + org.wso2.carbon.devicemgt org.wso2.carbon.device.mgt.ui.feature