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 extends Operation>) 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 extends Operation>) 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 extends Operation> operations;
+
+ @ApiModelProperty(value = "List of operations returned")
+ @JsonProperty("operations")
+ public List extends Operation> getList() {
+ return operations;
+ }
+
+ public void setList(List extends Operation> 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 extends Operation> 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 extends Operation> 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 extends Operation>) 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