Merge branch 'application-mgt-new' into 'application-mgt-new'

Improve review management

See merge request entgra/carbon-device-mgt!135
feature/appm-store/pbac
Dharmakeerthi Lasantha 5 years ago
commit 061317c438

1
.gitignore vendored

@ -8,6 +8,7 @@ target
*.ipr
.idea
*.ids
.editorconfig
# Mac crap
.DS_Store

@ -22,13 +22,13 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.apimgt.annotations</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>WSO2 Carbon - API Management Annotations</name>
<description>WSO2 Carbon - API Management Custom Annotation Module</description>

@ -21,12 +21,12 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<artifactId>org.wso2.carbon.apimgt.application.extension.api</artifactId>
<packaging>war</packaging>
<name>WSO2 Carbon - API Application Management API</name>

@ -22,12 +22,12 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<artifactId>org.wso2.carbon.apimgt.application.extension</artifactId>
<packaging>bundle</packaging>
<name>WSO2 Carbon - API Application Management</name>

@ -21,13 +21,13 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.apimgt.handlers</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>WSO2 Carbon - API Security Handler Component</name>
<description>WSO2 Carbon - API Management Security Handler Module</description>

@ -13,13 +13,13 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.apimgt.integration.client</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>WSO2 Carbon - API Management Integration Client</name>
<description>WSO2 Carbon - API Management Integration Client</description>

@ -13,13 +13,13 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.apimgt.integration.generated.client</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>WSO2 Carbon - API Management Integration Generated Client</name>
<description>WSO2 Carbon - API Management Integration Client</description>

@ -22,13 +22,13 @@
<parent>
<artifactId>apimgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.apimgt.webapp.publisher</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>WSO2 Carbon - API Management Webapp Publisher</name>
<description>WSO2 Carbon - API Management Webapp Publisher</description>

@ -22,13 +22,13 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>carbon-devicemgt</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>apimgt-extensions</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<packaging>pom</packaging>
<name>WSO2 Carbon - API Management Extensions Component</name>
<url>http://wso2.org</url>

@ -5,12 +5,12 @@
<parent>
<artifactId>application-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.application.mgt.addons</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<name>WSO2 Carbon - Application Management Add-Ons</name>
<description>WSO2 Carbon - Application Management Add-Ons</description>
<url>http://wso2.org</url>

@ -22,13 +22,13 @@
<parent>
<artifactId>application-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.application.mgt.api</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<packaging>war</packaging>
<name>WSO2 Carbon - Application Management API</name>
<description>WSO2 Carbon - Application Management API</description>

@ -21,13 +21,13 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>application-mgt</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.application.mgt.common</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>WSO2 Carbon - Application Management Common</name>
<description>WSO2 Carbon - Application Management Common</description>

@ -28,6 +28,8 @@ public class ReviewDTO {
private int rating;
private int rootParentId;
private int immediateParentId;
private String releaseUuid;
private String releaseVersion;
public int getId() {
return id;
@ -84,4 +86,12 @@ public class ReviewDTO {
public int getImmediateParentId() { return immediateParentId; }
public void setImmediateParentId(int immediateParentId) { this.immediateParentId = immediateParentId; }
public String getReleaseUuid() { return releaseUuid; }
public void setReleaseUuid(String releaseUuid) { this.releaseUuid = releaseUuid; }
public String getReleaseVersion() { return releaseVersion; }
public void setReleaseVersion(String releaseVersion) { this.releaseVersion = releaseVersion; }
}

@ -192,7 +192,7 @@ public interface ApplicationManager {
* @param applicationReleaseWrapper ApplicatonRelease that need to be be created.
* @return the unique id of the application release, if the application release succeeded else -1
*/
ApplicationRelease createRelease(int applicationId, ApplicationReleaseWrapper applicationReleaseWrapper,
ApplicationRelease createEntAppRelease(int applicationId, ApplicationReleaseWrapper applicationReleaseWrapper,
ApplicationArtifact applicationArtifact) throws ApplicationManagementException;
/***

@ -39,7 +39,7 @@ public interface ReviewManager {
* @return {@link Review} Added review
* @throws ReviewManagementException Exceptions of the reviewTmp management.
*/
boolean addReview(ReviewWrapper reviewWrapper, String uuid)
boolean addReview(ReviewWrapper reviewWrapper, String uuid, boolean allowMultipleReviews)
throws ReviewManagementException, ApplicationManagementException;
boolean addReplyComment(ReviewWrapper reviewWrapper, String uuid, int parentReviewId)
@ -53,14 +53,19 @@ public interface ReviewManager {
* @return {@link PaginationResult} pagination result with starting offSet and limit
* @throws ReviewManagementException Exceptions of the comment management.
*/
PaginationResult getAllReviews(PaginationRequest request, String uuid)
PaginationResult getAllReleaseReviews(PaginationRequest request, String uuid)
throws ReviewManagementException, ApplicationManagementException;
PaginationResult getAllAppReviews(PaginationRequest request, String uuid) throws ReviewManagementException,
ApplicationManagementException;
PaginationResult getAllAppReviewsOfUser(PaginationRequest request, String uuid) throws ReviewManagementException,
ApplicationManagementException;
/**
* To delete review using review id.
*
* @param uuid UUID of the application release
* @return If review is successfully deleted return true, otherwise returns false
* @throws ReviewManagementException Exceptions of the comment management
*/
void deleteReview(String uuid, int reviewId, boolean isPriviledgedUser)
@ -70,19 +75,21 @@ public interface ReviewManager {
* To update a reviewTmp.
*
* @param reviewId id of the reviewTmp
* @param uuid UUID of the application release
* @return {@link Review}updated review
* @throws ReviewManagementException Exceptions of the reviewTmp management
*/
boolean updateReview(ReviewWrapper updatingReview, int reviewId, String uuid, boolean isPriviledgedUser)
boolean updateReview(ReviewWrapper updatingReview, int reviewId, String uuid, boolean isPrivilegedUser)
throws ReviewManagementException, ApplicationManagementException;
/**
* To get the overall rating for a application release
*
* @param appReleaseUuuid UUID of the application release.
* @param appReleaseUuid UUID of the application release.
* @return {@link Review}updated review
* @throws ReviewManagementException Exceptions of the review management
*/
Rating getRating(String appReleaseUuuid) throws ReviewManagementException, ApplicationManagementException;
Rating getAppReleaseRating(String appReleaseUuid) throws ReviewManagementException, ApplicationManagementException;
Rating getAppRating(String appReleaseUuid) throws ReviewManagementException, ApplicationManagementException;
}

@ -21,13 +21,13 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>application-mgt</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.application.mgt.core</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>WSO2 Carbon - Application Management Core</name>
<description>WSO2 Carbon - Application Management Core</description>

@ -48,13 +48,13 @@ import java.util.List;
/**
* To verify whether user has already commented for the application release or not.
*
* @param appReleaseId ID of the application release.
* @param appReleaseIds List of the application release IDs.
* @param username username of the logged in user.
* @param tenantId tenantId of the commented application.
* @return If review exists, review returns
* @throws ReviewManagementDAOException Exceptions of the review management DAO.
*/
boolean haveUerReviewed(int appReleaseId, String username, int tenantId) throws ReviewManagementDAOException;
boolean hasUerReviewedApp(List<Integer> appReleaseIds, String username, int tenantId) throws ReviewManagementDAOException;
/**
* To update already added comment.
@ -65,7 +65,8 @@ import java.util.List;
* @return row count if updating is succeed otherwise 0
* @throws ReviewManagementDAOException Exceptions of the reviewTmp management.
*/
int updateReview(ReviewDTO reviewDTO, int reviewId, int tenantId) throws ReviewManagementDAOException;
int updateReview(ReviewDTO reviewDTO, int reviewId, boolean isActiveReview, int tenantId)
throws ReviewManagementDAOException;
/**
@ -89,9 +90,15 @@ import java.util.List;
* @return {@link List}List of all reviews for the application release
* @throws ReviewManagementDAOException Review management DAO exception
**/
List<ReviewDTO> getAllReviews(int releaseId, PaginationRequest request, int tenantId)
List<ReviewDTO> getAllActiveReleaseReviews(int releaseId, PaginationRequest request, int tenantId)
throws ReviewManagementDAOException;
List<ReviewDTO> getAllActiveAppReviews(List<Integer> releaseIds, PaginationRequest request, int tenantId)
throws ReviewManagementDAOException;
List<ReviewDTO> getAllActiveAppReviewsOfUser(List<Integer> releaseIds, PaginationRequest request, String username,
int tenantId) throws ReviewManagementDAOException;
List<ReviewDTO> getReplyComments(int parentId, int tenantId)
throws ReviewManagementDAOException;
@ -102,7 +109,10 @@ import java.util.List;
* @return {@link List}List of comments
* @throws ReviewManagementDAOException Exceptions of the review management DAO.
*/
List<Integer> getAllRatingValues(String uuid, int tenantId) throws ReviewManagementDAOException;
List<Integer> getAllAppReleaseRatingValues(String uuid, int tenantId) throws ReviewManagementDAOException;
List<Integer> getAllAppRatingValues(List<String> uuids, int tenantId) throws ReviewManagementDAOException;
/**
* To get count of comments by application details.
@ -121,7 +131,6 @@ import java.util.List;
/**
* To delete review using review id and uuid of the application release.
*
* @param username username of the review owner
* @param reviewId id of the review
* @return If review is successfully deleted return 1, otherwise returns 0.
* @throws ReviewManagementDAOException Review management DAO exception.

@ -40,6 +40,7 @@ import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.StringJoiner;
/**
* This handles ReviewDAO related operations.
@ -98,28 +99,29 @@ public class ReviewDAOImpl extends AbstractDAOImpl implements ReviewDAO {
}
@Override
public boolean haveUerReviewed(int appReleaseId, String username, int tenantId) throws ReviewManagementDAOException {
public boolean hasUerReviewedApp(List<Integer> appReleaseIds, String username, int tenantId)
throws ReviewManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to check whether user have already reviewed or not for the "
+ "application release. Commenting user: " + username + " and tenant-id: " + tenantId);
+ "application. Commenting user: " + username + " and tenant-id: " + tenantId);
}
Connection conn;
sql = "SELECT "
+ "rv.ID "
+ "FROM AP_APP_REVIEW rv "
+ "WHERE "
+ "rv.AP_APP_RELEASE_ID = ? AND "
+ "rv.USERNAME = ? AND "
+ "rv.TENANT_ID = ?";
int index = 1;
try {
conn = this.getDBConnection();
try (PreparedStatement statement = conn.prepareStatement(sql)) {
statement.setInt(1, appReleaseId);
statement.setString(2, username);
statement.setInt(3, tenantId);
try (ResultSet rs = statement.executeQuery()) {
StringJoiner joiner = new StringJoiner(",",
"SELECT rv.ID FROM AP_APP_REVIEW " + "WHERE rv.AP_APP_RELEASE_ID IN (",
") AND rv.USERNAME = ? AND rv.TENANT_ID = ?");
appReleaseIds.stream().map(ignored -> "?").forEach(joiner::add);
String query = joiner.toString();
try (PreparedStatement ps = conn.prepareStatement(query)) {
for (Integer deviceId : appReleaseIds) {
ps.setObject(index++, deviceId);
}
ps.setInt(index++, tenantId);
ps.setInt(index, tenantId);
try (ResultSet rs = ps.executeQuery()) {
return rs.next();
}
}
} catch (SQLException e) {
@ -132,7 +134,7 @@ public class ReviewDAOImpl extends AbstractDAOImpl implements ReviewDAO {
}
@Override
public int updateReview(ReviewDTO reviewDTO, int reviewId, int tenantId)
public int updateReview(ReviewDTO reviewDTO, int reviewId, boolean isActiveReview, int tenantId)
throws ReviewManagementDAOException {
if (log.isDebugEnabled()) {
@ -146,7 +148,8 @@ public class ReviewDAOImpl extends AbstractDAOImpl implements ReviewDAO {
+ "SET "
+ "COMMENT = ?, "
+ "RATING = ?, "
+ "MODIFIED_AT = ? "
+ "MODIFIED_AT = ?, "
+ "ACTIVE_REVIEW = ? "
+ "WHERE ID = ? AND "
+ "TENANT_ID = ?";
try {
@ -158,8 +161,9 @@ public class ReviewDAOImpl extends AbstractDAOImpl implements ReviewDAO {
statement.setString(1, reviewDTO.getContent());
statement.setInt(2, reviewDTO.getRating());
statement.setTimestamp(3, timestamp);
statement.setInt(4, reviewId);
statement.setInt(5, tenantId);
statement.setBoolean(4, isActiveReview);
statement.setInt(5, reviewId);
statement.setInt(6, tenantId);
return statement.executeUpdate();
} catch (SQLException e) {
throw new ReviewManagementDAOException("Error occurred while executing reviewTmp updating query");
@ -182,16 +186,19 @@ public class ReviewDAOImpl extends AbstractDAOImpl implements ReviewDAO {
try {
conn = this.getDBConnection();
sql = "SELECT "
+ "ID, "
+ "COMMENT,"
+ "ROOT_PARENT_ID,"
+ "IMMEDIATE_PARENT_ID, "
+ "CREATED_AT, "
+ "MODIFIED_AT, "
+ "RATING, "
+ "USERNAME "
+ "FROM AP_APP_REVIEW "
+ "WHERE ID = ?";
+ "AP_APP_REVIEW.ID AS ID, "
+ "AP_APP_REVIEW.COMMENT AS COMMENT, "
+ "AP_APP_REVIEW.ROOT_PARENT_ID AS ROOT_PARENT_ID, "
+ "AP_APP_REVIEW.IMMEDIATE_PARENT_ID AS IMMEDIATE_PARENT_ID, "
+ "AP_APP_REVIEW.CREATED_AT AS CREATED_AT, "
+ "AP_APP_REVIEW.MODIFIED_AT AS MODIFIED_AT, "
+ "AP_APP_REVIEW.RATING AS RATING, "
+ "AP_APP_REVIEW.USERNAME AS USERNAME, "
+ "AP_APP_RELEASE.UUID AS UUID, "
+ "AP_APP_RELEASE.VERSION AS VERSION "
+ "FROM AP_APP_REVIEW INNER JOIN AP_APP_RELEASE ON "
+ "AP_APP_REVIEW.AP_APP_RELEASE_ID = AP_APP_RELEASE.ID "
+ "WHERE AP_APP_REVIEW.ID = ?";
statement = conn.prepareStatement(sql);
statement.setInt(1, reviewId);
rs = statement.executeQuery();
@ -251,14 +258,14 @@ public class ReviewDAOImpl extends AbstractDAOImpl implements ReviewDAO {
@Override
public List<ReviewDTO> getAllReviews(int releaseId, PaginationRequest request, int tenantId)
public List<ReviewDTO> getAllActiveReleaseReviews(int releaseId, PaginationRequest request, int tenantId)
throws ReviewManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Getting comment of the application release (" + releaseId + ") from the database");
}
Connection conn;
List<ReviewDTO> reviewDTOs = new ArrayList<>();
List<ReviewDTO> reviewDTOs;
try {
conn = this.getDBConnection();
sql = "SELECT "
@ -270,10 +277,13 @@ public class ReviewDAOImpl extends AbstractDAOImpl implements ReviewDAO {
+ "AP_APP_REVIEW.ROOT_PARENT_ID AS ROOT_PARENT_ID, "
+ "AP_APP_REVIEW.IMMEDIATE_PARENT_ID AS IMMEDIATE_PARENT_ID, "
+ "AP_APP_REVIEW.RATING AS RATING "
+ "FROM AP_APP_REVIEW "
+ "WHERE "
+ "AP_APP_REVIEW.AP_APP_RELEASE_ID = ? AND "
+ "AP_APP_RELEASE.UUID AS UUID, "
+ "AP_APP_RELEASE.VERSION AS VERSION "
+ "FROM AP_APP_REVIEW INNER JOIN AP_APP_RELEASE ON "
+ "AP_APP_REVIEW.AP_APP_RELEASE_ID = AP_APP_RELEASE.ID "
+ "WHERE AP_APP_REVIEW.AP_APP_RELEASE_ID = ? AND "
+ "AP_APP_REVIEW.ROOT_PARENT_ID = ? AND "
+ "AP_APP_REVIEW.ACTIVE_REVIEW = true "
+ "AP_APP_REVIEW.TENANT_ID = ? "
+ "LIMIT ? OFFSET ?";
try (PreparedStatement statement = conn.prepareStatement(sql)) {
@ -294,6 +304,120 @@ public class ReviewDAOImpl extends AbstractDAOImpl implements ReviewDAO {
} return reviewDTOs;
}
@Override
public List<ReviewDTO> getAllActiveAppReviews(List<Integer> releaseIds, PaginationRequest request, int tenantId)
throws ReviewManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Getting reviews of the application from the database.");
}
Connection conn;
List<ReviewDTO> reviewDTOs;
int index = 1;
try {
conn = this.getDBConnection();
StringJoiner joiner = new StringJoiner(",",
"SELECT "
+ "AP_APP_REVIEW.ID AS ID, "
+ "AP_APP_REVIEW.COMMENT AS COMMENT, "
+ "AP_APP_REVIEW.CREATED_AT AS CREATED_AT, "
+ "AP_APP_REVIEW.MODIFIED_AT AS MODIFIED_AT, "
+ "AP_APP_REVIEW.USERNAME AS USERNAME, "
+ "AP_APP_REVIEW.ROOT_PARENT_ID AS ROOT_PARENT_ID, "
+ "AP_APP_REVIEW.IMMEDIATE_PARENT_ID AS IMMEDIATE_PARENT_ID, "
+ "AP_APP_REVIEW.RATING AS RATING, "
+ "AP_APP_RELEASE.UUID AS UUID, "
+ "AP_APP_RELEASE.VERSION AS VERSION "
+ "FROM AP_APP_REVIEW INNER JOIN AP_APP_RELEASE ON "
+ "AP_APP_REVIEW.AP_APP_RELEASE_ID = AP_APP_RELEASE.ID "
+ "WHERE AP_APP_REVIEW.AP_APP_RELEASE_ID (",
") AND AP_APP_REVIEW.ROOT_PARENT_ID = ? AND "
+ "AP_APP_REVIEW.ACTIVE_REVIEW = true AND "
+ "AP_APP_REVIEW.TENANT_ID = ? "
+ "LIMIT ? OFFSET ?");
releaseIds.stream().map(ignored -> "?").forEach(joiner::add);
String query = joiner.toString();
try (PreparedStatement ps = conn.prepareStatement(query)) {
for (Integer releaseId : releaseIds) {
ps.setObject(index++, releaseId);
}
ps.setInt(index++, Constants.REVIEW_PARENT_ID);
ps.setInt(index++, tenantId);
ps.setInt(index++, request.getLimit());
ps.setInt(index, request.getOffSet());
try (ResultSet rs = ps.executeQuery()) {
reviewDTOs = DAOUtil.loadReviews(rs);
}
}
}
catch (DBConnectionException e) {
throw new ReviewManagementDAOException(
"Error occurred while obtaining the DB connection when verifying application existence.", e);
} catch (SQLException e) {
throw new ReviewManagementDAOException("DB connection error occurred while getting all reviews.", e);
} return reviewDTOs;
}
@Override
public List<ReviewDTO> getAllActiveAppReviewsOfUser(List<Integer> releaseIds, PaginationRequest request,
String username, int tenantId)
throws ReviewManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Getting reviews of the application for given user from the database.");
}
Connection conn;
List<ReviewDTO> reviewDTOs;
int index = 1;
try {
conn = this.getDBConnection();
StringJoiner joiner = new StringJoiner(",",
"SELECT "
+ "AP_APP_REVIEW.ID AS ID, "
+ "AP_APP_REVIEW.COMMENT AS COMMENT, "
+ "AP_APP_REVIEW.CREATED_AT AS CREATED_AT, "
+ "AP_APP_REVIEW.MODIFIED_AT AS MODIFIED_AT, "
+ "AP_APP_REVIEW.USERNAME AS USERNAME, "
+ "AP_APP_REVIEW.ROOT_PARENT_ID AS ROOT_PARENT_ID, "
+ "AP_APP_REVIEW.IMMEDIATE_PARENT_ID AS IMMEDIATE_PARENT_ID, "
+ "AP_APP_REVIEW.RATING AS RATING, "
+ "AP_APP_RELEASE.UUID AS UUID, "
+ "AP_APP_RELEASE.VERSION AS VERSION "
+ "FROM AP_APP_REVIEW INNER JOIN AP_APP_RELEASE ON "
+ "AP_APP_REVIEW.AP_APP_RELEASE_ID = AP_APP_RELEASE.ID "
+ "WHERE AP_APP_REVIEW.AP_APP_RELEASE_ID (",
") AND AP_APP_REVIEW.ROOT_PARENT_ID = ? AND "
+ "AP_APP_REVIEW.ACTIVE_REVIEW = true AND "
+ "AP_APP_REVIEW.USERNAME = ? AND "
+ "AP_APP_REVIEW.TENANT_ID = ? "
+ "LIMIT ? OFFSET ?");
releaseIds.stream().map(ignored -> "?").forEach(joiner::add);
String query = joiner.toString();
try (PreparedStatement ps = conn.prepareStatement(query)) {
for (Integer releaseId : releaseIds) {
ps.setObject(index++, releaseId);
}
ps.setInt(index++, Constants.REVIEW_PARENT_ID);
ps.setString(index++, username);
ps.setInt(index++, tenantId);
ps.setInt(index++, request.getLimit());
ps.setInt(index, request.getOffSet());
try (ResultSet rs = ps.executeQuery()) {
reviewDTOs = DAOUtil.loadReviews(rs);
}
}
}
catch (DBConnectionException e) {
throw new ReviewManagementDAOException(
"Error occurred while obtaining the DB connection when application review of user: " + username , e);
} catch (SQLException e) {
throw new ReviewManagementDAOException("DB connection error occurred while getting application reviews of "
+ "user:" + username, e);
} return reviewDTOs;
}
@Override
public List<ReviewDTO> getReplyComments(int parentId, int tenantId) throws ReviewManagementDAOException {
@ -312,8 +436,11 @@ public class ReviewDAOImpl extends AbstractDAOImpl implements ReviewDAO {
+ "AP_APP_REVIEW.USERNAME AS USERNAME, "
+ "AP_APP_REVIEW.ROOT_PARENT_ID AS ROOT_PARENT_ID, "
+ "AP_APP_REVIEW.IMMEDIATE_PARENT_ID AS IMMEDIATE_PARENT_ID, "
+ "AP_APP_REVIEW.RATING AS RATING "
+ "FROM AP_APP_REVIEW "
+ "AP_APP_REVIEW.RATING AS RATING, "
+ "AP_APP_RELEASE.UUID AS UUID, "
+ "AP_APP_RELEASE.VERSION AS VERSION "
+ "FROM AP_APP_REVIEW INNER JOIN AP_APP_RELEASE ON "
+ "AP_APP_REVIEW.AP_APP_RELEASE_ID = AP_APP_RELEASE.ID "
+ "WHERE "
+ "AP_APP_REVIEW.ROOT_PARENT_ID = ? AND "
+ "AP_APP_REVIEW.TENANT_ID = ?";
@ -334,7 +461,7 @@ public class ReviewDAOImpl extends AbstractDAOImpl implements ReviewDAO {
}
@Override
public List<Integer> getAllRatingValues(String uuid, int tenantId) throws ReviewManagementDAOException {
public List<Integer> getAllAppReleaseRatingValues(String uuid, int tenantId) throws ReviewManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Getting comment of the application release (" + uuid + ") from the database");
@ -347,7 +474,7 @@ public class ReviewDAOImpl extends AbstractDAOImpl implements ReviewDAO {
conn = this.getDBConnection();
sql = "SELECT AP_APP_REVIEW.RATING AS RATING FROM AP_APP_REVIEW, AP_APP_RELEASE WHERE "
+ "AP_APP_REVIEW.AP_APP_RELEASE_ID=AP_APP_RELEASE.ID AND AP_APP_RELEASE.UUID =? AND "
+ "AP_APP_REVIEW.TENANT_ID = AP_APP_RELEASE.TENANT_ID AND AP_APP_REVIEW.TENANT_ID = ?;";
+ "AP_APP_REVIEW.TENANT_ID = AP_APP_RELEASE.TENANT_ID AND AP_APP_REVIEW.TENANT_ID = ?";
statement = conn.prepareStatement(sql);
statement.setString(1, uuid);
statement.setInt(2, tenantId);
@ -369,6 +496,44 @@ public class ReviewDAOImpl extends AbstractDAOImpl implements ReviewDAO {
return reviews;
}
@Override
public List<Integer> getAllAppRatingValues(List<String> uuids, int tenantId) throws ReviewManagementDAOException {
if (log.isDebugEnabled()) {
log.debug("Getting rating values of the application from the database");
}
Connection conn;
List<Integer> reviews = new ArrayList<>();
try {
int index = 1;
conn = this.getDBConnection();
StringJoiner joiner = new StringJoiner(",",
"SELECT AP_APP_REVIEW.RATING AS RATING FROM AP_APP_REVIEW INNER JOIN AP_APP_RELEASE ON "
+ "AP_APP_REVIEW.AP_APP_RELEASE_ID = AP_APP_RELEASE.ID WHERE AP_APP_RELEASE.UUID IN (",
") AND AP_APP_REVIEW.ACTIVE_REVIEW = true AND AP_APP_REVIEW.TENANT_ID = ?");
uuids.stream().map(ignored -> "?").forEach(joiner::add);
String query = joiner.toString();
try (PreparedStatement ps = conn.prepareStatement(query)) {
for (String uuid : uuids) {
ps.setObject(index++, uuid);
}
ps.setInt(index++, tenantId);
ps.setInt(index, tenantId);
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
reviews.add(rs.getInt("RATING"));
} }
}
} catch (SQLException e) {
throw new ReviewManagementDAOException(
"Error occured while getting all rating values for the application.", e);
} catch (DBConnectionException e) {
throw new ReviewManagementDAOException(
"Error occured while getting DB connection to retrieve all rating values for the application.", e);
}
return reviews;
}
@Override
public int getReviewCount(String uuid) throws ReviewManagementDAOException {

@ -144,7 +144,7 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
+ "OPERATION_ID, "
+ "AP_DEVICE_SUBSCRIPTION_ID, "
+ "TENANT_ID) "
+ "VALUES (?, ?, ?, ?, ?)";
+ "VALUES (?, ?, ?)";
conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
for (Integer subId : deviceSubscriptionIds) {

@ -740,16 +740,24 @@ public class ApplicationManagerImpl implements ApplicationManager {
}
@Override
public ApplicationRelease createRelease(int applicationId, ApplicationReleaseWrapper applicationReleaseWrapper,
public ApplicationRelease createEntAppRelease(int applicationId, ApplicationReleaseWrapper applicationReleaseWrapper,
ApplicationArtifact applicationArtifact) throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
ApplicationRelease applicationRelease;
if (log.isDebugEnabled()) {
log.debug("ApplicationDTO release request is received for the application id: " + applicationId);
log.debug("Application release creating request is received for the application id: " + applicationId);
}
ApplicationDTO applicationDTO = getApplication(applicationId);
try {
if (!ApplicationType.ENTERPRISE.toString().equals(applicationDTO.getType())) {
String msg =
"It is possible to add new application release for " + ApplicationType.ENTERPRISE.toString()
+ " app type. But you are requesting to add new application release for "
+ applicationDTO.getType() + " app type.";
log.error(msg);
throw new BadRequestException(msg);
}
ApplicationReleaseDTO applicationReleaseDTO = uploadReleaseArtifacts(applicationReleaseWrapper,
applicationDTO, applicationArtifact);
ConnectionManagerUtil.beginDBTransaction();
@ -1916,6 +1924,14 @@ public class ApplicationManagerImpl implements ApplicationManager {
}
try {
ConnectionManagerUtil.beginDBTransaction();
if (applicationDAO.getTagForTagName(newTagName, tenantId) != null){
String msg =
"You are trying to modify tag name into existing tag. Therefore you can't modify tag name from "
+ oldTagName + " to new tag name " + newTagName;
log.error(msg);
throw new BadRequestException(msg);
}
TagDTO tag = applicationDAO.getTagForTagName(oldTagName, tenantId);
if (tag == null){
String msg = "Couldn't found a tag for tag name " + oldTagName + ".";
@ -2121,7 +2137,7 @@ public class ApplicationManagerImpl implements ApplicationManager {
if (!StringUtils.isEmpty(appType)) {
boolean isValidAppType = false;
for (ApplicationType applicationType : ApplicationType.values()) {
if (applicationType.toString().equals(appType)) {
if (applicationType.toString().equalsIgnoreCase(appType)) {
isValidAppType = true;
break;
}
@ -2489,8 +2505,7 @@ public class ApplicationManagerImpl implements ApplicationManager {
log.error(msg);
throw new BadRequestException(msg);
}
}
if (param instanceof WebAppReleaseWrapper) {
} else if (param instanceof WebAppReleaseWrapper) {
WebAppReleaseWrapper webAppReleaseWrapper = (WebAppReleaseWrapper) param;
UrlValidator urlValidator = new UrlValidator();
if (StringUtils.isEmpty(webAppReleaseWrapper.getVersion())) {

@ -24,6 +24,7 @@ import org.wso2.carbon.device.application.mgt.common.Rating;
import org.wso2.carbon.device.application.mgt.common.ReviewNode;
import org.wso2.carbon.device.application.mgt.common.PaginationRequest;
import org.wso2.carbon.device.application.mgt.common.PaginationResult;
import org.wso2.carbon.device.application.mgt.common.dto.ApplicationDTO;
import org.wso2.carbon.device.application.mgt.common.dto.ApplicationReleaseDTO;
import org.wso2.carbon.device.application.mgt.common.dto.ReviewDTO;
import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException;
@ -49,6 +50,7 @@ import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeMap;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
@ -72,7 +74,7 @@ public class ReviewManagerImpl implements ReviewManager {
}
@Override
public boolean addReview(ReviewWrapper reviewWrapper, String uuid)
public boolean addReview(ReviewWrapper reviewWrapper, String uuid,boolean allowMultipleReviews)
throws ReviewManagementException, ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
@ -82,37 +84,47 @@ public class ReviewManagerImpl implements ReviewManager {
log.error(msg);
throw new BadRequestException(msg);
}
if (reviewWrapper.getRating() < 0) {
if (reviewWrapper.getRating() <= 0) {
String msg = "You are trying to add invalid rating value as rating. Therefore please verify the request "
+ "payload.";
log.error(msg);
throw new ForbiddenException(msg);
throw new BadRequestException(msg);
}
try {
ConnectionManagerUtil.beginDBTransaction();
ApplicationReleaseDTO applicationReleaseDTO = this.applicationReleaseDAO.getReleaseByUUID(uuid, tenantId);
if (applicationReleaseDTO == null) {
String msg = "Couldn't find application release for the application UUID: " + uuid;
ApplicationDTO applicationDTO = this.applicationDAO.getApplicationByUUID(uuid, tenantId);
if (applicationDTO == null) {
String msg = "Couldn't find an application which has the application release of UUID: " + uuid;
log.error(msg);
throw new NotFoundException(msg);
}
if (this.reviewDAO.haveUerReviewed(applicationReleaseDTO.getId(), username, tenantId)) {
List<Integer> applicationReleaseIds = new ArrayList<>();
int associatedAppReleaseId = -1;
for (ApplicationReleaseDTO applicationReleaseDTO : applicationDTO.getApplicationReleaseDTOs()) {
if (applicationReleaseDTO.getUuid().equals(uuid)){
associatedAppReleaseId = applicationReleaseDTO.getId();
}
Integer id = applicationReleaseDTO.getId();
applicationReleaseIds.add(id);
}
if (!allowMultipleReviews && this.reviewDAO.hasUerReviewedApp(applicationReleaseIds, username, tenantId)) {
String msg =
"User " + username + " has already reviewed the application release which has UUID: " + uuid
+ ". Hence you can't add another review for same application release. But you can update "
+ "the review that you have already added for ths application release.";
"User " + username + " has already reviewed the application of app release which has UUID: "
+ uuid + ". Hence you can't add another review for same application. But if you have "
+ "added review for same app release you can update the review that you have already "
+ "added for ths application.";
log.error(msg);
throw new ForbiddenException(msg);
}
Runnable task = () -> calculateRating(reviewWrapper.getRating(), -12345, uuid, tenantId);
new Thread(task).start();
ReviewDTO reviewDTO = reviewWrapperToDO(reviewWrapper);
ReviewDTO reviewDTO = reviewWrapperToDTO(reviewWrapper);
reviewDTO.setUsername(username);
reviewDTO.setRootParentId(-1);
reviewDTO.setImmediateParentId(-1);
if (this.reviewDAO.addReview(reviewDTO, applicationReleaseDTO.getId(), tenantId)) {
if (this.reviewDAO.addReview(reviewDTO, associatedAppReleaseId, tenantId)) {
ConnectionManagerUtil.commitDBTransaction();
Runnable task = () -> calculateRating(reviewWrapper.getRating(), -12345, uuid, tenantId);
new Thread(task).start();
return true;
}
ConnectionManagerUtil.rollbackDBTransaction();
@ -153,45 +165,52 @@ public class ReviewManagerImpl implements ReviewManager {
log.error(msg);
throw new BadRequestException(msg);
}
ReviewDTO parentReview = getReview(parentReviewId);
if (parentReview == null) {
String msg = "Couldn't find an review which has review ID: " + parentReviewId
+ " for application release which has UUID: " + uuid;
log.error(msg);
throw new NotFoundException(msg);
}
if (!parentReview.getReleaseUuid().equals(uuid)) {
String msg =
"Bad Request. You are trying to add reply comment for application release which has UUID: " + uuid
+ "," + " but parent review is associated with application release which has UUID: "
+ parentReview.getReleaseUuid() + ". Hence can't proceed this request further.";
log.error(msg);
throw new BadRequestException(msg);
}
ReviewDTO replyComment = reviewWrapperToDTO(reviewWrapper);
replyComment.setUsername(username);
replyComment.setRating(0);
replyComment.setImmediateParentId(parentReview.getId());
if (parentReview.getRootParentId() == -1) {
replyComment.setRootParentId(parentReview.getId());
} else {
replyComment.setRootParentId(parentReview.getRootParentId());
}
try {
ConnectionManagerUtil.beginDBTransaction();
ApplicationReleaseDTO applicationReleaseDTO = this.applicationReleaseDAO.getReleaseByUUID(uuid, tenantId);
if (applicationReleaseDTO == null) {
String msg = "Couldn't find application release for the application UUID: " + uuid;
log.error(msg);
throw new NotFoundException(msg);
}
ReviewDTO parentReview = this.reviewDAO.getReview(applicationReleaseDTO.getId(), parentReviewId);
if (parentReview == null) {
String msg = "Couldn't find an review which has review ID: " + parentReviewId
+ " for application release which has UUID: " + uuid;
log.error(msg);
throw new NotFoundException(msg);
}
ReviewDTO replyComment = reviewWrapperToDO(reviewWrapper);
replyComment.setUsername(username);
replyComment.setRating(0);
replyComment.setImmediateParentId(parentReview.getId());
if (parentReview.getRootParentId() == -1) {
replyComment.setRootParentId(parentReview.getId());
} else {
replyComment.setRootParentId(parentReview.getRootParentId());
}
if (this.reviewDAO.addReview(replyComment, applicationReleaseDTO.getId(), tenantId)) {
ConnectionManagerUtil.commitDBTransaction();
return true;
}
ConnectionManagerUtil.rollbackDBTransaction();
return false;
} catch (DBConnectionException e) {
throw new ReviewManagementException(
"DB Connection error occurs ,Review for application release with UUID: " + uuid + " is failed",
e);
"DB Connection error occurs ,Review for application release with UUID: " + uuid + " is failed", e);
} catch (TransactionManagementException e) {
String msg = "DB transaction error occurred when adding reply comment for comment which has comment id: "
+ parentReviewId;
log.error(msg);
throw new ReviewManagementException(msg, e);
} catch (ApplicationManagementDAOException e) {
ConnectionManagerUtil.rollbackDBTransaction();
throw new ReviewManagementException(
"Error occured while verifying whether application release is exists or not.", e);
} finally {
@ -199,7 +218,7 @@ public class ReviewManagerImpl implements ReviewManager {
}
}
private ReviewDTO reviewWrapperToDO(ReviewWrapper reviewWrapper){
private ReviewDTO reviewWrapperToDTO(ReviewWrapper reviewWrapper){
ReviewDTO reviewDTO = new ReviewDTO();
reviewDTO.setContent(reviewWrapper.getContent());
reviewDTO.setRating(reviewWrapper.getRating());
@ -229,50 +248,77 @@ public class ReviewManagerImpl implements ReviewManager {
return review;
}
private ReviewDTO getReview(int reviewId) throws ReviewManagementException {
try {
ConnectionManagerUtil.openDBConnection();
return this.reviewDAO.getReview(reviewId);
} catch (DBConnectionException e) {
String msg = "DB Connection error occurs updating reviewTmp with reviewTmp id " + reviewId + ".";
log.error(msg);
throw new ReviewManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@Override
public boolean updateReview(ReviewWrapper updatingReview, int reviewId, String uuid, boolean isPriviledgedUser)
throws ReviewManagementException, ApplicationManagementException {
public boolean updateReview(ReviewWrapper updatingReview, int reviewId, String uuid,
boolean isPrivilegedUser) throws ReviewManagementException, ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
if (log.isDebugEnabled()) {
log.debug("Review updating request is received for the reviewTmp id " + reviewId);
ReviewDTO reviewDTO = getReview(reviewId);
if (reviewDTO == null) {
String msg = "Couldn't found a review for review ID: " + reviewId;
log.error(msg);
throw new NotFoundException(msg);
}
if (!isPrivilegedUser && !username.equals(reviewDTO.getUsername())) {
String msg = "You are trying to update a review which is created by " + reviewDTO.getUsername()
+ ". Hence you are not permitted to update the review.";
log.error(msg);
throw new ForbiddenException(msg);
}
try {
ConnectionManagerUtil.beginDBTransaction();
ApplicationReleaseDTO applicationReleaseDTO = this.applicationReleaseDAO.getReleaseByUUID(uuid, tenantId);
if (applicationReleaseDTO == null) {
String msg = "Couldn't found an application release for UUID: " + uuid;
log.error(msg);
throw new NotFoundException(msg);
}
ReviewDTO reviewDTO = this.reviewDAO.getReview(applicationReleaseDTO.getId(), reviewId);
if (reviewDTO == null) {
String msg =
"Couldn't found a review for application release which has UUID: " + uuid + " and review ID: "
+ reviewId;
log.error(msg);
throw new NotFoundException(msg);
}
if (!isPriviledgedUser && !username.equals(reviewDTO.getUsername())) {
String msg = "You are trying to update a review which is created by " + reviewDTO.getUsername()
+ ". Hence you are not permitted to update the review.";
log.error(msg);
throw new ForbiddenException(msg);
}
if (reviewDTO.getRootParentId() == -1 && reviewDTO.getImmediateParentId() == -1
&& updatingReview.getRating() > 0 && updatingReview.getRating() != reviewDTO.getRating()) {
Runnable task = () -> calculateRating(updatingReview.getRating(), reviewDTO.getRating(), uuid,
tenantId);
boolean isActiveReview = true;
//Handle Review
if (reviewDTO.getRootParentId() == -1 && reviewDTO.getImmediateParentId() == -1) {
if (!reviewDTO.getReleaseUuid().equals(uuid)) {
isActiveReview = false;
if (!addReview(updatingReview, uuid, true)) {
String msg = "Review Updating Status: New review adding is failed.";
log.error(msg);
throw new ReviewManagementException(msg);
}
} else if (updatingReview.getRating() > 0 && updatingReview.getRating() != reviewDTO.getRating()) {
Runnable task = () -> ReviewManagerImpl.this
.calculateRating(updatingReview.getRating(), reviewDTO.getRating(), uuid, tenantId);
new Thread(task).start();
reviewDTO.setRating(updatingReview.getRating());
reviewDTO.setContent(updatingReview.getContent());
}
} else {
if (!reviewDTO.getReleaseUuid().equals(uuid)) {
String msg = "You are trying to update reply comment, but associated application release UUID and "
+ "requested app release UUID are mismatched.";
throw new BadRequestException(msg);
}
reviewDTO.setContent(updatingReview.getContent());
if (this.reviewDAO.updateReview(reviewDTO, reviewId, tenantId) == 1){
}
return updateReviewInDB(reviewDTO, uuid, reviewId, isActiveReview, tenantId);
}
private boolean updateReviewInDB(ReviewDTO reviewDTO, String uuid, int reviewId, boolean isActiveReview,
int tenantId) throws ReviewManagementException, ApplicationManagementException {
try {
ConnectionManagerUtil.beginDBTransaction();
if (this.reviewDAO.updateReview(reviewDTO, reviewId, isActiveReview, tenantId) == 1) {
if (!isActiveReview) {
updateAppRating(uuid, tenantId);
}
ConnectionManagerUtil.commitDBTransaction();
return true;
}
ConnectionManagerUtil.rollbackDBTransaction();
return false;
} catch (ReviewManagementDAOException e) {
ConnectionManagerUtil.rollbackDBTransaction();
@ -283,10 +329,6 @@ public class ReviewManagerImpl implements ReviewManager {
String msg = "DB Connection error occurs updating reviewTmp with reviewTmp id " + reviewId + ".";
log.error(msg);
throw new ReviewManagementException(msg, e);
} catch (ApplicationManagementDAOException e) {
String msg = "Error occured when getting application release data for application release UUID: " + uuid;
log.error(msg);
throw new ApplicationManagementException(msg, e);
} catch (TransactionManagementException e) {
String msg = "DB transaction error occurred when updating comment which has comment id: " + reviewId;
log.error(msg);
@ -297,13 +339,11 @@ public class ReviewManagerImpl implements ReviewManager {
}
@Override
public PaginationResult getAllReviews(PaginationRequest request, String uuid)
public PaginationResult getAllReleaseReviews(PaginationRequest request, String uuid)
throws ReviewManagementException, ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
PaginationResult paginationResult = new PaginationResult();
TreeMap<Integer, ReviewNode<ReviewDTO>> reviewTree = new TreeMap<>();
if (log.isDebugEnabled()) {
log.debug("Get all reviewTmps of the application release uuid: " + uuid);
log.debug("Get all release reviews of the application release uuid: " + uuid);
}
try {
ConnectionManagerUtil.openDBConnection();
@ -313,13 +353,115 @@ public class ReviewManagerImpl implements ReviewManager {
log.error(msg);
throw new NotFoundException(msg);
}
List<ReviewDTO> reviewDTOs= this.reviewDAO.getAllReviews(releaseDTO.getId(), request, tenantId);
for (ReviewDTO reviewDTO : reviewDTOs){
return getReviewTree(this.reviewDAO.getAllActiveReleaseReviews(releaseDTO.getId(), request, tenantId));
} catch (ReviewManagementDAOException e) {
throw new ReviewManagementException("Error occured while getting all reviews for application uuid: " + uuid,
e);
} catch (DBConnectionException e) {
throw new ReviewManagementException("Error occured while getting the DB connection.", e);
} catch (ApplicationManagementDAOException e) {
String msg = "Error occurred while getting application release details for application release UUId " + uuid;
log.error(msg);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@Override
public PaginationResult getAllAppReviews(PaginationRequest request, String uuid)
throws ReviewManagementException, ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
if (log.isDebugEnabled()) {
log.debug("Get all reviews of the application release uuid: " + uuid);
}
List<Integer> applicationReleaseIds = getAppReleaseIdsByUUID(uuid, tenantId);
try {
ConnectionManagerUtil.openDBConnection();
return getReviewTree(this.reviewDAO.getAllActiveAppReviews(applicationReleaseIds, request, tenantId));
} catch (ReviewManagementDAOException e) {
String msg = "Error occured while getting all reviews for application which has an "
+ "application release of uuid: " + uuid;
log.error(msg);
throw new ReviewManagementException(msg, e);
} catch (DBConnectionException e) {
String msg = "Error occured while getting the DB connection to get app app reviews.";
log.error(msg);
throw new ReviewManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@Override
public PaginationResult getAllAppReviewsOfUser(PaginationRequest request, String uuid)
throws ReviewManagementException, ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
if (log.isDebugEnabled()) {
log.debug("Get all reviews of the application release uuid: " + uuid);
}
List<Integer> applicationReleaseIds = getAppReleaseIdsByUUID(uuid, tenantId);
try {
ConnectionManagerUtil.openDBConnection();
List<ReviewDTO> reviewDtos = this.reviewDAO
.getAllActiveAppReviewsOfUser(applicationReleaseIds, request, username, tenantId);
if (!reviewDtos.isEmpty() && reviewDtos.size() > 1) {
String msg = "User " + username + " can't have more than active application review for application which"
+ " has application release of UUID: " + uuid;
log.error(msg);
throw new ApplicationManagementException(msg);
}
return getReviewTree(reviewDtos);
} catch (ReviewManagementDAOException e) {
throw new ReviewManagementException("Error occured while getting all reviews for application which has an "
+ "application release of uuid: " + uuid,
e);
} catch (DBConnectionException e) {
throw new ReviewManagementException("Error occured while getting the DB connection.", e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
private List<Integer> getAppReleaseIdsByUUID(String uuid, int tenantId)
throws ReviewManagementException, ApplicationManagementException {
try {
ConnectionManagerUtil.openDBConnection();
ApplicationDTO applicationDTO = this.applicationDAO.getApplicationByUUID(uuid, tenantId);
if (applicationDTO == null) {
String msg = "Couldn't find an application which has the application release of UUID: " + uuid;
log.error(msg);
throw new NotFoundException(msg);
}
return applicationDTO.getApplicationReleaseDTOs().stream().map(ApplicationReleaseDTO::getId)
.collect(Collectors.toList());
} catch (DBConnectionException e) {
String msg = "Error occured while getting the DB connection to get application which has application release"
+ " of UUID: " + uuid;
log.error(msg);
throw new ReviewManagementException(msg, e);
} catch (ApplicationManagementDAOException e) {
String msg = "Error occurred while getting application release details for application which has an "
+ "application release of UUID " + uuid;
log.error(msg);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
private PaginationResult getReviewTree(List<ReviewDTO> reviewDTOs) throws ReviewManagementException {
TreeMap<Integer, ReviewNode<ReviewDTO>> reviewTree = new TreeMap<>();
PaginationResult paginationResult = new PaginationResult();
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
try {
for (ReviewDTO reviewDTO : reviewDTOs) {
ReviewNode<ReviewDTO> rootNode = new ReviewNode<>(reviewDTO);
reviewTree.put(reviewDTO.getId(), rootNode);
List<ReviewDTO> replyComments = this.reviewDAO.getReplyComments(reviewDTO.getId(), tenantId);
replyComments.sort(Comparator.comparing(ReviewDTO::getId));
for (ReviewDTO reply : replyComments){
for (ReviewDTO reply : replyComments) {
reviewTree.put(reply.getRootParentId(),
findAndSetChild(reviewTree.get(reply.getRootParentId()), reply));
}
@ -327,7 +469,7 @@ public class ReviewManagerImpl implements ReviewManager {
int numOfReviews = reviewTree.size();
List<Review> results = new ArrayList<>();
for (ReviewNode<ReviewDTO> reviewNode : reviewTree.values()){
for (ReviewNode<ReviewDTO> reviewNode : reviewTree.values()) {
results.add(constructReviewResponse(null, reviewNode));
}
paginationResult.setData(new ArrayList<>(results));
@ -335,16 +477,8 @@ public class ReviewManagerImpl implements ReviewManager {
paginationResult.setRecordsTotal(numOfReviews);
return paginationResult;
} catch (ReviewManagementDAOException e) {
throw new ReviewManagementException("Error occured while getting all reviewTmps for application uuid: " + uuid,
throw new ReviewManagementException("Error occured while getting all reply comments for given review list",
e);
} catch (DBConnectionException e) {
throw new ReviewManagementException("Error occured while getting the DB connection.", e);
} catch (ApplicationManagementDAOException e) {
String msg = "Error occurred while getting application release details for application release UUId " + uuid;
log.error(msg);
throw new ApplicationManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@ -406,19 +540,18 @@ public class ReviewManagerImpl implements ReviewManager {
String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
try {
ConnectionManagerUtil.beginDBTransaction();
ApplicationReleaseDTO applicationReleaseDTO = this.applicationReleaseDAO.getReleaseByUUID(uuid, tenantId);
if (applicationReleaseDTO == null) {
String msg = "Couldn't found an application release for UUID: " + uuid
+ " to delete review which has review ID: " + reviewId;
log.error(msg);
throw new NotFoundException(msg);
}
ReviewDTO existingReview = this.reviewDAO.getReview(applicationReleaseDTO.getId(), reviewId);
ReviewDTO existingReview = this.reviewDAO.getReview(reviewId);
if (existingReview == null) {
String msg = "Cannot delete a non-existing review for the application with review id" + reviewId;
log.error(msg);
throw new NotFoundException(msg);
}
if (!existingReview.getReleaseUuid().equals(uuid)){
String msg = "You are trying to delete a review which is not associated with application release which "
+ "has UUID: " + uuid;
log.error(msg);
throw new ForbiddenException(msg);
}
if (!isPriviledgedUser && !username.equals(existingReview.getUsername())) {
String msg = "You are trying to delete a comment that is owned by you. Hence you are not permitted to "
+ "delete the review";
@ -433,7 +566,7 @@ public class ReviewManagerImpl implements ReviewManager {
Runnable task = () -> calculateRating(0, existingReview.getRating(), uuid, tenantId);
new Thread(task).start();
} else {
ReviewDTO rootReview = this.reviewDAO.getReview(existingReview.getRootParentId());
ReviewDTO rootReview = this.reviewDAO.getReview(existingReview.getRootParentId(), tenantId);
List<ReviewDTO> replyComments = this.reviewDAO.getReplyComments(rootReview.getId(), tenantId);
ReviewNode<ReviewDTO> reviewNode = new ReviewNode<>(rootReview);
@ -460,59 +593,97 @@ public class ReviewManagerImpl implements ReviewManager {
String msg = "Error occurred when handleing transaction to delete application reviews.";
log.error(msg);
throw new ReviewManagementException(msg, e);
} catch (ApplicationManagementDAOException e) {
String msg = "Error Occurred when getting application release data for application release UUID: " + uuid;
log.error(msg);
throw new ReviewManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@Override public Rating getRating(String appReleaseUuuid) throws ReviewManagementException, ApplicationManagementException {
@Override
public Rating getAppReleaseRating(String appReleaseUuid) throws ReviewManagementException, ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
try {
ConnectionManagerUtil.openDBConnection();
Rating rating = this.applicationReleaseDAO.getRating(appReleaseUuuid, tenantId);
Rating rating = this.applicationReleaseDAO.getRating(appReleaseUuid, tenantId);
if (rating == null) {
throw new NotFoundException(
"Couldn't find rating for application release UUID: " + appReleaseUuuid
"Couldn't find rating for application release UUID: " + appReleaseUuid
+ ". Please check the existence of the application release");
}
List<Integer> ratingValues = this.reviewDAO.getAllRatingValues(appReleaseUuuid, tenantId);
TreeMap<Integer, Integer> ratingVariety = new TreeMap<>();
ratingValues.forEach(ratingVal -> {
if (ratingVariety.containsKey(ratingVal)) {
ratingVariety.replace(ratingVal, ratingVariety.get(ratingVal) + 1);
} else {
ratingVariety.put(ratingVal, 1);
}
});
IntStream.rangeClosed(1, Constants.MAX_RATING).filter(i -> !ratingVariety.containsKey(i))
.forEach(i -> ratingVariety.put(i, 0));
rating.setRatingVariety(ratingVariety);
List<Integer> ratingValues = this.reviewDAO.getAllAppReleaseRatingValues(appReleaseUuid, tenantId);
rating.setRatingVariety(constructRatingVariety(ratingValues));
return rating;
} catch (ApplicationManagementDAOException e) {
ConnectionManagerUtil.rollbackDBTransaction();
throw new ReviewManagementException(
"Error occured while getting the rating value of the application release uuid: " + appReleaseUuuid,
"Error occured while getting the rating value of the application release uuid: " + appReleaseUuid,
e);
} catch (DBConnectionException e) {
ConnectionManagerUtil.rollbackDBTransaction();
throw new ReviewManagementException(
"DB Connection error occured while getting the rating value of the application release uuid: "
+ appReleaseUuuid, e);
+ appReleaseUuid, e);
} catch (ReviewManagementDAOException e) {
throw new ReviewManagementException(
"Error occured while getting all rating values for the application release UUID: "
+ appReleaseUuuid, e);
+ appReleaseUuid, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
@Override
public Rating getAppRating(String appReleaseUuid) throws ReviewManagementException, ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
try {
ConnectionManagerUtil.openDBConnection();
ApplicationDTO applicationDTO = this.applicationDAO.getApplicationByUUID(appReleaseUuid, tenantId);
if (applicationDTO == null) {
String msg = "Couldn't found an application for application release UUID: " + appReleaseUuid;
log.error(msg);
throw new NotFoundException(msg);
}
List<String> uuids = applicationDTO.getApplicationReleaseDTOs().stream().map(ApplicationReleaseDTO::getUuid)
.collect(Collectors.toList());
List<Integer> ratingValues = this.reviewDAO.getAllAppRatingValues(uuids, tenantId);
Rating rating = new Rating();
rating.setRatingValue(applicationDTO.getAppRating());
rating.setNoOfUsers(ratingValues.size());
rating.setRatingVariety(constructRatingVariety(ratingValues));
return rating;
} catch (DBConnectionException e) {
String msg = "DB Connection error occured while getting app rating of the application which has application "
+ "release for uuid: " + appReleaseUuid;
log.error(msg);
throw new ReviewManagementException(msg, e);
}catch (ApplicationManagementDAOException e) {
String msg = "Error occured while getting the application DTO for the application release uuid: " + appReleaseUuid;
log.error(msg);
throw new ReviewManagementException(msg, e);
} catch (ReviewManagementDAOException e) {
String msg ="Error occured while getting all rating values of application which has the application release "
+ "for UUID: " + appReleaseUuid;
log.error(msg);
throw new ReviewManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
private TreeMap<Integer, Integer> constructRatingVariety(List<Integer> ratingValues) {
TreeMap<Integer, Integer> ratingVariety = new TreeMap<>();
ratingValues.forEach(ratingVal -> {
if (ratingVariety.containsKey(ratingVal)) {
ratingVariety.replace(ratingVal, ratingVariety.get(ratingVal) + 1);
} else {
ratingVariety.put(ratingVal, 1);
}
});
IntStream.rangeClosed(1, Constants.MAX_RATING).filter(i -> !ratingVariety.containsKey(i))
.forEach(i -> ratingVariety.put(i, 0));
return ratingVariety;
}
private void calculateRating(int newRatingVal, int oldRatingVal, String uuid, int tenantId) {
try {
ConnectionManagerUtil.beginDBTransaction();
@ -544,14 +715,7 @@ public class ReviewManagerImpl implements ReviewManager {
}
this.applicationReleaseDAO.updateRatingValue(uuid, updatedRating, numOfUsers);
List<Double> releaseRatings = this.applicationReleaseDAO.getReleaseRatings(uuid, tenantId);
double appAverageRatingValue = 0.0;
double sumOfRatings = releaseRatings.stream().mapToDouble(rt -> rt).sum();
if (sumOfRatings != 0.0) {
appAverageRatingValue = sumOfRatings / releaseRatings.size();
}
this.applicationDAO.updateApplicationRating(uuid, appAverageRatingValue, tenantId);
updateAppRating(uuid, tenantId);
ConnectionManagerUtil.commitDBTransaction();
}
} catch (ApplicationManagementDAOException e) {
@ -564,8 +728,31 @@ public class ReviewManagerImpl implements ReviewManager {
log.error(
"Transaction error occured while updated the rating value of the application release UUID: " + uuid
+ " can not get.", e);
} catch (ApplicationManagementException e) {
ConnectionManagerUtil.rollbackDBTransaction();
log.error("Error occured while updating app rating value which has application release for UUID: " + uuid,
e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
private void updateAppRating(String uuid, int tenantId) throws ApplicationManagementException {
try {
ApplicationDTO applicationDTO = this.applicationDAO.getApplicationByUUID(uuid, tenantId);
List<String> uuids = applicationDTO.getApplicationReleaseDTOs().stream().map(ApplicationReleaseDTO::getUuid)
.collect(Collectors.toList());
List<Integer> appRatings = this.reviewDAO.getAllAppRatingValues(uuids, tenantId);
double appAverageRatingValue = appRatings.stream().mapToDouble(x -> x).average().orElse(Double.NaN);
this.applicationDAO.updateApplicationRating(uuid, appAverageRatingValue, tenantId);
} catch (ApplicationManagementDAOException e) {
String msg = "Error occurred when getting application data or updating application rating value.";
log.error(msg);
throw new ApplicationManagementException(msg, e);
} catch (ReviewManagementDAOException e) {
String msg = "Error occurred when getting application rating values";
log.error(msg, e);
throw new ApplicationManagementException(msg, e);
}
}
}

@ -388,7 +388,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
ConnectionManagerUtil.commitDBTransaction();
} catch (ApplicationManagementDAOException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Error occurred when adding subscription data for application release UUID: "
String msg = "Error occurred when adding subscription data for application release ID: "
+ applicationReleaseId;
log.error(msg);
throw new ApplicationManagementException(msg, e);
@ -398,7 +398,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
throw new ApplicationManagementException(msg, e);
} catch (TransactionManagementException e) {
String msg =
"SQL Error occurred when adding new device subscription to application release which has UUID: "
"SQL Error occurred when adding new device subscription to application release which has ID: "
+ applicationReleaseId;
log.error(msg);
throw new ApplicationManagementException(msg, e);

@ -190,13 +190,13 @@ public class APIUtil {
try {
deviceTypes = DAOUtil.getDeviceManagementService().getDeviceTypes();
if(deviceTypeAttr instanceof String){
if (deviceTypeAttr instanceof String) {
for (DeviceType dt : deviceTypes) {
if (dt.getName().equals(deviceTypeAttr)) {
return dt;
}
}
} else if (deviceTypeAttr instanceof Integer){
} else if (deviceTypeAttr instanceof Integer) {
for (DeviceType dt : deviceTypes) {
if (dt.getId() == (Integer) deviceTypeAttr) {
return dt;

@ -234,6 +234,8 @@ public class DAOUtil {
reviewDTO.setImmediateParentId(rs.getInt("IMMEDIATE_PARENT_ID"));
reviewDTO.setUsername(rs.getString("USERNAME"));
reviewDTO.setRating(rs.getInt("RATING"));
reviewDTO.setReleaseUuid(rs.getString("UUID"));
reviewDTO.setReleaseVersion(rs.getString("VERSION"));
reviewDTOs.add(reviewDTO);
}
return reviewDTOs;

@ -24,11 +24,11 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>application-mgt</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
</parent>
<artifactId>org.wso2.carbon.device.application.mgt.handler</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<packaging>war</packaging>
<name>WSO2 Carbon - Application Management Authentication Handler API</name>
<description>Proxy Service for Authentication Handling in WSO2 App Manager.</description>

@ -22,13 +22,13 @@
<parent>
<artifactId>application-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.application.mgt.publisher.api</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<packaging>war</packaging>
<name>WSO2 Carbon - Application Management Publisher API</name>
<description>WSO2 Carbon - Application Management Publisher API</description>

@ -143,6 +143,7 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
@PathParam("uuid") String uuid) {
ApplicationManager applicationManager = APIUtil.getApplicationManager();
try {
//todo return application
ApplicationRelease applicationRelease = applicationManager.getApplicationReleaseByUUID(uuid);
if (applicationRelease == null){
String msg = "Application release is in the end state of the application lifecycle flow.";
@ -186,7 +187,7 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
applicationManager.validateBinaryArtifact(binaryFile);
applicationManager.validateImageArtifacts(iconFile, bannerFile, attachmentList);
// Created new application entry
// Created new Ent App
Application application = applicationManager.createApplication(applicationWrapper,
constructApplicationArtifact(binaryFile, iconFile, bannerFile, attachmentList));
if (application != null) {
@ -224,7 +225,7 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
applicationManager.validateReleaseCreatingRequest(webAppWrapper.getWebAppReleaseWrappers().get(0));
applicationManager.validateImageArtifacts(iconFile, bannerFile, attachmentList);
// Created new application entry
// Created new Web App
Application application = applicationManager.createWebClip(webAppWrapper,
constructApplicationArtifact(null, iconFile, bannerFile, attachmentList));
if (application != null) {
@ -262,7 +263,7 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
applicationManager.validateReleaseCreatingRequest(publicAppWrapper.getPublicAppReleaseWrappers().get(0));
applicationManager.validateImageArtifacts(iconFile, bannerFile, attachmentList);
// Created new application entry
// Created new Public App
Application application = applicationManager.createPublicApp(publicAppWrapper,
constructApplicationArtifact(null, iconFile, bannerFile, attachmentList));
if (application != null) {
@ -302,8 +303,8 @@ public class ApplicationManagementPublisherAPIImpl implements ApplicationManagem
applicationManager.validateBinaryArtifact(binaryFile);
applicationManager.validateImageArtifacts(iconFile, bannerFile, attachmentList);
// Created new application release
ApplicationRelease release = applicationManager.createRelease(appId, applicationReleaseWrapper,
// Created new Ent App release
ApplicationRelease release = applicationManager.createEntAppRelease(appId, applicationReleaseWrapper,
constructApplicationArtifact(binaryFile, iconFile, bannerFile, attachmentList));
if (release != null) {
return Response.status(Response.Status.CREATED).entity(release).build();

@ -24,10 +24,10 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>application-mgt</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
</parent>
<artifactId>org.wso2.carbon.device.application.mgt.publisher.ui</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<packaging>war</packaging>
<name>WSO2 Carbon - Application Management Publisher UI Component</name>
<url>http://wso2.org</url>

@ -0,0 +1,60 @@
import React from "react";
import "antd/dist/antd.css";
import {PageHeader, Typography,Input, Button, Row, Col} from "antd";
import AppList from "../../../components/apps/AppList";
import ReleaseModal from "../../../components/apps/ReleaseModal";
const Search = Input.Search;
const routes = [
{
path: 'index',
breadcrumbName: 'Publisher',
},
{
path: 'first',
breadcrumbName: 'Dashboard',
},
{
path: 'second',
breadcrumbName: 'Apps',
},
];
class Apps extends React.Component {
routes;
constructor(props) {
super(props);
this.routes = props.routes;
}
render() {
return (
<div>
<PageHeader
breadcrumb={{routes}}
/>
<div style={{background: '#f0f2f5', padding: 24, minHeight: 780}}>
<Row style={{padding:10}}>
<Col span={6} offset={18}>
<Search
placeholder="search"
onSearch={value => console.log(value)}
style={{ width: 200}}
/>
<Button style={{margin:5}}>Advanced Search</Button>
</Col>
</Row>
<ReleaseModal/>
<AppList/>
</div>
</div>
);
}
}
export default Apps;

@ -22,13 +22,13 @@
<parent>
<artifactId>application-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.device.application.mgt.store.api</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<packaging>war</packaging>
<name>WSO2 Carbon - Application Management Store API</name>
<description>WSO2 Carbon - Application Management Store API</description>

@ -92,13 +92,13 @@ public interface ReviewManagementAPI {
String SCOPE = "scope";
@GET
@Path("/{uuid}")
@Path("/release/{uuid}")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "get reviews",
notes = "Get all reviews",
value = "get app release reviews",
notes = "Get all app release reviews",
tags = "Store Management",
extensions = {
@Extension(properties = {
@ -111,7 +111,7 @@ public interface ReviewManagementAPI {
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully retrieved reviews.",
message = "OK. \n Successfully retrieved app release reviews.",
response = PaginationResult.class,
responseContainer = "PaginationResult"),
@ApiResponse(
@ -123,7 +123,7 @@ public interface ReviewManagementAPI {
response = ErrorResponse.class)
})
Response getAllReviews(
Response getAllReleaseReviews(
@ApiParam(
name="uuid",
value="uuid of the application release.",
@ -140,6 +140,106 @@ public interface ReviewManagementAPI {
defaultValue = "20")
@QueryParam("limit") int limit);
@GET
@Path("/app/user/{uuid}")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "get app reviews",
notes = "Get all app reviews",
tags = "Store Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:app:review:view")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully retrieved app reviews.",
response = PaginationResult.class,
responseContainer = "PaginationResult"),
@ApiResponse(
code = 404,
message = "Not Found. \n Not found an application release associated with requested "
+ "UUID."),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error occurred while getting the review list.",
response = ErrorResponse.class)
})
Response getUserReviews(
@ApiParam(
name="uuid",
value="uuid of the application release.",
required = true)
@PathParam("uuid") String uuid,
@ApiParam(
name="offset",
value="Starting review number.",
defaultValue = "0")
@QueryParam("offSet") int offSet,
@ApiParam(
name="limit",
value = "Limit of paginated reviews",
defaultValue = "20")
@QueryParam("limit") int limit);
@GET
@Path("/app/{uuid}")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "get app reviews",
notes = "Get all app reviews",
tags = "Store Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:app:review:view")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully retrieved app reviews.",
response = PaginationResult.class,
responseContainer = "PaginationResult"),
@ApiResponse(
code = 404,
message = "Not Found. \n Not found an application release associated with requested "
+ "UUID."),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error occurred while getting the review list.",
response = ErrorResponse.class)
})
Response getAllAppReviews(
@ApiParam(
name="uuid",
value="uuid of the application release.",
required = true)
@PathParam("uuid") String uuid,
@ApiParam(
name="offset",
value="Starting review number.",
defaultValue = "0")
@QueryParam("offSet") int offSet,
@ApiParam(
name="limit",
value = "Limit of paginated reviews",
defaultValue = "20")
@QueryParam("limit") int limit);
@POST
@Path("/{uuid}")
@Produces(MediaType.APPLICATION_JSON)
@ -342,7 +442,7 @@ public interface ReviewManagementAPI {
@PathParam("reviewId") int reviewId);
@GET
@Path("/{uuid}/rating")
@Path("/{uuid}/release-rating")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
@ -374,11 +474,52 @@ public interface ReviewManagementAPI {
response = ErrorResponse.class)
})
Response getRating(
Response getAppReleaseRating(
@ApiParam(
name = "uuid",
value = "uuid of the application release",
required = true)
@PathParam("uuid")
String uuid);
@GET
@Path("/{uuid}/app-rating")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "get app ratings",
notes = "Get all app ratings",
tags = "Store Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = SCOPE, value = "perm:app:review:view")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully retrieved ratings.",
response = List.class,
responseContainer = "List"),
@ApiResponse(
code = 404,
message = "Not Found. \n No Application found which has application release of UUID.",
response = ErrorResponse.class),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error occurred while getting ratings",
response = ErrorResponse.class)
})
Response getAppRating(
@ApiParam(
name = "uuid",
value = "uuid of the application release",
required = true)
@PathParam("uuid")
String uuid);
}

@ -55,15 +55,15 @@ public class ReviewManagementAPIImpl implements ReviewManagementAPI {
@Override
@GET
@Path("/{uuid}")
public Response getAllReviews(
@Path("/release/{uuid}")
public Response getAllReleaseReviews(
@PathParam("uuid") String uuid,
@DefaultValue("0") @QueryParam("offset") int offSet,
@DefaultValue("20") @QueryParam("limit") int limit) {
ReviewManager reviewManager = APIUtil.getReviewManager();
PaginationRequest request = new PaginationRequest(offSet, limit);
try {
PaginationResult paginationResult = reviewManager.getAllReviews(request, uuid);
PaginationResult paginationResult = reviewManager.getAllReleaseReviews(request, uuid);
return Response.status(Response.Status.OK).entity(paginationResult).build();
} catch (NotFoundException e) {
String msg = "Couldn't find an application release for UUID: " + uuid;
@ -80,6 +80,62 @@ public class ReviewManagementAPIImpl implements ReviewManagementAPI {
}
}
@Override
@GET
@Path("/app/user/{uuid}")
public Response getUserReviews(
@PathParam("uuid") String uuid,
@DefaultValue("0") @QueryParam("offset") int offSet,
@DefaultValue("20") @QueryParam("limit") int limit) {
ReviewManager reviewManager = APIUtil.getReviewManager();
PaginationRequest request = new PaginationRequest(offSet, limit);
try {
PaginationResult paginationResult = reviewManager.getAllAppReviewsOfUser(request, uuid);
return Response.status(Response.Status.OK).entity(paginationResult).build();
} catch (NotFoundException e) {
String msg = "Couldn't find an application which has application release of UUID: " + uuid;
log.error(msg, e);
return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
} catch (ReviewManagementException e) {
String msg = "Error occurred while retrieving reviews for application which has application release for "
+ "UUID: " + uuid;
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (ApplicationManagementException e) {
String msg = "Error occurred while retrieving application release details for application UUID: " + uuid;
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
}
@Override
@GET
@Path("/app/{uuid}")
public Response getAllAppReviews(
@PathParam("uuid") String uuid,
@DefaultValue("0") @QueryParam("offset") int offSet,
@DefaultValue("20") @QueryParam("limit") int limit) {
ReviewManager reviewManager = APIUtil.getReviewManager();
PaginationRequest request = new PaginationRequest(offSet, limit);
try {
PaginationResult paginationResult = reviewManager.getAllAppReviews(request, uuid);
return Response.status(Response.Status.OK).entity(paginationResult).build();
} catch (NotFoundException e) {
String msg = "Couldn't find an application which has application release of UUID: " + uuid;
log.error(msg, e);
return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
} catch (ReviewManagementException e) {
String msg = "Error occurred while retrieving reviews for application which has application release for "
+ "UUID: " + uuid;
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (ApplicationManagementException e) {
String msg = "Error occurred while retrieving application release details for application UUID: " + uuid;
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
}
@Override
@POST
@Consumes("application/json")
@ -89,7 +145,7 @@ public class ReviewManagementAPIImpl implements ReviewManagementAPI {
@PathParam("uuid") String uuid) {
ReviewManager reviewManager = APIUtil.getReviewManager();
try {
boolean isReviewCreated = reviewManager.addReview(reviewWrapper, uuid);
boolean isReviewCreated = reviewManager.addReview(reviewWrapper, uuid, false);
if (isReviewCreated) {
return Response.status(Response.Status.CREATED).entity(reviewWrapper).build();
} else {
@ -227,13 +283,13 @@ public class ReviewManagementAPIImpl implements ReviewManagementAPI {
@Override
@GET
@Path("/{uuid}/rating")
public Response getRating(
@Path("/{uuid}/release-rating")
public Response getAppReleaseRating(
@PathParam("uuid") String uuid) {
ReviewManager reviewManager = APIUtil.getReviewManager();
Rating rating;
try {
rating = reviewManager.getRating(uuid);
rating = reviewManager.getAppReleaseRating(uuid);
} catch (NotFoundException e) {
String msg = "Couldn't found an application release for UUID: " + uuid;
log.error(msg, e);
@ -246,4 +302,25 @@ public class ReviewManagementAPIImpl implements ReviewManagementAPI {
return Response.status(Response.Status.OK).entity(rating).build();
}
@Override
@GET
@Path("/{uuid}/app-rating")
public Response getAppRating(
@PathParam("uuid") String uuid) {
ReviewManager reviewManager = APIUtil.getReviewManager();
Rating rating;
try {
rating = reviewManager.getAppRating(uuid);
} catch (NotFoundException e) {
String msg = "Couldn't found an application for application release UUID: " + uuid;
log.error(msg, e);
return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
} catch (ReviewManagementException | ApplicationManagementException e) {
String msg = "Error occured while getting review data for application release UUID: " + uuid;
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
return Response.status(Response.Status.OK).entity(rating).build();
}
}

@ -58,7 +58,7 @@ import org.wso2.carbon.device.application.mgt.core.util.APIUtil;
// @Test
// public void testGetAllCommentsWithValidDetails() throws Exception {
// PowerMockito.stub(PowerMockito.method(APIUtil.class, "getReviewManager")).toReturn(this.reviewManager);
// Response response = this.commentManagementAPI.getAllReviews("a", 1, 2);
// Response response = this.commentManagementAPI.getAllReleaseReviews("a", 1, 2);
// Assert.assertNotNull(response, "The response object is null.");
// Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
// "The response status should be 200.");
@ -69,8 +69,8 @@ import org.wso2.carbon.device.application.mgt.core.util.APIUtil;
// public void testGetAllCommentsInternalError() throws Exception {
// PowerMockito.stub(PowerMockito.method(APIUtil.class, "getReviewManager")).toReturn(this.reviewManager);
// Mockito.doThrow(new ReviewManagementException()).when(this.reviewManager)
// .getAllReviews(Mockito.any(), Mockito.anyString());
// Response response = this.commentManagementAPI.getAllReviews("a", 1, 4);
// .getAllReleaseReviews(Mockito.any(), Mockito.anyString());
// Response response = this.commentManagementAPI.getAllReleaseReviews("a", 1, 4);
// Assert.assertNotNull(response, "The response object is null.");
// Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
// "The response status should be 500.");
@ -80,7 +80,7 @@ import org.wso2.carbon.device.application.mgt.core.util.APIUtil;
// @Test
// public void testGetAllCommentsNotFoundError() throws Exception {
// PowerMockito.stub(PowerMockito.method(APIUtil.class, "getReviewManager")).toReturn(this.reviewManager);
// Response response = this.commentManagementAPI.getAllReviews(null, 1, 3);
// Response response = this.commentManagementAPI.getAllReleaseReviews(null, 1, 3);
// Assert.assertNotNull(response, "The response object is null.");
// Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode(),
// "The response status should be 404.");
@ -192,7 +192,7 @@ import org.wso2.carbon.device.application.mgt.core.util.APIUtil;
// @Test
// public void testGetStars() throws Exception {
// PowerMockito.stub(PowerMockito.method(APIUtil.class, "getReviewManager")).toReturn(this.reviewManager);
// Response response = this.commentManagementAPI.getRating("a");
// Response response = this.commentManagementAPI.getAppReleaseRating("a");
// Assert.assertNotNull(response, "The response object is null.");
// Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
// "The response status should be 200.");
@ -202,9 +202,9 @@ import org.wso2.carbon.device.application.mgt.core.util.APIUtil;
// @Test
// public void testGetStarsCommentError() throws Exception {
// PowerMockito.stub(PowerMockito.method(APIUtil.class, "getReviewManager")).toReturn(this.reviewManager);
// Mockito.when(this.commentManagementAPI.getRating(Mockito.anyString()))
// Mockito.when(this.commentManagementAPI.getAppReleaseRating(Mockito.anyString()))
// .thenThrow(new ReviewManagementException());
// Response response = this.commentManagementAPI.getRating("a");
// Response response = this.commentManagementAPI.getAppReleaseRating("a");
// Assert.assertNotNull(response, "The response object is null.");
// Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
// "The response status should be 500.");
@ -214,9 +214,9 @@ import org.wso2.carbon.device.application.mgt.core.util.APIUtil;
// @Test
// public void testGetStarsApplicationError() throws Exception {
// PowerMockito.stub(PowerMockito.method(APIUtil.class, "getReviewManager")).toReturn(this.reviewManager);
// Mockito.when(this.commentManagementAPI.getRating(Mockito.anyString()))
// Mockito.when(this.commentManagementAPI.getAppReleaseRating(Mockito.anyString()))
// .thenThrow(new ApplicationManagementException());
// Response response = this.commentManagementAPI.getRating("a");
// Response response = this.commentManagementAPI.getAppReleaseRating("a");
// Assert.assertNotNull(response, "The response object is null.");
// Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
// "The response status should be 500.");

@ -24,10 +24,10 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>application-mgt</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
</parent>
<artifactId>org.wso2.carbon.device.application.mgt.store.ui</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<packaging>war</packaging>
<name>WSO2 Carbon - Application Management Store UI Component</name>
<url>http://wso2.org</url>

@ -22,13 +22,13 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>carbon-devicemgt</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>application-mgt</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<packaging>pom</packaging>
<name>WSO2 Carbon - Application Management Component</name>
<description>WSO2 Carbon - Application Management Component</description>

@ -22,7 +22,7 @@
<parent>
<artifactId>certificate-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>certificate-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -49,6 +49,8 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Path("/admin/certificates")
public class CertificateManagementAdminServiceImpl implements CertificateManagementAdminService {
@ -242,6 +244,11 @@ public class CertificateManagementAdminServiceImpl implements CertificateManagem
String challengeToken = certMgtService.extractChallengeToken(cert);
if (challengeToken != null) {
Pattern regexPattern = Pattern.compile("[a-zA-Z0-9][a-zA-Z0-9-]+$");
Matcher regexMatcher = regexPattern.matcher(challengeToken);
if (regexMatcher.find()) {
challengeToken = regexMatcher.group();
}
challengeToken = challengeToken.substring(challengeToken.indexOf("(") + 1).trim();
SCEPManager scepManager = CertificateMgtAPIUtils.getSCEPManagerService();

@ -21,13 +21,13 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>certificate-mgt</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.certificate.mgt.core</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>WSO2 Carbon - Certificate Management Core</name>
<description>WSO2 Carbon - Certificate Management Core</description>

@ -22,14 +22,14 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>carbon-devicemgt</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>certificate-mgt</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<packaging>pom</packaging>
<name>WSO2 Carbon - Certificate Management Component</name>
<url>http://wso2.org</url>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt-extensions</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<artifactId>carbon-devicemgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>device-mgt</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -20,7 +20,7 @@
<parent>
<artifactId>device-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -32,6 +32,10 @@ public class BasicUserInfo {
private String lastname;
@ApiModelProperty(name = "emailAddress", value = "The email address of the user.", required = true )
private String emailAddress;
@ApiModelProperty(name = "createdDate", value = "User creation date." )
private String createdDate;
@ApiModelProperty(name = "modifiedDate", value = "User modifiedDate date." )
private String modifiedDate;
public String getUsername() {
return username;
@ -65,4 +69,20 @@ public class BasicUserInfo {
this.emailAddress = emailAddress;
}
public String getCreatedDate() {
return createdDate;
}
public void setCreatedDate(String createdDate) {
this.createdDate = createdDate;
}
public String getModifiedDate() {
return modifiedDate;
}
public void setModifiedDate(String modifiedDate) {
this.modifiedDate = modifiedDate;
}
}

@ -16,6 +16,24 @@
* under the License.
*
*/
/*
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
*
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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;
@ -143,11 +161,11 @@ import java.util.List;
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"}
),
name = "Change device status.",
description = "Change device status.",
key = "perm:devices:change-status",
permissions = {"/device-mgt/devices/change-status"}
),
}
)
@Path("/devices")
@ -165,10 +183,10 @@ public interface DeviceManagementService {
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")
})
}
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:view")
})
}
)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK. \n Successfully fetched the list of devices.",
@ -212,14 +230,14 @@ public interface DeviceManagementService {
value = "The device name. For example, Nexus devices can have names, suhc as shamu, bullhead or angler.",
required = false)
@Size(max = 45)
String name,
String name,
@ApiParam(
name = "type",
value = "The device type, such as ios, android, or windows.",
required = false)
@QueryParam("type")
@Size(max = 45)
String type,
String type,
@ApiParam(
name = "user",
value = "The username of the owner of the device.",
@ -248,14 +266,14 @@ public interface DeviceManagementService {
required = false)
@QueryParam("ownership")
@Size(max = 45)
String ownership,
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,
String status,
@ApiParam(
name = "groupId",
value = "Id of the group which device belongs",
@ -269,7 +287,7 @@ public interface DeviceManagementService {
"Example: Mon, 05 Jan 2014 15:10:00 +0200",
required = false)
@QueryParam("since")
String since,
String since,
@ApiParam(
name = "If-Modified-Since",
value = "Checks if the requested variant was modified, since the specified date-time.\n" +
@ -277,7 +295,7 @@ public interface DeviceManagementService {
"Example: Mon, 05 Jan 2014 15:10:00 +0200",
required = false)
@HeaderParam("If-Modified-Since")
String timestamp,
String timestamp,
@ApiParam(
name = "requireDeviceInfo",
value = "Boolean flag indicating whether to include device-info (location, application list etc) \n" +
@ -291,14 +309,14 @@ public interface DeviceManagementService {
required = false,
defaultValue = "0")
@QueryParam("offset")
int 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);
int limit);
@GET
@ApiOperation(
@ -323,16 +341,16 @@ public interface DeviceManagementService {
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
"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."),
"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"),
"the requested resource.\n"),
@ApiResponse(
code = 400,
message = "The incoming request has more than one selection criteria defined via the query parameters.",
@ -383,9 +401,9 @@ public interface DeviceManagementService {
"the owner.",
tags = "Device Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:details")
})
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:details")
})
}
)
@ApiResponses(
@ -446,16 +464,92 @@ public interface DeviceManagementService {
required = false)
@QueryParam("owner")
@Size(max = 100)
String owner,
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)
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/any/id/{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 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 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 getDeviceByID(
@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 timestamp,
@ApiParam(
name = "requireDeviceInfo",
value = "Boolean flag indicating whether to include device-info \n" +
"(location, application list etc) to the device object.",
required = false)
@QueryParam("requireDeviceInfo")
boolean requireDeviceInfo);
@PUT
@Path("/{type}/{id}")
@ApiOperation(
@ -587,7 +681,6 @@ public interface DeviceManagementService {
String ifModifiedSince);
@GET
@Path("/{type}/{id}/info")
@ApiOperation(
@ -646,14 +739,14 @@ public interface DeviceManagementService {
required = true)
@PathParam("type")
@Size(max = 45)
String type,
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,
String id,
@ApiParam(
name = "If-Modified-Since",
value = "Checks if the requested variant was modified, since the specified date-time. \n" +
@ -661,7 +754,7 @@ public interface DeviceManagementService {
"Example: Mon, 05 Jan 2014 15:10:00 +0200",
required = false)
@HeaderParam("If-Modified-Since")
String ifModifiedSince);
String ifModifiedSince);
//device rename request would looks like follows
//POST devices/type/virtual_firealarm/id/us06ww93auzp/rename
@ -806,7 +899,12 @@ public interface DeviceManagementService {
required = true)
@PathParam("device-id")
@Size(max = 45)
String deviceId);
String deviceId,
@ApiParam(
name = "permanentDelete",
value = "Boolean flag indicating whether to permanently delete the device.",
required = false)
@QueryParam("permanentDelete") boolean permanentDelete);
@GET
@Path("/{type}/{id}/features")
@ -820,10 +918,10 @@ public interface DeviceManagementService {
" such as iOS, Android or Windows.",
tags = "Device Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:features")
})
}
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:features")
})
}
)
@ApiResponses(
value = {
@ -880,7 +978,7 @@ public interface DeviceManagementService {
required = true)
@PathParam("type")
@Size(max = 45)
String type,
String type,
@ApiParam(
name = "id",
value = "The device identifier of the device.\n" +
@ -888,7 +986,7 @@ public interface DeviceManagementService {
required = true)
@PathParam("id")
@Size(max = 45)
String id,
String id,
@ApiParam(
name = "If-Modified-Since",
value = "Checks if the requested variant was modified, since the specified date-time. \n" +
@ -896,7 +994,7 @@ public interface DeviceManagementService {
"Example: Mon, 05 Jan 2014 15:10:00 +0200",
required = false)
@HeaderParam("If-Modified-Since")
String ifModifiedSince);
String ifModifiedSince);
@POST
@Path("/search-devices")
@ -908,9 +1006,9 @@ public interface DeviceManagementService {
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")
})
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:search")
})
}
)
@ApiResponses(
@ -962,19 +1060,19 @@ public interface DeviceManagementService {
required = false,
defaultValue = "0")
@QueryParam("offset")
int 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,
int limit,
@ApiParam(
name = "searchContext",
value = "The properties to advanced search devices.",
required = true)
SearchContext searchContext);
SearchContext searchContext);
@GET
@Path("/{type}/{id}/applications")
@ -985,11 +1083,11 @@ public interface DeviceManagementService {
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")
})
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:applications")
})
}
}
)
@ApiResponses(
value = {
@ -1046,14 +1144,14 @@ public interface DeviceManagementService {
required = true)
@PathParam("type")
@Size(max = 45)
String type,
String type,
@ApiParam(
name = "id",
value = "The device identifier of the device.",
required = true)
@PathParam("id")
@Size(max = 45)
String id,
String id,
@ApiParam(
name = "If-Modified-Since",
value = "Checks if the requested variant was modified, since the specified date-time. \n" +
@ -1061,21 +1159,21 @@ public interface DeviceManagementService {
"Example: Mon, 05 Jan 2014 15:10:00 +0200",
required = false)
@HeaderParam("If-Modified-Since")
String ifModifiedSince,
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,
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);
int limit);
@GET
@ -1087,10 +1185,10 @@ public interface DeviceManagementService {
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")
})
}
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:operations")
})
}
)
@ApiResponses(
value = {
@ -1147,7 +1245,7 @@ public interface DeviceManagementService {
required = true)
@PathParam("type")
@Size(max = 45)
String type,
String type,
@ApiParam(
name = "id",
value = "The device identifier of the device you wish to get details.\n" +
@ -1155,7 +1253,7 @@ public interface DeviceManagementService {
required = true)
@PathParam("id")
@Size(max = 45)
String id,
String id,
@ApiParam(
name = "If-Modified-Since",
value = "Checks if the requested variant was modified, since the specified date-time. \n" +
@ -1163,21 +1261,21 @@ public interface DeviceManagementService {
"Example: Mon, 05 Jan 2014 15:10:00 +0200",
required = false)
@HeaderParam("If-Modified-Since")
String ifModifiedSince,
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,
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,
int limit,
@ApiParam(
name = "owner",
value = "Provides the owner of the required device.",
@ -1197,10 +1295,10 @@ public interface DeviceManagementService {
"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")
})
}
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:effective-policy")
})
}
)
@ApiResponses(
value = {
@ -1257,14 +1355,14 @@ public interface DeviceManagementService {
required = true)
@PathParam("type")
@Size(max = 45)
String type,
String type,
@ApiParam(
name = "id",
value = "The device ID.",
required = true)
@PathParam("id")
@Size(max = 45)
String id,
String id,
@ApiParam(
name = "If-Modified-Since",
value = "Checks if the requested variant was modified, since the specified date-time. \n" +
@ -1272,7 +1370,7 @@ public interface DeviceManagementService {
"Example: Mon, 05 Jan 2014 15:10:00 +0200",
required = false)
@HeaderParam("If-Modified-Since")
String ifModifiedSince);
String ifModifiedSince);
@GET
@ -1285,9 +1383,9 @@ public interface DeviceManagementService {
"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")
})
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:compliance-data")
})
}
)
@ApiResponses(
@ -1313,14 +1411,14 @@ public interface DeviceManagementService {
required = true)
@PathParam("type")
@Size(max = 45)
String type,
String type,
@ApiParam(
name = "id",
value = "Device Identifier",
required = true)
@PathParam("id")
@Size(max = 45)
String id);
String id);
@PUT
@Path("/{type}/{id}/changestatus")

@ -14,40 +14,41 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
*
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
*
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.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.Feature;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceTypeList;
@ -61,9 +62,9 @@ import javax.ws.rs.HeaderParam;
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(
@ -279,8 +280,18 @@ public interface DeviceTypeManagementService {
value = "The device type name, such as ios, android, windows or fire-alarm.",
required = true)
@PathParam("type")
@Size(max = 45)
String type,
@Size(max = 45) String type,
@ApiParam(
name = "featureType",
value = "Type of the feature, such as operation or policy"
)
@QueryParam("featureType")
String featureType,
@ApiParam(
name = "hidden",
value = "true for hidden operations and false for non hidden operations"
)
String hidden,
@ApiParam(
name = "If-Modified-Since",
value = "Checks if the requested variant was modified, since the specified date-time.\n" +

@ -16,6 +16,24 @@
* under the License.
*
*/
/*
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
*
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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;
@ -305,7 +323,9 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
@DELETE
@Override
@Path("/type/{device-type}/id/{device-id}")
public Response deleteDevice(@PathParam("device-type") String deviceType, @PathParam("device-id") String deviceId) {
public Response deleteDevice(@PathParam("device-type") String deviceType,
@PathParam("device-id") String deviceId,
@QueryParam("permanentDelete") boolean permanentDelete) {
DeviceManagementProviderService deviceManagementProviderService =
DeviceMgtAPIUtils.getDeviceManagementService();
try {
@ -315,13 +335,19 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
return Response.status(Response.Status.NOT_FOUND).build();
}
boolean response = deviceManagementProviderService.disenrollDevice(deviceIdentifier);
boolean response;
if (permanentDelete) {
response = deviceManagementProviderService.deleteDevice(deviceIdentifier);
} else {
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);
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()
).build();
@ -447,6 +473,77 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
return Response.status(Response.Status.OK).entity(device).build();
}
@GET
@Path("/type/any/id/{id}")
@Override
public Response getDeviceByID(
@PathParam("id") @Size(max = 45) String id,
@HeaderParam("If-Modified-Since") String ifModifiedSince,
@QueryParam("requireDeviceInfo") boolean requireDeviceInfo) {
Device device;
try {
RequestValidationUtil.validateDeviceIdentifier("any", id);
DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService();
DeviceAccessAuthorizationService deviceAccessAuthorizationService =
DeviceMgtAPIUtils.getDeviceAccessAuthorizationService();
// this is the user who initiates the request
String authorizedUser = CarbonContext.getThreadLocalCarbonContext().getUsername();
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) {
String message = "Error occurred while parse the since date.Invalid date string is provided in " +
"'If-Modified-Since' header";
log.error(message, 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 (sinceDate != null) {
device = dms.getDevice(id, sinceDate, requireDeviceInfo);
if (device == null) {
String message = "No device is modified after the timestamp provided in 'If-Modified-Since' header";
log.error(message);
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(id, requireDeviceInfo);
}
if (device == null) {
String message = "Device does not exist with id '" + id + "'";
log.error(message);
return Response.status(Response.Status.NOT_FOUND).entity(
new ErrorResponse.ErrorResponseBuilder().setCode(404l).setMessage(message).build()).build();
}
DeviceIdentifier deviceIdentifier = new DeviceIdentifier(id, device.getType());
// check whether the user is authorized
if (!deviceAccessAuthorizationService.isUserAuthorized(deviceIdentifier, authorizedUser)) {
String message = "User '" + authorizedUser + "' is not authorized to retrieve the given " +
"device id '" + id + "'";
log.error(message);
return Response.status(Response.Status.UNAUTHORIZED).entity(
new ErrorResponse.ErrorResponseBuilder().setCode(401l).setMessage(message).build()).build();
}
} catch (DeviceManagementException e) {
String message = "Error occurred while fetching the device information.";
log.error(message, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(message).build()).build();
} catch (DeviceAccessAuthorizationException e) {
String message = "Error occurred while checking the device authorization.";
log.error(message, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(message).build()).build();
}
return Response.status(Response.Status.OK).entity(device).build();
}
@GET
@Path("/{type}/{id}/location")
@Override
@ -491,7 +588,7 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
deviceInfo = informationManager.getDeviceInfo(deviceIdentifier);
} catch (DeviceDetailsMgtException e) {
String msg = "Error occurred while getting the device information of id : " + id + " type : " + type ;
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();
@ -681,8 +778,8 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
/**
* Change device status.
*
* @param type Device type
* @param id Device id
* @param type Device type
* @param id Device id
* @param newsStatus Device new status
* @return {@link Response} object
*/
@ -766,7 +863,7 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
String date = new SimpleDateFormat(DATE_FORMAT_NOW).format(new Date());
operation.setCreatedTimeStamp(date);
Activity activity = DeviceMgtAPIUtils.getDeviceManagementService().addOperation(type, operation,
deviceIdentifiers);
deviceIdentifiers);
return Response.status(Response.Status.CREATED).entity(activity).build();
} else {
String message = "Only Command and Config operation is supported through this api";

@ -14,27 +14,28 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
*
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
*
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.device.mgt.common.exceptions.DeviceManagementException;
@ -55,6 +56,7 @@ 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;
@ -107,27 +109,42 @@ public class DeviceTypeManagementServiceImpl implements DeviceTypeManagementServ
@Override
@Path("/{type}/features")
public Response getFeatures(@PathParam("type") @Size(max = 45) String type,
@QueryParam("featureType") String featureType,
@QueryParam("hidden") String hidden,
@HeaderParam("If-Modified-Since") String ifModifiedSince) {
List<Feature> features = new ArrayList<>();
List<Feature> features;
DeviceManagementProviderService dms;
try {
if (StringUtils.isEmpty(type)) {
return Response.status(Response.Status.BAD_REQUEST).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("Type cannot be empty.").build()).build();
}
dms = DeviceMgtAPIUtils.getDeviceManagementService();
FeatureManager fm;
try {
fm = dms.getFeatureManager(type);
} catch (DeviceTypeNotFoundException e) {
FeatureManager fm = dms.getFeatureManager(type);
if (fm == null) {
return Response.status(Response.Status.NOT_FOUND).entity(
new ErrorResponse.ErrorResponseBuilder()
.setMessage("No device type found with name '" + type + "'").build()).build();
new ErrorResponse.ErrorResponseBuilder().setMessage("No feature manager is " +
"registered with the given type '" + type + "'").build()).build();
}
if (fm != null) {
features = fm.getFeatures();
if (StringUtils.isEmpty(hidden)) {
features = fm.getFeatures(featureType);
} else {
features = fm.getFeatures(featureType, Boolean.valueOf(hidden));
}
} catch (DeviceManagementException e) {
String msg = "Error occurred while retrieving the list of features of '" + type + "' device type";
String msg = "Error occurred while retrieving the list of [" + type + "] features with params " +
"{featureType: " + featureType + ", hidden: " + hidden + "}";
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
} catch (DeviceTypeNotFoundException e) {
String msg = "No device type found with name '" + type + "'";
log.error(msg, e);
return Response.status(Response.Status.NOT_FOUND).entity(
new ErrorResponse.ErrorResponseBuilder()
.setMessage(msg).build()).build();
}
return Response.status(Response.Status.OK).entity(features).build();
}

@ -94,6 +94,7 @@ import java.net.URISyntaxException;
import java.security.SecureRandom;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
@ -143,10 +144,16 @@ public class UserManagementServiceImpl implements UserManagementService {
"was refused.").build()).build();
}
String initialUserPassword = this.generateInitialUserPassword();
String initialUserPassword;
if (userInfo.getPassword() != null) {
initialUserPassword = userInfo.getPassword();
} else {
initialUserPassword = this.generateInitialUserPassword();
}
Map<String, String> defaultUserClaims =
this.buildDefaultUserClaims(userInfo.getFirstname(), userInfo.getLastname(),
userInfo.getEmailAddress());
userInfo.getEmailAddress(), true);
// calling addUser method of carbon user api
List<String> tmpRoles = new ArrayList<>();
String[] userInfoRoles = userInfo.getRoles();
@ -273,7 +280,7 @@ public class UserManagementServiceImpl implements UserManagementService {
Map<String, String> defaultUserClaims =
this.buildDefaultUserClaims(userInfo.getFirstname(), userInfo.getLastname(),
userInfo.getEmailAddress());
userInfo.getEmailAddress(), false);
if (StringUtils.isNotEmpty(userInfo.getPassword())) {
// Decoding Base64 encoded password
userStoreManager.updateCredentialByAdmin(username,
@ -421,11 +428,7 @@ public class UserManagementServiceImpl implements UserManagementService {
userList = new ArrayList<>(users.length);
BasicUserInfo user;
for (String username : users) {
user = new BasicUserInfo();
user.setUsername(username);
user.setEmailAddress(getClaimValue(username, Constants.USER_CLAIM_EMAIL_ADDRESS));
user.setFirstname(getClaimValue(username, Constants.USER_CLAIM_FIRST_NAME));
user.setLastname(getClaimValue(username, Constants.USER_CLAIM_LAST_NAME));
user = getBasicUserInfo(username);
userList.add(user);
}
@ -893,11 +896,17 @@ public class UserManagementServiceImpl implements UserManagementService {
}
}
private Map<String, String> buildDefaultUserClaims(String firstName, String lastName, String emailAddress) {
private Map<String, String> buildDefaultUserClaims(String firstName, String lastName, String emailAddress,
boolean isFresh) {
Map<String, String> defaultUserClaims = new HashMap<>();
defaultUserClaims.put(Constants.USER_CLAIM_FIRST_NAME, firstName);
defaultUserClaims.put(Constants.USER_CLAIM_LAST_NAME, lastName);
defaultUserClaims.put(Constants.USER_CLAIM_EMAIL_ADDRESS, emailAddress);
if (isFresh) {
defaultUserClaims.put(Constants.USER_CLAIM_CREATED, String.valueOf(Instant.now().getEpochSecond()));
} else {
defaultUserClaims.put(Constants.USER_CLAIM_MODIFIED, String.valueOf(Instant.now().getEpochSecond()));
}
if (log.isDebugEnabled()) {
log.debug("Default claim map is created for new user: " + defaultUserClaims.toString());
}
@ -930,6 +939,8 @@ public class UserManagementServiceImpl implements UserManagementService {
userInfo.setEmailAddress(getClaimValue(username, Constants.USER_CLAIM_EMAIL_ADDRESS));
userInfo.setFirstname(getClaimValue(username, Constants.USER_CLAIM_FIRST_NAME));
userInfo.setLastname(getClaimValue(username, Constants.USER_CLAIM_LAST_NAME));
userInfo.setCreatedDate(getClaimValue(username, Constants.USER_CLAIM_CREATED));
userInfo.setModifiedDate(getClaimValue(username, Constants.USER_CLAIM_MODIFIED));
return userInfo;
}

@ -26,6 +26,8 @@ public class Constants {
public static final String USER_CLAIM_EMAIL_ADDRESS = "http://wso2.org/claims/emailaddress";
public static final String USER_CLAIM_FIRST_NAME = "http://wso2.org/claims/givenname";
public static final String USER_CLAIM_LAST_NAME = "http://wso2.org/claims/lastname";
public static final String USER_CLAIM_CREATED = "http://wso2.org/claims/created";
public static final String USER_CLAIM_MODIFIED = "http://wso2.org/claims/modified";
public static final String PRIMARY_USER_STORE = "PRIMARY";
public static final String DEFAULT_STREAM_VERSION = "1.0.0";
public static final String SCOPE = "scope";

@ -154,9 +154,9 @@ public class DeviceAgentServiceTest {
public void testEnrollExistingDevice() throws DeviceManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(demoDevice);
Mockito.when(this.deviceManagementProviderService.getDevice((DeviceIdentifier) Mockito.any())).thenReturn(demoDevice);
Device device = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(device);
Mockito.when(this.deviceManagementProviderService.getDevice((DeviceIdentifier) Mockito.any())).thenReturn(device);
Response response = this.deviceAgentService.enrollDevice(device);
Assert.assertNotNull(response, "Response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(),
@ -173,7 +173,7 @@ public class DeviceAgentServiceTest {
EnrolmentInfo enrolmentInfo = demoDevice.getEnrolmentInfo();
enrolmentInfo.setStatus(EnrolmentInfo.Status.INACTIVE);
demoDevice.setEnrolmentInfo(enrolmentInfo);
Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(demoDevice);
Mockito.when(this.deviceManagementProviderService.getDevice((DeviceIdentifier) Mockito.any())).thenReturn(demoDevice);
Response response = this.deviceAgentService.enrollDevice(demoDevice);
Assert.assertNotNull(response, "Response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
@ -191,7 +191,7 @@ public class DeviceAgentServiceTest {
EnrolmentInfo enrolmentInfo = device.getEnrolmentInfo();
enrolmentInfo.setStatus(EnrolmentInfo.Status.INACTIVE);
device.setEnrolmentInfo(enrolmentInfo);
Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(device);
Mockito.when(this.deviceManagementProviderService.getDevice((DeviceIdentifier) Mockito.any())).thenReturn(device);
Mockito.when(this.deviceManagementProviderService.enrollDevice(Mockito.any()))
.thenThrow(new DeviceManagementException());
Response response = this.deviceAgentService.enrollDevice(device);
@ -240,7 +240,7 @@ public class DeviceAgentServiceTest {
public void testUpdateDeviceWithDeviceManagementException() throws DeviceManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenThrow(new
Mockito.when(this.deviceManagementProviderService.getDevice((DeviceIdentifier) Mockito.any())).thenThrow(new
DeviceManagementException());
Device testDevice = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Response response = deviceAgentService.updateDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER, testDevice);
@ -264,7 +264,7 @@ public class DeviceAgentServiceTest {
public void testUpdateDeviceWithNonExistingDevice() throws DeviceManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(null);
Mockito.when(this.deviceManagementProviderService.getDevice((DeviceIdentifier) Mockito.any())).thenReturn(null);
Device testDevice = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Response response = deviceAgentService.updateDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER, testDevice);
Assert.assertNotNull(response, "Response should not be null");
@ -281,7 +281,7 @@ public class DeviceAgentServiceTest {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class,
"getDeviceAccessAuthorizationService")).toReturn(this.deviceAccessAuthorizationService);
Device testDevice = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(testDevice);
Mockito.when(this.deviceManagementProviderService.getDevice((DeviceIdentifier) Mockito.any())).thenReturn(testDevice);
Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class)))
.thenThrow(new DeviceAccessAuthorizationException());
Response response = deviceAgentService.updateDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER, testDevice);
@ -300,7 +300,7 @@ public class DeviceAgentServiceTest {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class,
"getDeviceAccessAuthorizationService")).toReturn(this.deviceAccessAuthorizationService);
Device testDevice = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(testDevice);
Mockito.when(this.deviceManagementProviderService.getDevice((DeviceIdentifier) Mockito.any())).thenReturn(testDevice);
Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class)))
.thenReturn(false);
Response response = deviceAgentService.updateDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER, testDevice);
@ -321,7 +321,7 @@ public class DeviceAgentServiceTest {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class,
"getAuthenticatedUser")).toReturn(AUTHENTICATED_USER);
Device testDevice = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(testDevice);
Mockito.when(this.deviceManagementProviderService.getDevice((DeviceIdentifier) Mockito.any())).thenReturn(testDevice);
Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class)))
.thenReturn(true);
Mockito.when(this.deviceManagementProviderService.modifyEnrollment(Mockito.any())).thenReturn(false);
@ -343,7 +343,7 @@ public class DeviceAgentServiceTest {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class,
"getAuthenticatedUser")).toReturn(AUTHENTICATED_USER);
Device testDevice = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(testDevice);
Mockito.when(this.deviceManagementProviderService.getDevice((DeviceIdentifier) Mockito.any())).thenReturn(testDevice);
Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class)))
.thenReturn(true);
Mockito.when(this.deviceManagementProviderService.modifyEnrollment(Mockito.any()))
@ -365,7 +365,7 @@ public class DeviceAgentServiceTest {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class,
"getAuthenticatedUser")).toReturn(AUTHENTICATED_USER);
Device testDevice = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
Mockito.when(this.deviceManagementProviderService.getDevice(Mockito.any())).thenReturn(testDevice);
Mockito.when(this.deviceManagementProviderService.getDevice((DeviceIdentifier) Mockito.any())).thenReturn(testDevice);
Mockito.when(this.deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class)))
.thenReturn(true);
Mockito.when(this.deviceManagementProviderService.modifyEnrollment(Mockito.any())).thenReturn((true));

@ -1,19 +1,37 @@
/*
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
* 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
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
/*
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
*
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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;
@ -31,6 +49,7 @@ import org.testng.annotations.BeforeClass;
import org.testng.annotations.ObjectFactory;
import org.testng.annotations.Test;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceTypeNotFoundException;
@ -51,13 +70,17 @@ import org.wso2.carbon.device.mgt.core.search.mgt.SearchMgtException;
import org.wso2.carbon.device.mgt.core.search.mgt.impl.SearchManagerServiceImpl;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderServiceImpl;
import org.wso2.carbon.device.mgt.jaxrs.service.api.DeviceAgentService;
import org.wso2.carbon.device.mgt.jaxrs.service.api.DeviceManagementService;
import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.DeviceMgtAPITestHelper;
import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils;
import org.wso2.carbon.policy.mgt.common.PolicyManagementException;
import org.wso2.carbon.policy.mgt.core.PolicyManagerService;
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.UUID;
import javax.ws.rs.core.Response;
@ -74,6 +97,7 @@ import static org.mockito.MockitoAnnotations.initMocks;
public class DeviceManagementServiceImplTest {
private static final Log log = LogFactory.getLog(DeviceManagementServiceImplTest.class);
private static final String TEST_DEVICE_IDENTIFIER = "TEST_DEVICE_IDENTIFIER";
private static final String TEST_DEVICE_TYPE = "TEST-DEVICE-TYPE";
private static final String TEST_DEVICE_NAME = "TEST-DEVICE";
private static final String DEFAULT_USERNAME = "admin";
@ -85,6 +109,7 @@ public class DeviceManagementServiceImplTest {
private DeviceManagementService deviceManagementService;
private DeviceAccessAuthorizationService deviceAccessAuthorizationService;
private DeviceManagementProviderService deviceManagementProviderService;
private static Device demoDevice;
@ObjectFactory
public IObjectFactory getObjectFactory() {
@ -99,6 +124,7 @@ public class DeviceManagementServiceImplTest {
.mock(DeviceManagementProviderServiceImpl.class, Mockito.RETURNS_MOCKS);
this.deviceManagementService = new DeviceManagementServiceImpl();
this.deviceAccessAuthorizationService = Mockito.mock(DeviceAccessAuthorizationServiceImpl.class);
demoDevice = DeviceMgtAPITestHelper.generateDummyDevice(TEST_DEVICE_TYPE, TEST_DEVICE_IDENTIFIER);
}
@Test(description = "Testing if the device is enrolled when the device is enrolled.")
@ -180,6 +206,103 @@ public class DeviceManagementServiceImplTest {
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode());
}
@Test(description = "Testing get devices by identifier with correct request.")
public void testGetDeviceByID() throws DeviceAccessAuthorizationException {
String ifModifiedSince = new SimpleDateFormat(DEFAULT_DATE_FORMAT).format(new Date());
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getAuthenticatedUser"))
.toReturn(DEFAULT_USERNAME);
CarbonContext carbonContext = Mockito.mock(CarbonContext.class, Mockito.RETURNS_MOCKS);
DeviceAccessAuthorizationService deviceAccessAuthorizationService =
Mockito.mock(DeviceAccessAuthorizationService.class, Mockito.RETURNS_MOCKS);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class,
"getDeviceAccessAuthorizationService"))
.toReturn(deviceAccessAuthorizationService);
PowerMockito.stub(PowerMockito.method(CarbonContext.class, "getThreadLocalCarbonContext"))
.toReturn(carbonContext);
Mockito.when(carbonContext.getTenantId()).thenReturn(-1234);
Mockito.when(carbonContext.getUsername()).thenReturn(DEFAULT_USERNAME);
Mockito.when(deviceAccessAuthorizationService.isUserAuthorized(Mockito.any(DeviceIdentifier.class),
Mockito.anyString())).thenReturn(true);
Response response = this.deviceManagementService
.getDeviceByID(TEST_DEVICE_IDENTIFIER, ifModifiedSince,true);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode());
response = this.deviceManagementService
.getDeviceByID(TEST_DEVICE_IDENTIFIER, null,true);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode());
}
@Test(description = "Testing get devices by identifier when unauthorized user.")
public void testGetDeviceByIDWithErroneousUnauthorizedException()
throws DeviceAccessAuthorizationException {
String ifModifiedSince = new SimpleDateFormat(DEFAULT_DATE_FORMAT).format(new Date());
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getAuthenticatedUser"))
.toReturn(DEFAULT_USERNAME);
CarbonContext carbonContext = Mockito.mock(CarbonContext.class, Mockito.RETURNS_MOCKS);
DeviceAccessAuthorizationService deviceAccessAuthorizationService =
Mockito.mock(DeviceAccessAuthorizationService.class, Mockito.RETURNS_MOCKS);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class,
"getDeviceAccessAuthorizationService"))
.toReturn(deviceAccessAuthorizationService);
PowerMockito.stub(PowerMockito.method(CarbonContext.class, "getThreadLocalCarbonContext"))
.toReturn(carbonContext);
Mockito.when(carbonContext.getTenantId()).thenReturn(-1234);
Mockito.when(carbonContext.getUsername()).thenReturn(DEFAULT_USERNAME);
Mockito.when(deviceAccessAuthorizationService.isDeviceAdminUser()).thenReturn(false);
Response response = this.deviceManagementService
.getDeviceByID(TEST_DEVICE_IDENTIFIER, ifModifiedSince,true);
Assert.assertEquals(response.getStatus(), Response.Status.UNAUTHORIZED.getStatusCode());
}
@Test(description = "Testing get device when DeviceAccessAuthorizationService is not available",
expectedExceptions = ExceptionInInitializerError.class)
public void testGetDeviceByIDWithErroneousDeviceAccessAuthorizationService()
throws DeviceAccessAuthorizationException {
String ifModifiedSince = new SimpleDateFormat(DEFAULT_DATE_FORMAT).format(new Date());
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getAuthenticatedUser"))
.toReturn(DEFAULT_USERNAME);
CarbonContext carbonContext = Mockito.mock(CarbonContext.class, Mockito.RETURNS_MOCKS);
PowerMockito.stub(PowerMockito.method(CarbonContext.class, "getThreadLocalCarbonContext"))
.toReturn(carbonContext);
Mockito.when(carbonContext.getTenantId()).thenReturn(-1234);
Mockito.when(carbonContext.getUsername()).thenReturn(DEFAULT_USERNAME);
Mockito.when(deviceAccessAuthorizationService.isDeviceAdminUser()).thenReturn(true);
this.deviceManagementService.getDeviceByID(TEST_DEVICE_IDENTIFIER, ifModifiedSince,true);
}
@Test(description = "Testing get device when DeviceManagementProviderService is not available",
expectedExceptions = NoClassDefFoundError.class)
public void testGetDeviceByIDWithErroneousDeviceManagementProviderService()
throws DeviceAccessAuthorizationException {
String ifModifiedSince = new SimpleDateFormat(DEFAULT_DATE_FORMAT).format(new Date());
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getAuthenticatedUser"))
.toReturn(DEFAULT_USERNAME);
CarbonContext carbonContext = Mockito.mock(CarbonContext.class, Mockito.RETURNS_MOCKS);
DeviceAccessAuthorizationService deviceAccessAuthorizationService =
Mockito.mock(DeviceAccessAuthorizationService.class, Mockito.RETURNS_MOCKS);
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class,
"getDeviceAccessAuthorizationService"))
.toReturn(deviceAccessAuthorizationService);
PowerMockito.stub(PowerMockito.method(CarbonContext.class, "getThreadLocalCarbonContext"))
.toReturn(carbonContext);
Mockito.when(carbonContext.getTenantId()).thenReturn(-1234);
Mockito.when(carbonContext.getUsername()).thenReturn(DEFAULT_USERNAME);
Mockito.when(deviceAccessAuthorizationService.isDeviceAdminUser()).thenReturn(true);
this.deviceManagementService.getDeviceByID(TEST_DEVICE_IDENTIFIER, ifModifiedSince,true);
}
@Test(description = "Testing get devices when DeviceAccessAuthorizationService is not available")
public void testGetDevicesWithErroneousDeviceAccessAuthorizationService() {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
@ -358,7 +481,8 @@ public class DeviceManagementServiceImplTest {
public void testDeleteDevice() {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Response response = this.deviceManagementService.deleteDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString());
Response response = this.deviceManagementService.deleteDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString()
, false);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode());
}
@ -368,7 +492,8 @@ public class DeviceManagementServiceImplTest {
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService
.getDevice(Mockito.any(DeviceIdentifier.class), Mockito.anyBoolean())).thenReturn(null);
Response response = this.deviceManagementService.deleteDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString());
Response response = this.deviceManagementService.deleteDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString()
, false);
Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode());
Mockito.reset(this.deviceManagementProviderService);
}
@ -379,7 +504,8 @@ public class DeviceManagementServiceImplTest {
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService.disenrollDevice(Mockito.any(DeviceIdentifier.class)))
.thenThrow(new DeviceManagementException());
Response response = this.deviceManagementService.deleteDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString());
Response response = this.deviceManagementService.deleteDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString()
, false);
Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode());
Mockito.reset(this.deviceManagementProviderService);
}

@ -113,7 +113,7 @@ public class DeviceTypeManagementServiceTest {
public void testGetDeviceTypeFeatures() throws Exception {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Response response = this.deviceTypeManagementService.getFeatures(TEST_DEVICE_TYPE, MODIFIED_SINCE);
Response response = this.deviceTypeManagementService.getFeatures(TEST_DEVICE_TYPE, null, "false", MODIFIED_SINCE);
Assert.assertNotNull(response, "The response object is null.");
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
"The response status should be 200.");
@ -126,8 +126,9 @@ public class DeviceTypeManagementServiceTest {
FeatureManager featureManager = Mockito.mock(FeatureManager.class);
Mockito.when(this.deviceManagementProviderService.getFeatureManager(Mockito.anyString())).thenReturn
(featureManager);
Mockito.when((featureManager).getFeatures()).thenThrow(new DeviceManagementException());
Response response = this.deviceTypeManagementService.getFeatures(TEST_DEVICE_TYPE, MODIFIED_SINCE);
Mockito.when((featureManager).getFeatures(Mockito.anyString())).thenThrow(new DeviceManagementException());
Mockito.when((featureManager).getFeatures(Mockito.anyString(), Mockito.anyBoolean())).thenThrow(new DeviceManagementException());
Response response = this.deviceTypeManagementService.getFeatures(TEST_DEVICE_TYPE, null, "false", MODIFIED_SINCE);
Assert.assertNotNull(response, "The response object is null.");
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"The response status should be 500.");
@ -140,11 +141,10 @@ public class DeviceTypeManagementServiceTest {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService.getFeatureManager(Mockito.anyString())).thenReturn(null);
Response response = this.deviceTypeManagementService.getFeatures(TEST_DEVICE_TYPE, MODIFIED_SINCE);
Response response = this.deviceTypeManagementService.getFeatures(TEST_DEVICE_TYPE, null, "false", MODIFIED_SINCE);
Assert.assertNotNull(response, "The response object is null.");
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
"The response status should be 200.");
Assert.assertEquals(response.getEntity().toString(), "[]", "The response should be [].");
Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode(),
"The response status should be 404.");
Mockito.reset(deviceManagementProviderService);
}

@ -21,7 +21,7 @@
<parent>
<artifactId>device-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -15,32 +15,92 @@
* specific language governing permissions and limitations
* under the License.
*/
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.common;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import java.io.Serializable;
import java.util.List;
import io.swagger.annotations.*;
@ApiModel(value = "Feature", description = "This class carries all information related to a devices enrollment" +
" status.")
@ApiModel(
value = "Feature",
description = "This class carries all information related to a device feature."
)
public class Feature implements Serializable {
@ApiModelProperty(name = "id", value = "Feature Id.", required = true )
@ApiModelProperty(
name = "id",
value = "Feature Id.",
required = true
)
private int id;
@ApiModelProperty(name = "code", value = "The code of the feature. For example the code to lock a device" +
" is DEVICE_LOCK.", required = true )
@ApiModelProperty(
name = "code",
value = "The code of the feature. For example the code to lock a device is DEVICE_LOCK.",
required = true
)
private String code;
@ApiModelProperty(name = "name", value = "A name that describes a feature.", required = true )
@ApiModelProperty(
name = "name",
value = "A name that describes a feature.",
required = true
)
private String name;
@ApiModelProperty(name = "description", value = "Provides a description of the features..", required = true )
@ApiModelProperty(
name = "description",
value = "Provides a description of the features.",
required = true
)
private String description;
@ApiModelProperty(name = "deviceType", value = "Provide the device type for the respective feature. " +
"Features allow you to perform operations on any device type, " +
"such as android, iOS or windows..", required = true )
@ApiModelProperty(
name = "type",
value = "Type of the feature.",
required = true
)
private String type;
@ApiModelProperty(
name = "hidden",
value = "If the feature is hidden from the UI."
)
private boolean hidden;
@ApiModelProperty(
name = "deviceType",
value = "Provide the device type for the respective feature. Features allow you to perform operations " +
"on any device type, such as android, iOS or windows.",
required = true
)
private String deviceType;
@ApiModelProperty(name = "metadataEntries", value = "Properties related to features.", required = true )
@ApiModelProperty(
name = "metadataEntries",
value = "Properties related to features.",
required = true
)
private List<MetadataEntry> metadataEntries;
@XmlElement
@ -96,9 +156,27 @@ public class Feature implements Serializable {
this.description = description;
}
@XmlAttribute
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public boolean isHidden() {
return hidden;
}
public void setHidden(boolean hidden) {
this.hidden = hidden;
}
public static class MetadataEntry implements Serializable {
private int id;
private String name;
private Object value;
public int getId() {
@ -109,6 +187,14 @@ public class Feature implements Serializable {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object getValue() {
return value;
}

@ -14,7 +14,24 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.common;
@ -32,6 +49,10 @@ public interface FeatureManager {
List<Feature> getFeatures() throws DeviceManagementException;
List<Feature> getFeatures(String type) throws DeviceManagementException;
List<Feature> getFeatures(String type, boolean isHidden) throws DeviceManagementException;
boolean removeFeature(String name) throws DeviceManagementException;
boolean addSupportedFeaturesToDB() throws DeviceManagementException;

@ -0,0 +1,33 @@
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.common;
import java.util.List;
public class StartupOperationConfig {
private List<String> startupOperations;
public List<String> getStartupOperations() {
return startupOperations;
}
public void setStartupOperations(List<String> startupOperations) {
this.startupOperations = startupOperations;
}
}

@ -15,6 +15,22 @@
* specific language governing permissions and limitations
* under the License.
*
*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.common.spi;
@ -51,6 +67,8 @@ public interface DeviceManagementService {
InitialOperationConfig getInitialOperationConfig();
StartupOperationConfig getStartupOperationConfig();
PullNotificationSubscriber getPullNotificationSubscriber();
DeviceStatusTaskPluginConfig getDeviceStatusTaskPluginConfig();

@ -22,7 +22,7 @@
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>device-mgt</artifactId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -15,6 +15,23 @@
* specific language governing permissions and limitations
* under the License.
*/
/*
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
*
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.core.dao;
@ -128,6 +145,17 @@ public interface DeviceDAO {
*/
Device getDevice(DeviceIdentifier deviceIdentifier, int tenantId) throws DeviceManagementDAOException;
/**
* This method is used to retrieve a device of a given device-identifier and tenant-id.
*
* @param deviceIdentifier device id.
* @param tenantId tenant id.
* @return returns the device object.
* @throws DeviceManagementDAOException
*/
Device getDevice(String deviceIdentifier, int tenantId) throws DeviceManagementDAOException;
/**
* This method is used to retrieve a device of a given device-identifier and owner and tenant-id.
*
@ -152,6 +180,19 @@ public interface DeviceDAO {
Device getDevice(DeviceIdentifier deviceIdentifier, Date ifModifiedSince, int tenantId) throws
DeviceManagementDAOException;
/**
* This method is used to retrieve a device of a given device-identifier and tenant-id which modified
* later than the ifModifiedSince param.
*
* @param deviceIdentifier device id.
* @param ifModifiedSince last modified time.
* @param tenantId tenant id.
* @return returns the device object.
* @throws DeviceManagementDAOException
*/
Device getDevice(String deviceIdentifier, Date ifModifiedSince, int tenantId) throws
DeviceManagementDAOException;
/**
* This method is used to retrieve a device of a given device-identifier and owner and tenant-id which modified
* later than the ifModifiedSince param.
@ -437,5 +478,13 @@ public interface DeviceDAO {
* fails.
*/
List<Device> getDevicesByIdentifiers(List<String> deviceIdentifiers, int tenantId) throws DeviceManagementDAOException;
/**
* This method is used to permanently delete the device and its related details
* @param deviceIdentifier device id
* @param tenantId tenant id
* @throws DeviceManagementDAOException
*/
void deleteDevice(DeviceIdentifier deviceIdentifier, int tenantId) throws DeviceManagementDAOException;
}

@ -1,23 +1,42 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
* 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
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
/*
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
*
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.core.dao.impl;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
@ -44,6 +63,8 @@ import java.util.StringJoiner;
public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
private static final org.apache.commons.logging.Log log = LogFactory.getLog(AbstractDeviceDAOImpl.class);
@Override
public int addDevice(int typeId, Device device, int tenantId) throws DeviceManagementDAOException {
Connection conn;
@ -55,7 +76,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
String sql = "INSERT INTO DM_DEVICE(DESCRIPTION, NAME, DEVICE_TYPE_ID, DEVICE_IDENTIFICATION, " +
"LAST_UPDATED_TIMESTAMP, TENANT_ID) " +
"VALUES (?, ?, ?, ?, ?, ?)";
stmt = conn.prepareStatement(sql, new String[] {"id"});
stmt = conn.prepareStatement(sql, new String[]{"id"});
stmt.setString(1, device.getDescription());
stmt.setString(2, device.getName());
stmt.setInt(3, typeId);
@ -87,7 +108,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
String sql = "UPDATE DM_DEVICE SET NAME = ?, DESCRIPTION = ?, LAST_UPDATED_TIMESTAMP = ? " +
"WHERE DEVICE_TYPE_ID = (SELECT ID FROM DM_DEVICE_TYPE WHERE NAME = ? AND (PROVIDER_TENANT_ID = ? OR SHARED_WITH_ALL_TENANTS = ?)) " +
"AND DEVICE_IDENTIFICATION = ? AND TENANT_ID = ?";
stmt = conn.prepareStatement(sql, new String[] {"id"});
stmt = conn.prepareStatement(sql, new String[]{"id"});
stmt.setString(1, device.getName());
stmt.setString(2, device.getDescription());
stmt.setTimestamp(3, new Timestamp(new Date().getTime()));
@ -145,6 +166,53 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
return device;
}
@Override
public Device getDevice(String deviceIdentifier, int tenantId) throws DeviceManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
ResultSet rs = null;
Device device = null;
try {
conn = this.getConnection();
String sql = "SELECT " +
"d1.ID AS DEVICE_ID, d1.DESCRIPTION, d1.NAME AS DEVICE_NAME, d1.DEVICE_TYPE, " +
"d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " +
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID " +
"FROM " +
"DM_ENROLMENT e," +
" (SELECT d.ID, d.DESCRIPTION, d.NAME, t.NAME AS DEVICE_TYPE, d.DEVICE_IDENTIFICATION " +
"FROM " +
"DM_DEVICE d, DM_DEVICE_TYPE t " +
"WHERE " +
"t.ID = d.DEVICE_TYPE_ID AND d.DEVICE_IDENTIFICATION = ? AND d.TENANT_ID = ?) d1 " +
"WHERE " +
"d1.ID = e.DEVICE_ID " +
"AND TENANT_ID = ? " +
"ORDER BY e.DATE_OF_LAST_UPDATE DESC, e.STATUS ASC";
// Status adeed as an orderby clause to fix a bug : when an existing device is
// re-enrolled, earlier enrollment is marked as removed and a new enrollment is added.
// However, both enrollments share the same time stamp. When retrieving the device
// due to same timestamp, enrollment information is incorrect, intermittently. Hence
// status also should be taken into consideration when ordering. This should not present a
// problem for other status transitions, as there would be an intermediary removed
// state in between.
stmt = conn.prepareStatement(sql);
stmt.setString(1, deviceIdentifier);
stmt.setInt(2, tenantId);
stmt.setInt(3, tenantId);
rs = stmt.executeQuery();
if (rs.next()) {
device = DeviceManagementDAOUtil.loadMatchingDevice(rs, false);
}
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while listing device " +
"'" + deviceIdentifier + "'", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
return device;
}
@Override
public Device getDevice(DeviceIdentifier deviceIdentifier, String owner, int tenantId)
throws DeviceManagementDAOException {
@ -181,7 +249,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
@Override
public Device getDevice(DeviceIdentifier deviceIdentifier, Date since, int tenantId)
throws DeviceManagementDAOException {
throws DeviceManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
ResultSet rs = null;
@ -189,11 +257,11 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
try {
conn = this.getConnection();
String sql = "SELECT d1.ID AS DEVICE_ID, d1.DESCRIPTION, d1.NAME AS DEVICE_NAME, d1.DEVICE_TYPE, " +
"d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " +
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, (SELECT d.ID, d.DESCRIPTION, d.NAME, " +
"t.NAME AS DEVICE_TYPE, d.DEVICE_IDENTIFICATION FROM DM_DEVICE d, DM_DEVICE_TYPE t, DM_DEVICE_DETAIL dt " +
"WHERE t.NAME = ? AND t.ID = d.DEVICE_TYPE_ID AND d.DEVICE_IDENTIFICATION = ? AND d.TENANT_ID = ? AND dt.DEVICE_ID = d.ID " +
"AND dt.UPDATE_TIMESTAMP > ?) d1 WHERE d1.ID = e.DEVICE_ID AND TENANT_ID = ? ORDER BY e.DATE_OF_LAST_UPDATE DESC" ;
"d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " +
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, (SELECT d.ID, d.DESCRIPTION, d.NAME, " +
"t.NAME AS DEVICE_TYPE, d.DEVICE_IDENTIFICATION FROM DM_DEVICE d, DM_DEVICE_TYPE t, DM_DEVICE_DETAIL dt " +
"WHERE t.NAME = ? AND t.ID = d.DEVICE_TYPE_ID AND d.DEVICE_IDENTIFICATION = ? AND d.TENANT_ID = ? AND dt.DEVICE_ID = d.ID " +
"AND dt.UPDATE_TIMESTAMP > ?) d1 WHERE d1.ID = e.DEVICE_ID AND TENANT_ID = ? ORDER BY e.DATE_OF_LAST_UPDATE DESC";
stmt = conn.prepareStatement(sql);
int paramIdx = 1;
stmt.setString(paramIdx++, deviceIdentifier.getType());
@ -207,7 +275,52 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
}
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while listing device for type " +
"'" + deviceIdentifier.getType() + "'", e);
"'" + deviceIdentifier.getType() + "'", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
return device;
}
@Override
public Device getDevice(String deviceIdentifier, Date since, int tenantId)
throws DeviceManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
ResultSet rs = null;
Device device = null;
try {
conn = this.getConnection();
String sql = "SELECT d1.ID AS DEVICE_ID, d1.DESCRIPTION, d1.NAME AS DEVICE_NAME, d1.DEVICE_TYPE, " +
"d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " +
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID " +
"FROM" +
" DM_ENROLMENT e, " +
"(SELECT d.ID, d.DESCRIPTION, d.NAME, " +
"t.NAME AS DEVICE_TYPE, d.DEVICE_IDENTIFICATION " +
"FROM" +
" DM_DEVICE d, DM_DEVICE_TYPE t," +
" DM_DEVICE_DETAIL dt " +
"WHERE " +
"t.ID = d.DEVICE_TYPE_ID AND d.DEVICE_IDENTIFICATION = ? AND d.TENANT_ID = ? AND" +
" dt.DEVICE_ID = d.ID AND dt.UPDATE_TIMESTAMP > ?) d1 " +
"WHERE" +
" d1.ID = e.DEVICE_ID AND TENANT_ID = ? " +
"ORDER BY " +
"e.DATE_OF_LAST_UPDATE DESC";
stmt = conn.prepareStatement(sql);
int paramIdx = 1;
stmt.setString(paramIdx++, deviceIdentifier);
stmt.setInt(paramIdx++, tenantId);
stmt.setLong(paramIdx++, since.getTime());
stmt.setInt(paramIdx, tenantId);
rs = stmt.executeQuery();
if (rs.next()) {
device = DeviceManagementDAOUtil.loadMatchingDevice(rs, false);
}
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while listing device for id " +
"'" + deviceIdentifier + "'", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
@ -228,7 +341,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, (SELECT d.ID, d.DESCRIPTION, d.NAME, " +
"t.NAME AS DEVICE_TYPE, d.DEVICE_IDENTIFICATION FROM DM_DEVICE d, DM_DEVICE_TYPE t, DM_DEVICE_DETAIL dt " +
"WHERE t.NAME = ? AND t.ID = d.DEVICE_TYPE_ID AND d.DEVICE_IDENTIFICATION = ? AND d.TENANT_ID = ? AND dt.DEVICE_ID = d.ID " +
"AND dt.UPDATE_TIMESTAMP > ?) d1 WHERE d1.ID = e.DEVICE_ID AND TENANT_ID = ? AND e.OWNER = ?" ;
"AND dt.UPDATE_TIMESTAMP > ?) d1 WHERE d1.ID = e.DEVICE_ID AND TENANT_ID = ? AND e.OWNER = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, deviceIdentifier.getType());
stmt.setString(2, deviceIdentifier.getId());
@ -250,8 +363,8 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
}
@Override
public Device getDevice(DeviceIdentifier deviceIdentifier, EnrolmentInfo.Status status, int tenantId) throws
DeviceManagementDAOException {
public Device getDevice(DeviceIdentifier deviceIdentifier, EnrolmentInfo.Status status, int tenantId)
throws DeviceManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
ResultSet rs = null;
@ -259,11 +372,11 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
try {
conn = this.getConnection();
String sql = "SELECT d1.ID AS DEVICE_ID, d1.DESCRIPTION, d1.NAME AS DEVICE_NAME, d1.DEVICE_TYPE, " +
"d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " +
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, (SELECT d.ID, d.DESCRIPTION, d.NAME, " +
"t.NAME AS DEVICE_TYPE, d.DEVICE_IDENTIFICATION FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE " +
"t.NAME = ? AND t.ID = d.DEVICE_TYPE_ID AND d.DEVICE_IDENTIFICATION = ? AND d.TENANT_ID = ?) d1 WHERE d1.ID = e.DEVICE_ID " +
"AND TENANT_ID = ? AND e.STATUS = ? ORDER BY e.DATE_OF_LAST_UPDATE DESC";
"d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " +
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, (SELECT d.ID, d.DESCRIPTION, d.NAME, " +
"t.NAME AS DEVICE_TYPE, d.DEVICE_IDENTIFICATION FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE " +
"t.NAME = ? AND t.ID = d.DEVICE_TYPE_ID AND d.DEVICE_IDENTIFICATION = ? AND d.TENANT_ID = ?) d1 WHERE d1.ID = e.DEVICE_ID " +
"AND TENANT_ID = ? AND e.STATUS = ? ORDER BY e.DATE_OF_LAST_UPDATE DESC";
stmt = conn.prepareStatement(sql);
stmt.setString(1, deviceIdentifier.getType());
stmt.setString(2, deviceIdentifier.getId());
@ -276,7 +389,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
}
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while listing devices for type " +
"'" + deviceIdentifier.getType() + "'", e);
"'" + deviceIdentifier.getType() + "'", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
@ -293,13 +406,13 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
try {
conn = this.getConnection();
String sql = "SELECT d1.ID AS DEVICE_ID, d1.DESCRIPTION, d1.NAME AS DEVICE_NAME, d1.DEVICE_TYPE, e.TENANT_ID, " +
"d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " +
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, (SELECT d.ID, d.DESCRIPTION, d.NAME, " +
"t.NAME AS DEVICE_TYPE, d.DEVICE_IDENTIFICATION FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE " +
"t.NAME = ? AND t.ID = d.DEVICE_TYPE_ID AND d.DEVICE_IDENTIFICATION = ? ) d1 WHERE d1.ID = e.DEVICE_ID ORDER BY e.DATE_OF_LAST_UPDATE DESC";
stmt = conn.prepareStatement(sql);
stmt.setString(1, deviceIdentifier.getType());
stmt.setString(2, deviceIdentifier.getId());
"d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " +
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, (SELECT d.ID, d.DESCRIPTION, d.NAME, " +
"t.NAME AS DEVICE_TYPE, d.DEVICE_IDENTIFICATION FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE " +
"t.NAME = ? AND t.ID = d.DEVICE_TYPE_ID AND d.DEVICE_IDENTIFICATION = ? ) d1 WHERE d1.ID = e.DEVICE_ID ORDER BY e.DATE_OF_LAST_UPDATE DESC";
stmt = conn.prepareStatement(sql);
stmt.setString(1, deviceIdentifier.getType());
stmt.setString(2, deviceIdentifier.getId());
rs = stmt.executeQuery();
if (rs.next()) {
device = DeviceManagementDAOUtil.loadDevice(rs);
@ -323,11 +436,11 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
try {
conn = this.getConnection();
String sql = "SELECT d1.ID AS DEVICE_ID, d1.DESCRIPTION, d1.NAME AS DEVICE_NAME, d1.DEVICE_TYPE, " +
"d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " +
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, (SELECT d.ID, d.DESCRIPTION, d.NAME, " +
"t.NAME AS DEVICE_TYPE, d.DEVICE_IDENTIFICATION FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE " +
"d.ID = ? AND t.ID = d.DEVICE_TYPE_ID AND d.TENANT_ID = ?) d1 WHERE d1.ID = e.DEVICE_ID " +
"AND TENANT_ID = ? ORDER BY e.DATE_OF_LAST_UPDATE DESC";
"d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " +
"e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, (SELECT d.ID, d.DESCRIPTION, d.NAME, " +
"t.NAME AS DEVICE_TYPE, d.DEVICE_IDENTIFICATION FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE " +
"d.ID = ? AND t.ID = d.DEVICE_TYPE_ID AND d.TENANT_ID = ?) d1 WHERE d1.ID = e.DEVICE_ID " +
"AND TENANT_ID = ? ORDER BY e.DATE_OF_LAST_UPDATE DESC";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, deviceId);
stmt.setInt(2, tenantId);
@ -338,7 +451,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
}
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while retrieving device for id " +
"'" + deviceId + "'", e);
"'" + deviceId + "'", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
@ -421,11 +534,11 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
try {
conn = this.getConnection();
String sql = "SELECT e1.OWNER, e1.OWNERSHIP, e1.ENROLMENT_ID, e1.DEVICE_ID, e1.STATUS, e1.DATE_OF_LAST_UPDATE," +
" e1.DATE_OF_ENROLMENT, d.DESCRIPTION, d.NAME AS DEVICE_NAME, d.DEVICE_IDENTIFICATION, t.NAME " +
"AS DEVICE_TYPE FROM DM_DEVICE d, (SELECT e.OWNER, e.OWNERSHIP, e.ID AS ENROLMENT_ID, " +
"e.DEVICE_ID, e.STATUS, e.DATE_OF_LAST_UPDATE, e.DATE_OF_ENROLMENT FROM DM_ENROLMENT e WHERE " +
"e.TENANT_ID = ? AND LOWER(e.OWNER) = LOWER(?) ORDER BY e.DATE_OF_LAST_UPDATE DESC) e1, DM_DEVICE_TYPE t WHERE d.ID = e1.DEVICE_ID " +
"AND t.ID = d.DEVICE_TYPE_ID";
" e1.DATE_OF_ENROLMENT, d.DESCRIPTION, d.NAME AS DEVICE_NAME, d.DEVICE_IDENTIFICATION, t.NAME " +
"AS DEVICE_TYPE FROM DM_DEVICE d, (SELECT e.OWNER, e.OWNERSHIP, e.ID AS ENROLMENT_ID, " +
"e.DEVICE_ID, e.STATUS, e.DATE_OF_LAST_UPDATE, e.DATE_OF_ENROLMENT FROM DM_ENROLMENT e WHERE " +
"e.TENANT_ID = ? AND LOWER(e.OWNER) = LOWER(?) ORDER BY e.DATE_OF_LAST_UPDATE DESC) e1, DM_DEVICE_TYPE t WHERE d.ID = e1.DEVICE_ID " +
"AND t.ID = d.DEVICE_TYPE_ID";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, tenantId);
stmt.setString(2, username);
@ -497,8 +610,8 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
try {
conn = this.getConnection();
String sql = "SELECT COUNT(d1.DEVICE_ID) AS DEVICE_COUNT FROM DM_ENROLMENT e, (SELECT d.ID AS DEVICE_ID FROM " +
"DM_DEVICE d, DM_DEVICE_TYPE t WHERE d.DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ?) d1 WHERE " +
"d1.DEVICE_ID = e.DEVICE_ID AND LOWER(e.OWNER) = LOWER(?) AND TENANT_ID = ?";
"DM_DEVICE d, DM_DEVICE_TYPE t WHERE d.DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ?) d1 WHERE " +
"d1.DEVICE_ID = e.DEVICE_ID AND LOWER(e.OWNER) = LOWER(?) AND TENANT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, tenantId);
stmt.setString(2, username);
@ -580,7 +693,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
@Override
public boolean setEnrolmentStatusInBulk(String deviceType, String status,
int tenantId, List<String> devices) throws DeviceManagementDAOException {
int tenantId, List<String> devices) throws DeviceManagementDAOException {
Connection conn;
PreparedStatement stmt = null;
try {
@ -625,8 +738,8 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
try {
conn = this.getConnection();
String sql = "SELECT COUNT(d1.DEVICE_ID) AS DEVICE_COUNT FROM DM_ENROLMENT e, (SELECT d.ID AS DEVICE_ID FROM " +
"DM_DEVICE d, DM_DEVICE_TYPE t WHERE d.DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ?) d1 WHERE " +
"d1.DEVICE_ID = e.DEVICE_ID AND TENANT_ID = ?";
"DM_DEVICE d, DM_DEVICE_TYPE t WHERE d.DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ?) d1 WHERE " +
"d1.DEVICE_ID = e.DEVICE_ID AND TENANT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, tenantId);
stmt.setInt(2, tenantId);
@ -665,7 +778,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
try {
conn = this.getConnection();
String sql = "SELECT COUNT(d1.ID) AS DEVICE_COUNT FROM DM_ENROLMENT e, (SELECT d.ID, d.NAME, d.DEVICE_IDENTIFICATION, " +
"t.NAME AS DEVICE_TYPE FROM DM_DEVICE d, DM_DEVICE_TYPE t";
"t.NAME AS DEVICE_TYPE FROM DM_DEVICE d, DM_DEVICE_TYPE t";
//Add query for last updated timestamp
if (since != null) {
@ -739,7 +852,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
}
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while retrieving information of all " +
"registered devices", e);
"registered devices", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
@ -755,8 +868,8 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
try {
conn = this.getConnection();
String sql = "SELECT COUNT(d1.ID) AS DEVICE_COUNT FROM DM_ENROLMENT e, (SELECT d.ID FROM DM_DEVICE d, " +
"DM_DEVICE_TYPE t WHERE DEVICE_TYPE_ID = t.ID AND t.NAME = ? " +
"AND d.TENANT_ID = ?) d1 WHERE d1.ID = e.DEVICE_ID AND TENANT_ID = ?";
"DM_DEVICE_TYPE t WHERE DEVICE_TYPE_ID = t.ID AND t.NAME = ? " +
"AND d.TENANT_ID = ?) d1 WHERE d1.ID = e.DEVICE_ID AND TENANT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, type);
stmt.setInt(2, tenantId);
@ -781,8 +894,8 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
try {
conn = this.getConnection();
String sql = "SELECT COUNT(e1.DEVICE_ID) AS DEVICE_COUNT FROM DM_DEVICE d, (SELECT e.DEVICE_ID " +
"FROM DM_ENROLMENT e WHERE e.TENANT_ID = ? AND LOWER(e.OWNER) = LOWER(?)) " +
"e1, DM_DEVICE_TYPE t WHERE d.ID = e1.DEVICE_ID AND t.ID = d.DEVICE_TYPE_ID";
"FROM DM_ENROLMENT e WHERE e.TENANT_ID = ? AND LOWER(e.OWNER) = LOWER(?)) " +
"e1, DM_DEVICE_TYPE t WHERE d.ID = e1.DEVICE_ID AND t.ID = d.DEVICE_TYPE_ID";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, tenantId);
stmt.setString(2, username);
@ -793,7 +906,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
}
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while fetching the list of devices belongs to '" +
username + "'", e);
username + "'", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, null);
}
@ -808,8 +921,8 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
try {
conn = this.getConnection();
String sql = "SELECT COUNT(d1.ID) AS DEVICE_COUNT FROM DM_ENROLMENT e, (SELECT d.ID FROM DM_DEVICE d, " +
"DM_DEVICE_TYPE t WHERE d.DEVICE_TYPE_ID = t.ID AND d.NAME LIKE ? AND d.TENANT_ID = ?) d1 " +
"WHERE d1.ID = e.DEVICE_ID AND TENANT_ID = ?";
"DM_DEVICE_TYPE t WHERE d.DEVICE_TYPE_ID = t.ID AND d.NAME LIKE ? AND d.TENANT_ID = ?) d1 " +
"WHERE d1.ID = e.DEVICE_ID AND TENANT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, deviceName + "%");
stmt.setInt(2, tenantId);
@ -821,7 +934,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
}
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while fetching the device count that matches " +
"'" + deviceName + "'", e);
"'" + deviceName + "'", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, null);
}
@ -836,8 +949,8 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
try {
conn = this.getConnection();
String sql = "SELECT COUNT(d.ID) AS DEVICE_COUNT FROM (SELECT e.DEVICE_ID FROM DM_ENROLMENT e WHERE " +
"TENANT_ID = ? AND OWNERSHIP = ?) e, DM_DEVICE d, " +
"DM_DEVICE_TYPE t WHERE d.ID = e.DEVICE_ID AND d.DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ?";
"TENANT_ID = ? AND OWNERSHIP = ?) e, DM_DEVICE d, " +
"DM_DEVICE_TYPE t WHERE d.ID = e.DEVICE_ID AND d.DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, tenantId);
stmt.setString(2, ownerShip);
@ -849,7 +962,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
}
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while fetching the list of devices that matches to ownership " +
"'" + ownerShip + "'", e);
"'" + ownerShip + "'", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, null);
}
@ -923,7 +1036,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
conn = this.getConnection();
String sql = "INSERT INTO DM_ENROLMENT(DEVICE_ID, OWNER, OWNERSHIP, STATUS,DATE_OF_ENROLMENT, " +
"DATE_OF_LAST_UPDATE, TENANT_ID) VALUES(?, ?, ?, ?, ?, ?, ?)";
stmt = conn.prepareStatement(sql, new String[] {"id"});
stmt = conn.prepareStatement(sql, new String[]{"id"});
stmt.setInt(1, device.getId());
stmt.setString(2, device.getEnrolmentInfo().getOwner());
stmt.setString(3, device.getEnrolmentInfo().getOwnership().toString());
@ -1044,10 +1157,10 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
try {
conn = this.getConnection();
String sql = "SELECT ID AS ENROLMENT_ID, DEVICE_ID, OWNER, OWNERSHIP, STATUS, DATE_OF_ENROLMENT, " +
"DATE_OF_LAST_UPDATE, TENANT_ID FROM DM_ENROLMENT WHERE DEVICE_ID = (SELECT d.ID " +
"FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE d.DEVICE_TYPE_ID = t.ID " +
"AND d.DEVICE_IDENTIFICATION = ? AND t.NAME = ? AND d.TENANT_ID = ?) " +
"AND TENANT_ID = ? AND STATUS in ('ACTIVE','UNREACHABLE','INACTIVE')";
"DATE_OF_LAST_UPDATE, TENANT_ID FROM DM_ENROLMENT WHERE DEVICE_ID = (SELECT d.ID " +
"FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE d.DEVICE_TYPE_ID = t.ID " +
"AND d.DEVICE_IDENTIFICATION = ? AND t.NAME = ? AND d.TENANT_ID = ?) " +
"AND TENANT_ID = ? AND STATUS in ('ACTIVE','UNREACHABLE','INACTIVE')";
stmt = conn.prepareStatement(sql);
stmt.setString(1, deviceId.getId());
stmt.setString(2, deviceId.getType());
@ -1060,8 +1173,8 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
return enrolmentInfo;
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while retrieving the enrolment " +
"information of device '" + deviceId.getId() + "' of type : "
+ deviceId.getType(), e);
"information of device '" + deviceId.getId() + "' of type : "
+ deviceId.getType(), e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
@ -1130,7 +1243,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
*
* @param timestamp Timestamp in long, after which the devices have been updated.
* @param tenantId Tenant id of the currently logged in user.
* @return A collection of devices that have been updated after the provided timestamp
* @return A collection of devices that have been updated after the provided timestamp
* @throws DeviceManagementDAOException
*/
public List<Device> getDevices(long timestamp, int tenantId) throws DeviceManagementDAOException {
@ -1194,7 +1307,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
List<GeoCluster> geoClusters = new ArrayList<>();
try {
conn = this.getConnection();
String sql ="SELECT AVG(DEVICE_LOCATION.LATITUDE) AS LATITUDE,AVG(DEVICE_LOCATION.LONGITUDE) AS LONGITUDE," +
String sql = "SELECT AVG(DEVICE_LOCATION.LATITUDE) AS LATITUDE,AVG(DEVICE_LOCATION.LONGITUDE) AS LONGITUDE," +
" MIN(DEVICE_LOCATION.LATITUDE) AS MIN_LATITUDE, MAX(DEVICE_LOCATION.LATITUDE) AS MAX_LATITUDE," +
" MIN(DEVICE_LOCATION.LONGITUDE) AS MIN_LONGITUDE," +
" MAX(DEVICE_LOCATION.LONGITUDE) AS MAX_LONGITUDE," +
@ -1217,7 +1330,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
stmt.setDouble(3, northEast.getLatitude());
stmt.setDouble(4, southWest.getLongitude());
stmt.setDouble(5, northEast.getLongitude());
stmt.setDouble(6,tenantId);
stmt.setDouble(6, tenantId);
if (deviceType != null && !deviceType.isEmpty()) {
stmt.setString(7, deviceType);
}
@ -1230,13 +1343,13 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
double min_longitude = rs.getDouble("MIN_LONGITUDE");
double max_longitude = rs.getDouble("MAX_LONGITUDE");
String device_identification = rs.getString("DEVICE_IDENTIFICATION");
String device_type=rs.getString("TYPE");
String device_type = rs.getString("TYPE");
String last_seen = rs.getString("LAST_UPDATED_TIMESTAMP");
long count = rs.getLong("COUNT");
String geohashPrefix = rs.getString("GEOHASH_PREFIX");
geoClusters.add(new GeoCluster(new GeoCoordinate(latitude, longitude),
new GeoCoordinate(min_latitude,min_longitude), new GeoCoordinate(max_latitude,max_longitude),
count, geohashPrefix,device_identification,device_type,last_seen));
new GeoCoordinate(min_latitude, min_longitude), new GeoCoordinate(max_latitude, max_longitude),
count, geohashPrefix, device_identification, device_type, last_seen));
}
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while retrieving information of " +
@ -1294,5 +1407,379 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
e);
}
}
public void deleteDevice(DeviceIdentifier deviceIdentifier, int tenantId) throws DeviceManagementDAOException {
Connection conn;
try {
conn = this.getConnection();
int deviceId = getDeviceId(conn, deviceIdentifier, tenantId);
if (deviceId == -1) {
String msg = "Device " + deviceIdentifier.getId() + " of type " + deviceIdentifier.getType() +
" is not found";
log.error(msg);
throw new DeviceManagementDAOException(msg);
} else {
int enrollmentId = getEnrollmentId(conn, deviceId, tenantId);
if (enrollmentId == -1) {
String msg = "Enrollment not found for the device " + deviceIdentifier.getId() + " of type " +
deviceIdentifier.getType();
log.error(msg);
throw new DeviceManagementDAOException(msg);
} else {
removeDeviceDetail(conn, deviceId);
if (log.isDebugEnabled()) {
log.debug("Successfully removed device detail data");
}
removeDeviceLocation(conn, deviceId);
if (log.isDebugEnabled()) {
log.debug("Successfully removed device location data");
}
removeDeviceInfo(conn, deviceId);
if (log.isDebugEnabled()) {
log.debug("Successfully removed device info data");
}
removeDeviceNotification(conn, deviceId);
if (log.isDebugEnabled()) {
log.debug("Successfully removed device notification data");
}
removeDeviceApplicationMapping(conn, deviceId);
if (log.isDebugEnabled()) {
log.debug("Successfully removed device application mapping data");
}
removeDevicePolicyApplied(conn, deviceId);
if (log.isDebugEnabled()) {
log.debug("Successfully removed device applied policy data");
}
removeDevicePolicy(conn, deviceId);
if (log.isDebugEnabled()) {
log.debug("Successfully removed device policy data");
}
removeEnrollmentDeviceDetail(conn, enrollmentId);
if (log.isDebugEnabled()) {
log.debug("Successfully removed enrollment device detail data");
}
removeEnrollmentDeviceLocation(conn, enrollmentId);
if (log.isDebugEnabled()) {
log.debug("Successfully removed enrollment device location data");
}
removeEnrollmentDeviceInfo(conn, enrollmentId);
if (log.isDebugEnabled()) {
log.debug("Successfully removed enrollment device info data");
}
removeEnrollmentDeviceApplicationMapping(conn, enrollmentId);
if (log.isDebugEnabled()) {
log.debug("Successfully removed enrollment device application mapping data");
}
removeDeviceOperationResponse(conn, enrollmentId);
if (log.isDebugEnabled()) {
log.debug("Successfully removed device operation response data");
}
removeEnrollmentOperationMapping(conn, enrollmentId);
if (log.isDebugEnabled()) {
log.debug("Successfully removed enrollment operation mapping data");
}
removeDeviceEnrollment(conn, deviceId);
if (log.isDebugEnabled()) {
log.debug("Successfully removed device enrollment data");
}
removeDeviceGroupMapping(conn, deviceId);
if (log.isDebugEnabled()) {
log.debug("Successfully removed device group mapping data");
}
removeDevice(conn, deviceId);
if (log.isDebugEnabled()) {
log.debug("Successfully permanently deleted the device");
}
}
}
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while deleting the device", e);
}
}
private int getDeviceId(Connection conn, DeviceIdentifier deviceIdentifier, int tenantId)
throws DeviceManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
int deviceId = -1;
try {
String sql = "SELECT ID FROM DM_DEVICE WHERE DEVICE_IDENTIFICATION = ? AND TENANT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setString(1, deviceIdentifier.getId());
stmt.setInt(2, tenantId);
rs = stmt.executeQuery();
if (rs.next()) {
deviceId = rs.getInt("ID");
}
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while retrieving device id of the device", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
return deviceId;
}
private int getEnrollmentId(Connection conn, int deviceId, int tenantId) throws DeviceManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
int enrollmentId = -1;
try {
String sql = "SELECT ID FROM DM_ENROLMENT WHERE DEVICE_ID = ? AND TENANT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, deviceId);
stmt.setInt(2, tenantId);
rs = stmt.executeQuery();
if (rs.next()) {
enrollmentId = rs.getInt("ID");
}
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while retrieving enrollment id of the device", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
return enrollmentId;
}
private void removeDeviceDetail(Connection conn, int deviceId) throws DeviceManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
try {
String sql = "DELETE FROM DM_DEVICE_DETAIL WHERE DEVICE_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, deviceId);
stmt.executeUpdate();
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while removing device detail", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
}
private void removeDeviceLocation(Connection conn, int deviceId) throws DeviceManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
try {
String sql = "DELETE FROM DM_DEVICE_LOCATION WHERE DEVICE_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, deviceId);
stmt.executeUpdate();
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while removing device location", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
}
private void removeDeviceInfo(Connection conn, int deviceId) throws DeviceManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
try {
String sql = "DELETE FROM DM_DEVICE_INFO WHERE DEVICE_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, deviceId);
stmt.executeUpdate();
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while removing device info", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
}
private void removeDeviceNotification(Connection conn, int deviceId) throws DeviceManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
try {
String sql = "DELETE FROM DM_NOTIFICATION WHERE DEVICE_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, deviceId);
stmt.executeUpdate();
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while removing device notification", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
}
private void removeDeviceApplicationMapping(Connection conn, int deviceId) throws DeviceManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
try {
String sql = "DELETE FROM DM_DEVICE_APPLICATION_MAPPING WHERE DEVICE_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, deviceId);
stmt.executeUpdate();
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while removing device application mapping", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
}
private void removeDevicePolicyApplied(Connection conn, int deviceId) throws DeviceManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
try {
String sql = "DELETE FROM DM_DEVICE_POLICY_APPLIED WHERE DEVICE_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, deviceId);
stmt.executeUpdate();
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while removing device policy applied", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
}
private void removeDevicePolicy(Connection conn, int deviceId) throws DeviceManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
try {
String sql = "DELETE FROM DM_DEVICE_POLICY WHERE DEVICE_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, deviceId);
stmt.executeUpdate();
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while removing device policy", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
}
private void removeEnrollmentDeviceDetail(Connection conn, int enrollmentId) throws DeviceManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
try {
String sql = "DELETE FROM DM_DEVICE_DETAIL WHERE ENROLMENT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, enrollmentId);
stmt.executeUpdate();
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while removing enrollment device detail", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
}
private void removeEnrollmentDeviceLocation(Connection conn, int enrollmentId) throws DeviceManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
try {
String sql = "DELETE FROM DM_DEVICE_LOCATION WHERE ENROLMENT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, enrollmentId);
stmt.executeUpdate();
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while removing enrollment device location", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
}
private void removeEnrollmentDeviceInfo(Connection conn, int enrollmentId) throws DeviceManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
try {
String sql = "DELETE FROM DM_DEVICE_INFO WHERE ENROLMENT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, enrollmentId);
stmt.executeUpdate();
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while removing enrollment device info", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
}
private void removeEnrollmentDeviceApplicationMapping(Connection conn, int enrollmentId)
throws DeviceManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
try {
String sql = "DELETE FROM DM_DEVICE_APPLICATION_MAPPING WHERE ENROLMENT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, enrollmentId);
stmt.executeUpdate();
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while removing enrollment device application " +
"mapping", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
}
private void removeDeviceOperationResponse(Connection conn, int enrollmentId) throws DeviceManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
try {
String sql = "DELETE FROM DM_DEVICE_OPERATION_RESPONSE WHERE ENROLMENT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, enrollmentId);
stmt.executeUpdate();
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while removing device operation response", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
}
private void removeEnrollmentOperationMapping(Connection conn, int enrollmentId)
throws DeviceManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
try {
String sql = "DELETE FROM DM_ENROLMENT_OP_MAPPING WHERE ENROLMENT_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, enrollmentId);
stmt.executeUpdate();
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while removing enrollment operation mapping", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
}
private void removeDeviceEnrollment(Connection conn, int deviceId) throws DeviceManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
try {
String sql = "DELETE FROM DM_ENROLMENT WHERE DEVICE_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, deviceId);
stmt.executeUpdate();
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while removing device enrollment", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
}
private void removeDeviceGroupMapping(Connection conn, int deviceId) throws DeviceManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
try {
String sql = "DELETE FROM DM_DEVICE_GROUP_MAP WHERE DEVICE_ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, deviceId);
stmt.executeUpdate();
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while removing device group mapping", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
}
private void removeDevice(Connection conn, int deviceId) throws DeviceManagementDAOException {
PreparedStatement stmt = null;
ResultSet rs = null;
try {
String sql = "DELETE FROM DM_DEVICE WHERE ID = ?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, deviceId);
stmt.executeUpdate();
} catch (SQLException e) {
throw new DeviceManagementDAOException("Error occurred while removing device", e);
} finally {
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
}
}
}

@ -1129,7 +1129,7 @@ public class OperationManagerImpl implements OperationManager {
DeviceManagementDAOFactory.beginTransaction();
int tenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId();
String user = this.getUser();
updateStatus = enrollmentDAO.setStatus(enrolmentId, user, status, tenantId);
updateStatus = enrollmentDAO.setStatus(enrolmentId, status, tenantId);
DeviceManagementDAOFactory.commitTransaction();
} catch (DeviceManagementDAOException e) {
DeviceManagementDAOFactory.rollbackTransaction();

@ -92,7 +92,8 @@ public class ProfileOperationDAOImpl extends GenericOperationDAOImpl {
try {
Connection conn = OperationManagementDAOFactory.getConnection();
String sql = "SELECT o.ID, po.ENABLED, po.OPERATION_DETAILS, o.CREATED_TIMESTAMP, o.OPERATION_CODE " +
"FROM DM_PROFILE_OPERATION po INNER JOIN DM_OPERATION o ON po.OPERATION_ID = O.ID WHERE po.OPERATION_ID=?";
"FROM DM_PROFILE_OPERATION po INNER JOIN DM_OPERATION o ON po.OPERATION_ID = o.ID WHERE po" +
".OPERATION_ID=?";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, id);

@ -15,6 +15,24 @@
* specific language governing permissions and limitations
* under the License.
*/
/*
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
*
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.core.service;
import org.wso2.carbon.device.mgt.common.Device;
@ -29,6 +47,7 @@ import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig;
import org.wso2.carbon.device.mgt.common.PaginationRequest;
import org.wso2.carbon.device.mgt.common.PaginationResult;
import org.wso2.carbon.device.mgt.common.exceptions.UserNotFoundException;
import org.wso2.carbon.device.mgt.common.StartupOperationConfig;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.common.license.mgt.License;
@ -190,6 +209,17 @@ public interface DeviceManagementProviderService {
*/
Device getDevice(DeviceIdentifier deviceId, boolean requireDeviceInfo) throws DeviceManagementException;
/**
* Returns the device of specified id.
*
* @param deviceId device Id
* @param requireDeviceInfo - A boolean indicating whether the device-info (location, app-info etc) is also required
* along with the device data.
* @return Device returns null when device is not available.
* @throws DeviceManagementException
*/
Device getDevice(String deviceId, boolean requireDeviceInfo) throws DeviceManagementException;
/**
* Returns the device of specified id owned by user with given username.
*
@ -225,6 +255,18 @@ public interface DeviceManagementProviderService {
*/
Device getDevice(DeviceIdentifier deviceId, Date since, boolean requireDeviceInfo) throws DeviceManagementException;
/**
* Returns the device of specified id.
*
* @param deviceId device Id
* @param since - Date value where the resource was last modified
* @param requireDeviceInfo - A boolean indicating whether the device-info (location, app-info etc) is also required
* along with the device data.
* @return Device returns null when device is not available.
* @throws DeviceManagementException
*/
Device getDevice(String deviceId, Date since, boolean requireDeviceInfo) throws DeviceManagementException;
/**
* Returns the device of specified id and owned by user with given username.
*
@ -541,6 +583,8 @@ public interface DeviceManagementProviderService {
boolean disenrollDevice(DeviceIdentifier deviceId) throws DeviceManagementException;
boolean deleteDevice(DeviceIdentifier deviceId) throws DeviceManagementException;
boolean isEnrolled(DeviceIdentifier deviceId) throws DeviceManagementException;
boolean isActive(DeviceIdentifier deviceId) throws DeviceManagementException;
@ -614,10 +658,14 @@ public interface DeviceManagementProviderService {
List<MonitoringOperation> getMonitoringOperationList(String deviceType);
List<String> getStartupOperations(String deviceType);
int getDeviceMonitoringFrequency(String deviceType);
OperationMonitoringTaskConfig getDeviceMonitoringConfig(String deviceType);
StartupOperationConfig getStartupOperationConfig(String deviceType);
boolean isDeviceMonitoringEnabled(String deviceType);
PolicyMonitoringManager getPolicyMonitoringManager(String deviceType);

@ -15,6 +15,23 @@
* specific language governing permissions and limitations
* under the License.
*/
/*
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
*
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.core.service;
import org.apache.commons.lang.StringUtils;
@ -50,6 +67,7 @@ import org.wso2.carbon.device.mgt.common.PaginationRequest;
import org.wso2.carbon.device.mgt.common.PaginationResult;
import org.wso2.carbon.device.mgt.common.exceptions.TransactionManagementException;
import org.wso2.carbon.device.mgt.common.exceptions.UserNotFoundException;
import org.wso2.carbon.device.mgt.common.StartupOperationConfig;
import org.wso2.carbon.device.mgt.common.app.mgt.Application;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
@ -497,6 +515,67 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
return deviceManager.disenrollDevice(deviceId);
}
@Override
public boolean deleteDevice(DeviceIdentifier deviceId) throws DeviceManagementException {
if (deviceId == null) {
String msg = "Required values are not set to permanently delete device";
log.error(msg);
throw new DeviceManagementException(msg);
}
if (log.isDebugEnabled()) {
log.debug("Permanently deleting device: " + deviceId.getId() + " of type '" + deviceId.getType() + "'");
}
DeviceManager deviceManager = this.getDeviceManager(deviceId.getType());
if (deviceManager == null) {
if (log.isDebugEnabled()) {
log.debug("Device Manager associated with the device type '" + deviceId.getType() + "' is null. " +
"Therefore, not attempting method 'deleteDevice'");
}
return false;
}
int tenantId = this.getTenantId();
Device device = this.getDevice(deviceId, false);
if (device == null) {
if (log.isDebugEnabled()) {
log.debug("Device not found for id '" + deviceId.getId() + "'");
}
return false;
}
if (!device.getEnrolmentInfo().getStatus().equals(EnrolmentInfo.Status.REMOVED)) {
String msg = "Device " + deviceId.getId() + " of type " + deviceId.getType() + " is not dis-enrolled to " +
"permanently delete the device";
log.error(msg);
throw new DeviceManagementException(msg);
} else {
try {
DeviceManagementDAOFactory.beginTransaction();
deviceDAO.deleteDevice(deviceId, tenantId);
DeviceManagementDAOFactory.commitTransaction();
this.removeDeviceFromCache(deviceId);
} catch (DeviceManagementDAOException e) {
DeviceManagementDAOFactory.rollbackTransaction();
String msg = "Error occurred while permanently deleting '" + deviceId.getType() +
"' device with the identifier '" + deviceId.getId() + "'";
log.error(msg, e);
throw new DeviceManagementException(msg, e);
} catch (TransactionManagementException e) {
String msg = "Error occurred while initiating transaction";
log.error(msg, e);
throw new DeviceManagementException(msg, e);
} catch (Exception e) {
String msg = "Error occurred while permanently deleting device: " + deviceId.getId();
log.error(msg, e);
throw new DeviceManagementException(msg, e);
} finally {
DeviceManagementDAOFactory.closeConnection();
}
}
return true;
}
@Override
public boolean isEnrolled(DeviceIdentifier deviceId) throws DeviceManagementException {
Device device = this.getDevice(deviceId, false);
@ -816,6 +895,53 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
return device;
}
@Override
public Device getDevice(String deviceId, boolean requireDeviceInfo) throws DeviceManagementException {
if (deviceId == null) {
String message = "Received null device identifier for method getDevice";
log.error(message);
throw new DeviceManagementException(message);
}
if (log.isDebugEnabled()) {
log.debug("Get device by device id :" + deviceId + " '" +
"' and requiredDeviceInfo: " + requireDeviceInfo);
}
int tenantId = this.getTenantId();
Device device;
try {
DeviceManagementDAOFactory.openConnection();
device = deviceDAO.getDevice(deviceId, tenantId);
if (device == null) {
String message = "No device is found upon the id '" +
deviceId + "'";
if (log.isDebugEnabled()) {
log.debug(message);
}
return null;
}
DeviceIdentifier deviceIdentifier = new DeviceIdentifier(deviceId, device.getType());
this.addDeviceToCache(deviceIdentifier, device);
} catch (DeviceManagementDAOException e) {
String message = "Error occurred while obtaining the device for '" + deviceId + "'";
log.error(message, e);
throw new DeviceManagementException(message, e);
} catch (SQLException e) {
String message = "Error occurred while opening a connection to the data source";
log.error(message);
throw new DeviceManagementException(message, e);
} catch (Exception e) {
String message = "Error occurred in getDevice: " + deviceId;
log.error(message, e);
throw new DeviceManagementException(message, e);
} finally {
DeviceManagementDAOFactory.closeConnection();
}
if (requireDeviceInfo) {
device = this.getAllDeviceInfo(device);
}
return device;
}
@Override
public Device getDevice(DeviceIdentifier deviceId, String owner, boolean requireDeviceInfo)
throws DeviceManagementException {
@ -1075,6 +1201,47 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
return device;
}
@Override
public Device getDevice(String deviceId, Date since, boolean requireDeviceInfo) throws DeviceManagementException {
if (deviceId == null || since == null) {
String message = "Received incomplete data for getDevice";
log.error(message);
throw new DeviceManagementException(message);
}
if (log.isDebugEnabled()) {
log.debug("Get device since '" + since.toString() + "' with identifier: " + deviceId + "");
}
Device device;
try {
DeviceManagementDAOFactory.openConnection();
device = deviceDAO.getDevice(deviceId, since, this.getTenantId());
if (device == null) {
if (log.isDebugEnabled()) {
log.debug("No device is found upon the id '" + deviceId + "'");
}
return null;
}
} catch (DeviceManagementDAOException e) {
String message = "Error occurred while obtaining the device for id '" + deviceId + "'";
log.error(message, e);
throw new DeviceManagementException(message, e);
} catch (SQLException e) {
String message = "Error occurred while opening a connection to the data source";
log.error(message, e);
throw new DeviceManagementException(message, e);
} catch (Exception e) {
String message = "Error occurred in getDevice for device: " + deviceId;
log.error(message, e);
throw new DeviceManagementException(message, e);
} finally {
DeviceManagementDAOFactory.closeConnection();
}
if (requireDeviceInfo) {
device = this.getAllDeviceInfo(device);
}
return device;
}
@Override
public Device getDevice(DeviceIdentifier deviceId, String owner, Date since, boolean requireDeviceInfo)
throws DeviceManagementException {
@ -1321,7 +1488,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
EnrolmentInfo enrolmentInfo = device.getEnrolmentInfo();
DeviceManagementDAOFactory.beginTransaction();
if (enrolmentInfo != null) {
success = enrollmentDAO.setStatus(enrolmentInfo.getId(), currentOwner, status, tenantId);
success = enrollmentDAO.setStatus(enrolmentInfo.getId(), status, tenantId);
}
DeviceManagementDAOFactory.commitTransaction();
this.removeDeviceFromCache(deviceId);
@ -1631,6 +1798,19 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
return operationMonitoringTaskConfig.getMonitoringOperation();
}
@Override
public List<String> getStartupOperations(String deviceType) {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
DeviceManagementService dms = pluginRepository.getDeviceManagementService(deviceType, tenantId);
StartupOperationConfig startupOperationConfig = dms.getStartupOperationConfig();
if (startupOperationConfig != null) {
return startupOperationConfig.getStartupOperations();
}
return null;
}
@Override
public int getDeviceMonitoringFrequency(String deviceType) {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
@ -1646,6 +1826,13 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
return dms.getOperationMonitoringConfig();
}
@Override
public StartupOperationConfig getStartupOperationConfig(String deviceType) {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
DeviceManagementService dms = pluginRepository.getDeviceManagementService(deviceType, tenantId);
return dms.getStartupOperationConfig();
}
@Override
public boolean isDeviceMonitoringEnabled(String deviceType) {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();

@ -14,6 +14,23 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
@ -21,7 +38,9 @@ package org.wso2.carbon.device.mgt.core.task;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Utils {
@ -46,5 +65,25 @@ public class Utils {
}
}
public static boolean getIsTenantedStartupConfig(Map<Integer, List<String>> map, String deviceType) {
List<String> deviceTypes;
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
if (map.containsKey(tenantId)) {
if (map.get(tenantId).contains(deviceType)) {
return false;
} else {
deviceTypes = map.get(tenantId);
deviceTypes.add(deviceType);
map.put(tenantId, deviceTypes);
return true;
}
} else {
deviceTypes = new ArrayList<>();
deviceTypes.add(deviceType);
map.put(tenantId, deviceTypes);
return true;
}
}
}

@ -14,6 +14,23 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.core.task.impl;
@ -23,6 +40,7 @@ import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig;
import org.wso2.carbon.device.mgt.common.StartupOperationConfig;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.core.task.DeviceMgtTaskException;
@ -56,17 +74,20 @@ public class DeviceDetailsRetrieverTask implements Task {
.getDeviceManagementProvider();
OperationMonitoringTaskConfig operationMonitoringTaskConfig = deviceManagementProviderService
.getDeviceMonitoringConfig(deviceType);
StartupOperationConfig startupOperationConfig = deviceManagementProviderService
.getStartupOperationConfig(deviceType);
if (System.getProperty(IS_CLOUD) != null && Boolean.parseBoolean(System.getProperty(IS_CLOUD))) {
executeForTenants = true;
}
if (executeForTenants) {
this.executeForAllTenants(operationMonitoringTaskConfig);
this.executeForAllTenants(operationMonitoringTaskConfig, startupOperationConfig);
} else {
if (log.isDebugEnabled()) {
log.debug("Device details retrieving task started to run.");
}
DeviceTaskManager deviceTaskManager = new DeviceTaskManagerImpl(deviceType, operationMonitoringTaskConfig);
DeviceTaskManager deviceTaskManager = new DeviceTaskManagerImpl(deviceType, operationMonitoringTaskConfig,
startupOperationConfig);
//pass the configurations also from here, monitoring tasks
try {
if (deviceManagementProviderService.isDeviceMonitoringEnabled(deviceType)) {
@ -78,7 +99,8 @@ public class DeviceDetailsRetrieverTask implements Task {
}
}
private void executeForAllTenants(OperationMonitoringTaskConfig operationMonitoringTaskConfig) {
private void executeForAllTenants(OperationMonitoringTaskConfig operationMonitoringTaskConfig,
StartupOperationConfig startupOperationConfig) {
if (log.isDebugEnabled()) {
log.debug("Device details retrieving task started to run for all tenants.");
@ -98,7 +120,8 @@ public class DeviceDetailsRetrieverTask implements Task {
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain);
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenant);
DeviceTaskManager deviceTaskManager = new DeviceTaskManagerImpl(deviceType,
operationMonitoringTaskConfig);
operationMonitoringTaskConfig,
startupOperationConfig);
//pass the configurations also from here, monitoring tasks
try {
if (deviceManagementProviderService.isDeviceMonitoringEnabled(deviceType)) {

@ -14,6 +14,22 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
@ -21,16 +37,19 @@ package org.wso2.carbon.device.mgt.core.task.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.base.ServerConfiguration;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.exceptions.InvalidDeviceException;
import org.wso2.carbon.device.mgt.common.MonitoringOperation;
import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig;
import org.wso2.carbon.device.mgt.common.StartupOperationConfig;
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.core.internal.DeviceManagementDataHolder;
import org.wso2.carbon.device.mgt.core.operation.mgt.CommandOperation;
import org.wso2.carbon.device.mgt.core.operation.mgt.ProfileOperation;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.core.task.DeviceMgtTaskException;
import org.wso2.carbon.device.mgt.core.task.DeviceTaskManager;
@ -44,7 +63,17 @@ public class DeviceTaskManagerImpl implements DeviceTaskManager {
private static Log log = LogFactory.getLog(DeviceTaskManagerImpl.class);
private String deviceType;
static volatile Map<Integer, Map<String, Map<String, Long>>> map = new HashMap<>();
private static volatile Map<Integer, List<String>> startupConfigMap = new HashMap<>();
private OperationMonitoringTaskConfig operationMonitoringTaskConfig;
private StartupOperationConfig startupOperationConfig;
public DeviceTaskManagerImpl(String deviceType,
OperationMonitoringTaskConfig operationMonitoringTaskConfig,
StartupOperationConfig startupOperationConfig) {
this.deviceType = deviceType;
this.operationMonitoringTaskConfig = operationMonitoringTaskConfig;
this.startupOperationConfig = startupOperationConfig;
}
public DeviceTaskManagerImpl(String deviceType,
OperationMonitoringTaskConfig operationMonitoringTaskConfig) {
@ -61,6 +90,13 @@ public class DeviceTaskManagerImpl implements DeviceTaskManager {
return operationMonitoringTaskConfig.getMonitoringOperation();
}
private List<String> getStartupOperations() {
if (startupOperationConfig != null) {
return startupOperationConfig.getStartupOperations();
}
return null;
}
@Override
public int getTaskFrequency() throws DeviceMgtTaskException {
return operationMonitoringTaskConfig.getFrequency();
@ -86,6 +122,7 @@ public class DeviceTaskManagerImpl implements DeviceTaskManager {
List<Device> devices;
List<String> operations;
List<DeviceIdentifier> validDeviceIdentifiers;
List<String> startupOperations;
operations = this.getValidOperationNames(); //list operations for each device type
devices = deviceManagementProviderService.getAllDevices(deviceType, false);//list devices for each type
@ -106,6 +143,11 @@ public class DeviceTaskManagerImpl implements DeviceTaskManager {
operation.setCode(str);
deviceManagementProviderService.addOperation(deviceType, operation, validDeviceIdentifiers);
}
startupOperations = getStartupOperations();
if (startupOperations != null && !startupOperations.isEmpty()) {
addStartupOperations(startupOperations, validDeviceIdentifiers,
deviceManagementProviderService);
}
} else {
if (log.isDebugEnabled()) {
log.debug("No operations are available.");
@ -153,6 +195,32 @@ public class DeviceTaskManagerImpl implements DeviceTaskManager {
return opNames;
}
private void addStartupOperations(List<String> startupOperations, List<DeviceIdentifier> validDeviceIdentifiers
, DeviceManagementProviderService deviceManagementProviderService) throws DeviceMgtTaskException {
boolean isStartupConfig = Utils.getIsTenantedStartupConfig(startupConfigMap, deviceType);
if (isStartupConfig) {
try {
Operation operation;
for (String startupOp : startupOperations) {
if ("SERVER_VERSION".equals(startupOp)) {
operation = new ProfileOperation();
operation.setPayLoad(ServerConfiguration.getInstance().getFirstProperty("Version"));
} else {
operation = new CommandOperation();
}
operation.setType(Operation.Type.COMMAND);
operation.setEnabled(true);
operation.setCode(startupOp);
deviceManagementProviderService.addOperation(deviceType, operation, validDeviceIdentifiers);
}
} catch (InvalidDeviceException e) {
throw new DeviceMgtTaskException("Invalid DeviceIdentifiers found.", e);
} catch (OperationManagementException e) {
throw new DeviceMgtTaskException("Error occurred while adding the operations to devices", e);
}
}
}
private List<MonitoringOperation> getOperationListforTask() throws DeviceMgtTaskException {
DeviceManagementProviderService deviceManagementProviderService = DeviceManagementDataHolder
@ -163,17 +231,31 @@ public class DeviceTaskManagerImpl implements DeviceTaskManager {
deviceType);//Get task list from each device type
}
private List<String> getStartupOperationListForTask() {
DeviceManagementProviderService deviceManagementProviderService = DeviceManagementDataHolder.getInstance()
.getDeviceManagementProvider();
return deviceManagementProviderService.getStartupOperations(deviceType);
}
@Override
public boolean isTaskOperation(String opName) {
try {
List<MonitoringOperation> monitoringOperations = this.getOperationListforTask();
List<String> startupOperations = this.getStartupOperationListForTask();
for (MonitoringOperation taop : monitoringOperations) {
if (taop.getTaskName().equalsIgnoreCase(opName)) {
return true;
}
}
if (startupOperations != null && !startupOperations.isEmpty()) {
for (String operation : startupOperations) {
if (opName.equalsIgnoreCase(operation)) {
return true;
}
}
}
} catch (DeviceMgtTaskException e) {
// ignoring the error, no need to throw, If error occurs, return value will be false.
}

@ -14,6 +14,22 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.core;
@ -102,6 +118,11 @@ public class TestDeviceManagementService implements DeviceManagementService {
return null;
}
@Override
public StartupOperationConfig getStartupOperationConfig() {
return null;
}
@Override
public PullNotificationSubscriber getPullNotificationSubscriber() {
return null;

@ -1,18 +1,39 @@
/*
* Copyright (c) 2015, 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.
*/
* 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.
*
*/
/*
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
*
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.core.service;
import org.apache.commons.logging.Log;
@ -70,6 +91,7 @@ public class DeviceManagementProviderServiceTest extends BaseDeviceManagementTes
private static final String ALTERNATE_DEVICE_ID = "1128";
private DeviceManagementProviderService providerService;
private static final String DEVICE_TYPE = "RANDOM_DEVICE_TYPE";
private static final String DEVICE_OWNER = "admin";
private DeviceDetailsDAO deviceDetailsDAO = DeviceManagementDAOFactory.getDeviceDetailsDAO();
DeviceManagementProviderService deviceMgtService;
@ -350,7 +372,6 @@ public class DeviceManagementProviderServiceTest extends BaseDeviceManagementTes
Assert.assertTrue(device.getDeviceIdentifier().equalsIgnoreCase(DEVICE_ID));
}
@Test(dependsOnMethods = {"testSuccessfulDeviceEnrollment"})
public void testGetDeviceWithInfo() throws DeviceManagementException {
Device device = deviceMgtService.getDevice(new DeviceIdentifier(DEVICE_ID, DEVICE_TYPE)
@ -360,6 +381,52 @@ public class DeviceManagementProviderServiceTest extends BaseDeviceManagementTes
}
}
@Test(dependsOnMethods = {"testSuccessfulDeviceEnrollment"})
public void testGetDeviceByID() throws DeviceManagementException {
Device device = deviceMgtService.getDevice(DEVICE_ID, true);
if (!isMock()) {
Assert.assertTrue(device.getDeviceIdentifier().equalsIgnoreCase(DEVICE_ID));
}
}
@Test(dependsOnMethods = {"testSuccessfulDeviceEnrollment"}, expectedExceptions =
DeviceManagementException.class)
public void testGetDeviceByIDWithNullID() throws DeviceManagementException {
deviceMgtService.getDevice((String) null, true);
}
@Test(dependsOnMethods = {"testSuccessfulDeviceEnrollment"})
public void testGetDeviceByIDAndSinceDate() throws DeviceManagementException, DeviceDetailsMgtDAOException
, TransactionManagementException {
Device initialDevice = deviceMgtService.getDevice(new DeviceIdentifier(DEVICE_ID,
DEVICE_TYPE));
addDeviceInformation(initialDevice);
Device device = deviceMgtService.getDevice(DEVICE_ID, yesterday(), true);
if (!isMock()) {
Assert.assertTrue(device != null);
}
}
@Test(dependsOnMethods = {"testSuccessfulDeviceEnrollment"}, expectedExceptions =
DeviceManagementException.class)
public void testGetDeviceByIDAndSinceDateWithNullID() throws DeviceManagementException, DeviceDetailsMgtDAOException
, TransactionManagementException {
Device initialDevice = deviceMgtService.getDevice(new DeviceIdentifier(DEVICE_ID,
DEVICE_TYPE));
addDeviceInformation(initialDevice);
deviceMgtService.getDevice((String)null, yesterday(), true);
}
@Test(dependsOnMethods = {"testSuccessfulDeviceEnrollment"}, expectedExceptions =
DeviceManagementException.class)
public void testGetDeviceByIDAndSinceDateWithNullDate() throws DeviceManagementException,
DeviceDetailsMgtDAOException, TransactionManagementException {
Device initialDevice = deviceMgtService.getDevice(new DeviceIdentifier(DEVICE_ID,
DEVICE_TYPE));
addDeviceInformation(initialDevice);
deviceMgtService.getDevice(DEVICE_ID, (Date)null, true);
}
@Test(dependsOnMethods = {"testSuccessfulDeviceEnrollment"})
public void testGetDeviceTypeWithProps() throws DeviceManagementException, NoSuchFieldException,
IllegalAccessException {
@ -435,7 +502,7 @@ public class DeviceManagementProviderServiceTest extends BaseDeviceManagementTes
@Test(dependsOnMethods = {"testSuccessfulDeviceEnrollment"}, expectedExceptions =
DeviceManagementException.class)
public void testDeviceByOwnerWithNullDeviceID() throws DeviceManagementException {
deviceMgtService.getDevice(null, "admin", true);
deviceMgtService.getDevice((DeviceIdentifier) null, "admin", true);
}
@Test(dependsOnMethods = {"testSuccessfulDeviceEnrollment"})
@ -496,7 +563,7 @@ public class DeviceManagementProviderServiceTest extends BaseDeviceManagementTes
@Test(dependsOnMethods = {"testSuccessfulDeviceEnrollment"}, expectedExceptions =
DeviceManagementException.class)
public void testDeviceByDateWithNullDeviceID() throws DeviceManagementException {
deviceMgtService.getDevice(null, yesterday());
deviceMgtService.getDevice((DeviceIdentifier) null, yesterday());
}
private void addDeviceInformation(Device initialDevice) throws TransactionManagementException, DeviceDetailsMgtDAOException {

@ -416,7 +416,7 @@ CREATE TABLE IF NOT EXISTS DM_DEVICE_INFO (
DEVICE_ID INT NULL,
ENROLMENT_ID INT NOT NULL,
KEY_FIELD VARCHAR(45) NULL,
VALUE_FIELD VARCHAR(100) NULL,
VALUE_FIELD VARCHAR(1000) NULL,
PRIMARY KEY (ID),
CONSTRAINT DM_DEVICE_INFO_DEVICE
FOREIGN KEY (DEVICE_ID)

@ -22,7 +22,7 @@
<parent>
<artifactId>device-mgt</artifactId>
<groupId>org.wso2.carbon.devicemgt</groupId>
<version>3.2.5-SNAPSHOT</version>
<version>3.2.7-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

@ -15,6 +15,22 @@
* specific language governing permissions and limitations
* under the License.
*
*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.extensions.device.type.template;
@ -27,6 +43,7 @@ import org.wso2.carbon.device.mgt.common.InitialOperationConfig;
import org.wso2.carbon.device.mgt.common.MonitoringOperation;
import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig;
import org.wso2.carbon.device.mgt.common.ProvisioningConfig;
import org.wso2.carbon.device.mgt.common.StartupOperationConfig;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager;
import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
@ -71,6 +88,7 @@ public class DeviceTypeManagerService implements DeviceManagementService {
private List<MonitoringOperation> monitoringOperations;
private PolicyMonitoringManager policyMonitoringManager;
private InitialOperationConfig initialOperationConfig;
private StartupOperationConfig startupOperationConfig;
private PullNotificationSubscriber pullNotificationSubscriber;
private DeviceStatusTaskPluginConfig deviceStatusTaskPluginConfig;
private DeviceTypePlatformDetails deviceTypePlatformDetails;
@ -89,6 +107,8 @@ public class DeviceTypeManagerService implements DeviceManagementService {
this.setOperationMonitoringConfig(deviceTypeConfiguration);
this.initialOperationConfig = new InitialOperationConfig();
this.setInitialOperationConfig(deviceTypeConfiguration);
this.startupOperationConfig = new StartupOperationConfig();
this.setStartupOperationConfig(deviceTypeConfiguration);
this.deviceStatusTaskPluginConfig = new DeviceStatusTaskPluginConfig();
this.deviceTypePlatformDetails = new DeviceTypePlatformDetails();
this.setDeviceTypePlatformDetails(deviceTypeConfiguration);
@ -214,6 +234,11 @@ public class DeviceTypeManagerService implements DeviceManagementService {
return initialOperationConfig;
}
@Override
public StartupOperationConfig getStartupOperationConfig() {
return startupOperationConfig;
}
@Override
public PullNotificationSubscriber getPullNotificationSubscriber() {
return pullNotificationSubscriber;
@ -276,6 +301,15 @@ public class DeviceTypeManagerService implements DeviceManagementService {
}
}
private void setStartupOperationConfig(DeviceTypeConfiguration deviceTypeConfiguration) {
if (deviceTypeConfiguration.getOperations() != null) {
List<String> startupOperations = deviceTypeConfiguration.getStartupOperations();
if (startupOperations != null && !startupOperations.isEmpty()) {
startupOperationConfig.setStartupOperations(startupOperations);
}
}
}
private void setType(String type) {
this.type = type;
}

@ -15,6 +15,22 @@
* specific language governing permissions and limitations
* under the License.
*
*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.extensions.device.type.template.config;
@ -99,6 +115,10 @@ public class DeviceTypeConfiguration {
this.deviceTypePlatformDetails = deviceTypePlatformDetails;
}
@XmlElementWrapper(name = "StartupOperationConfig")
@XmlElement(name = "Operation", required = true)
protected List<String> startupOperations;
public List<String> getOperations() {
return operations;
}
@ -375,4 +395,24 @@ public class DeviceTypeConfiguration {
public void setDeviceAuthorizationConfig(DeviceAuthorizationConfig value) {
this.deviceAuthorizationConfig = value;
}
/**
* Gets the value of startup operation config
*
* @return possible object is
* {@link List<String>}
*/
public List<String> getStartupOperations() {
return startupOperations;
}
/**
* Sets the value for startup operation config
*
* @param startupOperations possible object is
* {@link List<String>}
*/
public void setStartupOperations(List<String> startupOperations) {
this.startupOperations = startupOperations;
}
}

@ -14,8 +14,26 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
@ -33,41 +51,46 @@ import java.util.List;
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType name="Feature">
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element name="Name" type="{http://www.w3.org/2001/XMLSchema}string"/>
* &lt;element name="Description" type="{http://www.w3.org/2001/XMLSchema}string"/>
* &lt;element name="Operation" type="{}Operation"/>
* &lt;/sequence>
* &lt;attribute name="code" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* <xs:element name="Feature">
* <xs:complexType>
* <xs:sequence>
* <xs:element name="Name" type="xs:string" />
* <xs:element name="Description" type="xs:string" />
* <xs:element name="Operation" type="{}Operation" />
* </xs:sequence>
* <xs:attribute name="type" type="xs:string" />
* <xs:attribute name="code" type="xs:string" />
* </xs:complexType>
* </xs:element>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Feature", propOrder = {
"name",
"description",
"operation", "metaData"
"operation",
"metaData"
})
public class Feature {
@XmlElement(name = "Name", required = true)
protected String name;
@XmlElement(name = "Description", required = true)
protected String description;
@XmlElement(name = "Operation", required = true)
@XmlElement(name = "Operation")
protected Operation operation;
@XmlAttribute(name = "type", required = true)
protected String type;
@XmlAttribute(name = "code")
protected String code;
@XmlElementWrapper(name = "MetaData")
@XmlElement(name = "Property", required = true)
protected List<String> metaData;
private List<String> metaData;
/**
* Gets the value of the name property.
@ -172,4 +195,12 @@ public class Feature {
public void setMetaData(List<String> metaData) {
this.metaData = metaData;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}

@ -32,15 +32,15 @@ import java.util.List;
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType name="Features">
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element name="Feature" type="{}Feature"/>
* &lt;/sequence>
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* <complexType name="Features">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="Feature" type="{}Feature"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*

@ -0,0 +1,76 @@
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
/**
* Java class for filter complex type.
*
* The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <xs:element name="uiParam" maxOccurs="unbounded">
* <xs:complexType>
* <xs:sequence>
* <xs:element name="property" type="xs:string" />
* <xs:element name="value" type="xs:string" />
* <xs:element name="description" type="xs:string" />
* </xs:sequence>
* </xs:complexType>
* </xs:element>
* </pre>
*/
@XmlAccessorType(XmlAccessType.FIELD)
public class Filter {
@XmlElement(name = "property", required = true)
private String property;
@XmlElement(name = "value", required = true)
private String value;
@XmlElement(name = "description", required = true)
private String description;
public String getProperty() {
return property;
}
public void setProperty(String property) {
this.property = property;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}

@ -14,7 +14,24 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.extensions.device.type.template.config;
@ -27,26 +44,24 @@ import java.util.List;
/**
* <p>Java class for FormParameters complex type.
* <p>Java class for fromParams complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType name="FormParameters">
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element name="Parameter" type="{http://www.w3.org/2001/XMLSchema}string"/>
* &lt;/sequence>
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* <complexType name="formParams">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="Parameter" type="{http://www.w3.org/2001/XMLSchema}string"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "FormParameters", propOrder = {
@XmlType(name = "formParams", propOrder = {
"parameter"
})
public class FormParameters {
@ -56,7 +71,7 @@ public class FormParameters {
public List<String> getParameter() {
if (parameter == null) {
parameter = new ArrayList<String>();
parameter = new ArrayList<>();
}
return this.parameter;
}

@ -14,8 +14,26 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
@ -26,164 +44,71 @@ import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for Operation complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* Java class for Operation complex type.
*
* The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType name="Operation">
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element name="QueryParameters" type="{}QueryParameters"/>
* &lt;element name="FormParameters" type="{}FormParameters"/>
* &lt;/sequence>
* &lt;attribute name="context" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="method" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* <xs:element name="Operation">
* <xs:complexType>
* <xs:sequence>
* <xs:element name="params" type="{}Params"/>
* <xs:element name="metadata" type="{}OperationMetadata"/>
* </xs:sequence>
* <xs:attribute name="hidden" type="xs:boolean"/>
* <xs:attribute name="icon" type="xs:string"/>
* </xs:complexType>
* </xs:element>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Operation", propOrder = {
"queryParameters",
"formParameters"
"params",
"metadata"
})
public class Operation {
@XmlElement(name = "QueryParameters")
protected QueryParameters queryParameters;
@XmlElement(name = "FormParameters")
protected FormParameters formParameters;
@XmlAttribute(name = "context")
protected String context;
@XmlAttribute(name = "method")
protected String method;
@XmlAttribute(name = "type")
protected String type;
/**
* Gets the value of the Content Type property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getType() {
return type;
}
@XmlElement(name = "params")
private Params params;
/**
* Sets the value of the Content Type property.
*
* @param type
* allowed object is
* {@link String }
*
*/
public void setType(String type) {
this.type = type;
}
@XmlElement(name = "metadata", required = true)
private OperationMetadata metadata;
/**
* Gets the value of the queryParameters property.
*
* @return
* possible object is
* {@link QueryParameters }
*
*/
public QueryParameters getQueryParameters() {
return queryParameters;
}
@XmlAttribute(name = "hidden", required = true)
private boolean hidden;
@XmlAttribute(name = "icon")
private String icon;
/**
* Sets the value of the queryParameters property.
*
* @param value
* allowed object is
* {@link QueryParameters }
*
*/
public void setQueryParameters(QueryParameters value) {
this.queryParameters = value;
public Params getParams() {
return params;
}
/**
* Gets the value of the formParameters property.
*
* @return
* possible object is
* {@link FormParameters }
*
*/
public FormParameters getFormParameters() {
return formParameters;
public void setParams(Params params) {
this.params = params;
}
/**
* Sets the value of the formParameters property.
*
* @param value
* allowed object is
* {@link FormParameters }
*
*/
public void setFormParameters(FormParameters value) {
this.formParameters = value;
public OperationMetadata getMetadata() {
return metadata;
}
/**
* Gets the value of the context property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getContext() {
return context;
public void setMetadata(OperationMetadata metadata) {
this.metadata = metadata;
}
/**
* Sets the value of the context property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setContext(String value) {
this.context = value;
public String getIcon() {
return icon;
}
/**
* Gets the value of the method property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getMethod() {
return method;
public void setIcon(String icon) {
this.icon = icon;
}
/**
* Sets the value of the method property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setMethod(String value) {
this.method = value;
public boolean isHidden() {
return hidden;
}
public void setHidden(boolean hidden) {
this.hidden = hidden;
}
}

@ -0,0 +1,120 @@
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlType;
import java.util.List;
/**
* Java class for metadata complex type.
*
* The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <xs:element name="metadata">
* <xs:complexType>
* <xs:sequence>
* <xs:element name="uri" type="xs:string" />
* <xs:element name="method" type="xs:string" />
* <xs:element name="contentType" type="xs:string" />
* <xs:element name="permission" type="xs:string" />
* <xs:element name="filters">
* <xs:complexType>
* <xs:sequence>
* <xs:element name="property" type="xs:string" />
* <xs:element name="value" type="xs:string" />
* <xs:element name="description" type="xs:string" />
* </xs:sequence>
* </xs:complexType>
* </xs:element>
* </xs:sequence>
* </xs:complexType>
* </xs:element>
* </pre>
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "metadata", propOrder = {
"uri",
"method",
"contentType",
"permission",
"filterList"
})
public class OperationMetadata {
@XmlElement(name = "uri", required = true)
private String uri;
@XmlElement(name = "method", required = true)
private String method;
@XmlElement(name = "contentType")
private String contentType;
@XmlElement(name = "permission")
private String permission;
@XmlElementWrapper(name = "filters")
@XmlElement(name = "filter")
private List<Filter> filterList;
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public String getPermission() {
return permission;
}
public void setPermission(String permission) {
this.permission = permission;
}
public List<Filter> getFilterList() {
return filterList;
}
public void setFilters(List<Filter> filterList) {
this.filterList = filterList;
}
}

@ -0,0 +1,78 @@
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
/**
* Java class for params complex type.
*
* The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <xs:element name="params">
* <xs:complexType>
* <xs:sequence>
* <xs:element name="queryParams" type="{}QueryParameters"/>
* <xs:element name="formParams" type="{}FormParameters"/>
* <xs:element name="uiParams" type="{}UIParameters"/>
* </xs:sequence>
* </xs:complexType>
* </pre>
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "params")
public class Params {
@XmlElement(name = "queryParams")
private QueryParameters queryParameters;
@XmlElement(name = "formParams")
private FormParameters formParameters;
@XmlElement(name = "uiParams")
private UIParameters uiParameters;
public QueryParameters getQueryParameters() {
return queryParameters;
}
public void setQueryParameters(QueryParameters queryParameters) {
this.queryParameters = queryParameters;
}
public FormParameters getFormParameters() {
return formParameters;
}
public void setFormParameters(FormParameters formParameters) {
this.formParameters = formParameters;
}
public UIParameters getUiParameters() {
return uiParameters;
}
public void setUiParameters(UIParameters uiParameters) {
this.uiParameters = uiParameters;
}
}

@ -14,8 +14,26 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
@ -27,26 +45,24 @@ import java.util.List;
/**
* <p>Java class for QueryParameters complex type.
* Java class for queryParams complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
* The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType name="QueryParameters">
* &lt;complexContent>
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* &lt;sequence>
* &lt;element name="Parameter" type="{http://www.w3.org/2001/XMLSchema}string"/>
* &lt;/sequence>
* &lt;/restriction>
* &lt;/complexContent>
* &lt;/complexType>
* <complexType name="queryParams">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="Parameter" type="{http://www.w3.org/2001/XMLSchema}string"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "QueryParameters", propOrder = {
@XmlType(name = "queryParams", propOrder = {
"parameter"
})
public class QueryParameters {
@ -56,7 +72,7 @@ public class QueryParameters {
public List<String> getParameter() {
if (parameter == null) {
parameter = new ArrayList<String>();
parameter = new ArrayList<>();
}
return this.parameter;
}

@ -0,0 +1,134 @@
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import java.util.List;
/**
* Java class for uiParams complex type.
*
* The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <xs:element name="uiParam" maxOccurs="unbounded">
* <xs:complexType>
* <xs:sequence>
* <xs:element name="type" type="xs:string" />
* <xs:element name="name" type="xs:string" />
* <xs:element name="id" type="xs:string" />
* <xs:element name="values">
* <xs:complexType>
* <xs:sequence>
* <xs:element name="value" type="xs:string" />
* </xs:sequence>
* </xs:complexType>
* </xs:element>
* </xs:sequence>
* <xs:attribute name="optional" type="xs:string" />
* </xs:complexType>
* </xs:element>
* </pre>
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
public class UIParameter {
@XmlElement(name = "id", required = true)
protected String id;
@XmlAttribute(name = "optional", required = true)
private boolean optional;
@XmlElement(name = "type", required = true)
protected String type;
@XmlElement(name = "name")
protected String name;
@XmlElement(name = "label")
private String label;
@XmlElement(name = "helper")
private String helper;
@XmlElementWrapper(name = "values")
@XmlElement(name = "value")
protected List<String> value;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public String getHelper() {
return helper;
}
public void setHelper(String helper) {
this.helper = helper;
}
public List<String> getValue() {
return value;
}
public void setValue(List<String> value) {
this.value = value;
}
public boolean isOptional() {
return optional;
}
public void setOptional(boolean optional) {
this.optional = optional;
}
}

@ -0,0 +1,48 @@
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.extensions.device.type.template.config;
import javax.xml.bind.annotation.XmlElement;
import java.util.List;
/**
* Java class for uiParams complex type.
*
* The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <xs:element name="uiParams">
* <xs:complexType>
* <xs:sequence>
* <xs:element name="uiParam" type="{}UIParameter"/>
* </xs:sequence>
* </xs:complexType>
* </xs:element>
* </pre>
*
*/
public class UIParameters {
@XmlElement(name = "uiParam")
private List<UIParameter> uiParams;
public List<UIParameter> getUiParameterList() {
return this.uiParams;
}
}

@ -16,12 +16,35 @@
* under the License.
*
*/
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.extensions.device.type.template.feature;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.apache.commons.lang.StringUtils;
import org.wso2.carbon.device.mgt.common.Feature;
import org.wso2.carbon.device.mgt.common.FeatureManager;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.Operation;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.OperationMetadata;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.Params;
import org.wso2.carbon.device.mgt.extensions.device.type.template.config.UIParameter;
import java.util.ArrayList;
import java.util.HashMap;
@ -37,10 +60,15 @@ public class ConfigurationBasedFeatureManager implements FeatureManager {
private List<Feature> features = new ArrayList<>();
private static final String METHOD = "method";
private static final String URI = "uri";
private static final String OPERATION_META = "operationMeta";
private static final String CONTENT_TYPE = "contentType";
private static final String PERMISSION = "permission";
private static final String ICON = "icon";
private static final String FILTERS = "filters";
private static final String PATH_PARAMS = "pathParams";
private static final String QUERY_PARAMS = "queryParams";
private static final String FORM_PARAMS = "formParams";
private static final String UI_PARAMS = "uiParams";
private static final Pattern PATH_PARAM_REGEX = Pattern.compile("\\{(.*?)\\}");
public ConfigurationBasedFeatureManager(
@ -50,6 +78,7 @@ public class ConfigurationBasedFeatureManager implements FeatureManager {
deviceFeature.setCode(feature.getCode());
deviceFeature.setName(feature.getName());
deviceFeature.setDescription(feature.getDescription());
deviceFeature.setType(feature.getType());
Operation operation = feature.getOperation();
List<Feature.MetadataEntry> metadataEntries = null;
if (feature.getMetaData() != null) {
@ -64,31 +93,53 @@ public class ConfigurationBasedFeatureManager implements FeatureManager {
}
}
if (operation != null) {
Map<String, Object> apiParams = new HashMap<>();
apiParams.put(METHOD, operation.getMethod().toUpperCase());
apiParams.put(URI, operation.getContext());
apiParams.put(CONTENT_TYPE, operation.getType());
deviceFeature.setHidden(operation.isHidden());
Map<String, Object> operationMeta = new HashMap<>();
OperationMetadata metadata = operation.getMetadata();
List<String> pathParams = new ArrayList<>();
List<String> queryParams = new ArrayList<>();
List<String> formParams = new ArrayList<>();
setPathParams(operation.getContext(), pathParams);
apiParams.put(PATH_PARAMS, pathParams);
if (operation.getQueryParameters() != null) {
queryParams = operation.getQueryParameters().getParameter();
if (metadata != null) {
operationMeta.put(METHOD, metadata.getMethod().toUpperCase());
operationMeta.put(URI, metadata.getUri());
if (StringUtils.isNotEmpty(metadata.getContentType())) {
operationMeta.put(CONTENT_TYPE, metadata.getContentType());
}
if (StringUtils.isNotEmpty(metadata.getPermission())) {
operationMeta.put(PERMISSION, metadata.getPermission());
}
if (metadata.getFilterList() != null && metadata.getFilterList().size() > 0) {
operationMeta.put(FILTERS, metadata.getFilterList());
}
operationMeta.put(ICON, operation.getIcon());
setPathParams(metadata.getUri(), pathParams);
}
apiParams.put(QUERY_PARAMS, queryParams);
if (operation.getFormParameters() != null) {
formParams = operation.getFormParameters().getParameter();
operationMeta.put(PATH_PARAMS, pathParams);
Params params = operation.getParams();
if (params != null) {
List<String> queryParams = params.getQueryParameters() != null ?
params.getQueryParameters().getParameter() : new ArrayList<>();
List<String> formParams = params.getFormParameters() != null ?
params.getFormParameters().getParameter() : new ArrayList<>();
List<UIParameter> uiParams = params.getUiParameters() != null ?
params.getUiParameters().getUiParameterList() : new ArrayList<>();
operationMeta.put(QUERY_PARAMS, queryParams);
operationMeta.put(UI_PARAMS, uiParams);
operationMeta.put(FORM_PARAMS, formParams);
}
apiParams.put(FORM_PARAMS, formParams);
if (metadataEntries == null) {
metadataEntries = new ArrayList<>();
}
Feature.MetadataEntry metadataEntry = new Feature.MetadataEntry();
metadataEntry.setId(-1);
metadataEntry.setValue(apiParams);
metadataEntry.setId(0);
metadataEntry.setName(OPERATION_META);
metadataEntry.setValue(operationMeta);
metadataEntries.add(metadataEntry);
deviceFeature.setMetadataEntries(metadataEntries);
} else {
deviceFeature.setHidden(true);
}
this.features.add(deviceFeature);
}
@ -120,6 +171,49 @@ public class ConfigurationBasedFeatureManager implements FeatureManager {
return features;
}
@Override
public List<Feature> getFeatures(String type) throws DeviceManagementException {
if (StringUtils.isEmpty(type)) {
return this.getFeatures();
}
if (features == null) {
return null;
} else {
List<Feature> filteredFeatures = new ArrayList<>();
for (Feature feature : this.getFeatures()) {
if (type.equals(feature.getType())) {
filteredFeatures.add(feature);
}
}
return filteredFeatures;
}
}
@Override
public List<Feature> getFeatures(String type, boolean isHidden) throws DeviceManagementException {
if (features == null) {
return null;
} else {
List<Feature> filteredFeatures = new ArrayList<>();
if (StringUtils.isEmpty(type)) {
for (Feature feature : this.getFeatures()) {
if (isHidden == feature.isHidden()) {
filteredFeatures.add(feature);
}
}
return filteredFeatures;
} else {
for (Feature feature : this.getFeatures()) {
if (isHidden == feature.isHidden() && type.equals(feature.getType())) {
filteredFeatures.add(feature);
}
}
return filteredFeatures;
}
}
}
@Override
public boolean removeFeature(String name) throws DeviceManagementException {
return false;

@ -92,256 +92,474 @@
</DataSource>
<Features>
<Feature code="DEVICE_RING">
<Feature type="operation" code="DEVICE_RING">
<Name>Ring</Name>
<Description>Ring the device</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/ring" method="POST" type="application/json">
<Operation hidden="false" icon="fw-dial-up">
<params/>
<metadata>
<uri>/api/device-mgt/android/v1.0/admin/devices/ring</uri>
<method>POST</method>
<contentType>application/json</contentType>
<permission>/device-mgt/devices/owning-device/operations/android/ring</permission>
</metadata>
</Operation>
<MetaData>
<Property>test</Property>
</MetaData>
</Feature>
<Feature code="DEVICE_LOCK">
<Feature type="operation" code="DEVICE_LOCK">
<Name>Device Lock</Name>
<Description>Lock the device</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/lock-devices" method="POST" type="application/json">
<Operation hidden="false" icon="fw-lock">
<params>
<uiParams>
<uiParam optional="true">
<type>text</type>
<id>lock-message</id>
<label>Message to be sent to the device</label>
</uiParam>
<uiParam optional="true">
<type>checkbox</type>
<id>hard-lock</id>
<label>Hard lock enabled</label>
</uiParam>
</uiParams>
</params>
<metadata>
<uri>/api/device-mgt/android/v1.0/admin/devices/lock-devices</uri>
<method>POST</method>
<contentType>application/json</contentType>
<permission>/device-mgt/devices/owning-device/operations/android/ring</permission>
</metadata>
</Operation>
</Feature>
<Feature code="DEVICE_LOCATION">
<Feature type="operation" code="DEVICE_LOCATION">
<Name>Location</Name>
<Description>Request coordinates of device location</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/location" method="POST" type="application/json">
<Operation hidden="false" icon="fw-map-location">
<params/>
<metadata>
<uri>/api/device-mgt/android/v1.0/admin/devices/location</uri>
<method>POST</method>
<contentType>application/json</contentType>
<permission>/device-mgt/devices/owning-device/operations/android/location</permission>
</metadata>
</Operation>
</Feature>
<Feature code="CLEAR_PASSWORD">
<Feature type="operation" code="CLEAR_PASSWORD">
<Name>Clear Password</Name>
<Description>Clear current password</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/clear-password" method="POST" type="application/json">
<Description>Clear current password (This functionality is only working with profile owners from Android 7.0 API 24 onwards.)</Description>
<Operation hidden="false" icon="fw-clear">
<params/>
<metadata>
<uri>/api/device-mgt/android/v1.0/admin/devices/clear-password</uri>
<method>POST</method>
<contentType>application/json</contentType>
<permission>/device-mgt/devices/owning-device/operations/android/clear-passwor</permission>
</metadata>
</Operation>
</Feature>
<Feature code="DEVICE_REBOOT">
<Feature type="operation" code="DEVICE_REBOOT">
<Name>Reboot</Name>
<Description>Reboot the device</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/reboot" method="POST" type="application/json">
<Operation hidden="false" icon="fw-refresh">
<params/>
<metadata>
<uri>/api/device-mgt/android/v1.0/admin/devices/reboot</uri>
<method>POST</method>
<contentType>application/json</contentType>
<permission>/device-mgt/devices/owning-device/operations/android/reboot</permission>
<filters>
<filter>
<property>ownership</property>
<value>COPE</value>
<description>This feature is only available in COPE/COSU</description>
</filter>
</filters>
</metadata>
</Operation>
</Feature>
<Feature code="UPGRADE_FIRMWARE">
<Feature type="operation" code="UPGRADE_FIRMWARE">
<Name>Upgrade Firmware</Name>
<Description>Upgrade Firmware</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/upgrade-firmware" method="POST" type="application/json">
<Operation hidden="false" icon="fw-hardware">
<params>
<uiParams>
<uiParam optional="true">
<type>checkbox</type>
<id>immediate</id>
<label>Instant Upgrade</label>
<helper>Once enabled, device firmware upgrade process will start instantly.</helper>
</uiParam>
<uiParam optional="false">
<type>text</type>
<id>schedule</id>
<label>Enter the date and time to schedule firmware upgrade.</label>
</uiParam>
<uiParam optional="true">
<type>text</type>
<id>server</id>
<label>Enter firmware upgrade server URL (ie. http://abc.com or http://abc.com/ota)</label>
</uiParam>
</uiParams>
</params>
<metadata>
<uri>/api/device-mgt/android/v1.0/admin/devices/reboot</uri>
<method>POST</method>
<contentType>application/json</contentType>
<permission>/device-mgt/devices/owning-device/operations/android/upgrade-firmware</permission>
<filters>
<filter>
<property>ownership</property>
<value>COPE</value>
<description>This feature is only available in COPE/COSU</description>
</filter>
</filters>
</metadata>
</Operation>
</Feature>
<Feature code="DEVICE_MUTE">
<Feature type="operation" code="DEVICE_MUTE">
<Name>Mute</Name>
<Description>Enable mute in the device</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/mute" method="POST" type="application/json">
<Operation hidden="false" icon="fw-mute">
<params/>
<metadata>
<uri>/api/device-mgt/android/v1.0/admin/devices/mute</uri>
<method>POST</method>
<contentType>application/json</contentType>
<permission>/device-mgt/devices/owning-device/operations/android/mute</permission>
</metadata>
</Operation>
</Feature>
<Feature code="NOTIFICATION">
<Feature type="operation" code="NOTIFICATION">
<Name>Message</Name>
<Description>Send message</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/send-notification" method="POST" type="application/json">
<Operation hidden="false" icon="fw-message">
<params>
<uiParams>
<uiParam optional="false">
<type>text</type>
<id>messageTitle</id>
<label>Title Here...</label>
</uiParam>
<uiParam optional="false">
<type>text</type>
<id>messageText</id>
<label>Message Here...</label>
</uiParam>
</uiParams>
</params>
<metadata>
<uri>/api/device-mgt/android/v1.0/admin/devices/send-notification</uri>
<method>POST</method>
<contentType>application/json</contentType>
<permission>/device-mgt/devices/owning-device/operations/android/send-notification</permission>
</metadata>
</Operation>
</Feature>
<Feature code="CHANGE_LOCK_CODE">
<Feature type="operation" code="CHANGE_LOCK_CODE">
<Name>Change Lock-code</Name>
<Description>Change current lock code</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/change-lock-code" method="POST" type="application/json">
<Description>Change current lock code (This functionality is only working with profile owners from Android 7.0 API 24 onwards.)</Description>
<Operation hidden="false" icon="fw-security">
<params/>
<metadata>
<uri>/api/device-mgt/android/v1.0/admin/devices/change-lock-code</uri>
<method>POST</method>
<contentType>application/json</contentType>
<permission>/device-mgt/devices/owning-device/operations/android/change-lock-code</permission>
</metadata>
</Operation>
</Feature>
<Feature code="ENTERPRISE_WIPE">
<Feature type="operation" code="FILE_TRANSFER">
<Name>File Transfer</Name>
<Description>Transfer file to the device</Description>
<Operation hidden="false" icon="fw-save">
<params>
<uiParams>
<uiParam optional="false">
<type>radio</type>
<name>directionSelection</name>
<id>upload</id>
<values>
<value>To device</value>
</values>
</uiParam>
<uiParam optional="false">
<type>radio</type>
<name>directionSelection</name>
<id>download</id>
<values>
<value>From device</value>
</values>
</uiParam>
<uiParam optional="false">
<type>select</type>
<name>protocolSelection</name>
<id>protocol</id>
<values>
<value>HTTP</value>
<value>FTP</value>
<value>SFTP</value>
</values>
<label>Protocol</label>
</uiParam>
<uiParam optional="false">
<type>text</type>
<id>fileURL</id>
<label>URL to upload file from device</label>
</uiParam>
<uiParam optional="false">
<type>info</type>
<id>defaultFileLocation</id>
<label>File will be saved in Default download directory if not specified.</label>
</uiParam>
<uiParam optional="false">
<type>text</type>
<id>fileLocation</id>
<label>File location in the device</label>
</uiParam>
<uiParam optional="false">
<type>checkbox</type>
<id>authentication</id>
<label>Authentication required</label>
</uiParam>
<uiParam optional="false">
<type>text</type>
<id>userName</id>
<label>Username</label>
</uiParam>
<uiParam optional="false">
<type>password</type>
<id>ftpPassword</id>
<label>Password (Ignore if not needed)</label>
</uiParam>
</uiParams>
</params>
<metadata>
<uri>/api/device-mgt/android/v1.0/admin/devices/file-transfer</uri>
<method>POST</method>
<contentType>application/json</contentType>
<permission>/device-mgt/devices/owning-device/operations/android/file-transfer</permission>
</metadata>
</Operation>
</Feature>
<Feature type="operation" code="ENTERPRISE_WIPE">
<Name>Enterprise Wipe</Name>
<Description>Remove enterprise applications</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/enterprise-wipe" method="POST" type="application/json">
<Operation hidden="false" icon="fw-block">
<params/>
<metadata>
<uri>/api/device-mgt/android/v1.0/admin/devices/enterprise-wipe</uri>
<method>POST</method>
<contentType>application/json</contentType>
<permission>/device-mgt/devices/owning-device/operations/android/enterprise-wipe</permission>
</metadata>
</Operation>
</Feature>
<Feature code="WIPE_DATA">
<Feature type="operation" code="WIPE_DATA">
<Name>Wipe Data</Name>
<Description>Factory reset the device</Description>
<Operation context="/api/device-mgt/android/v1.0/admin/devices/wipe" method="POST" type="application/json">
<Operation hidden="false" icon="fw-delete">
<params>
<uiParams>
<uiParam optional="false">
<type>text</type>
<id>pin</id>
<label>Enter PIN code* of the device.</label>
</uiParam>
</uiParams>
</params>
<metadata>
<uri>/api/device-mgt/android/v1.0/admin/devices/wipe</uri>
<method>POST</method>
<contentType>application/json</contentType>
<permission>/device-mgt/devices/owning-device/operations/android/wipe</permission>
</metadata>
</Operation>
</Feature>
<Feature code="WIFI">
<Feature type="policy" code="WIFI">
<Name>Wifi</Name>
<Description>Setting up wifi configuration</Description>
</Feature>
<Feature code="CAMERA">
<Feature type="policy" code="GLOBAL_PROXY">
<Name>Global Proxy</Name>
<Description>Setting up a network-independent global HTTP proxy on a device.</Description>
</Feature>
<Feature type="policy" code="CAMERA">
<Name>Camera</Name>
<Description>Enable or disable camera</Description>
</Feature>
<Feature code="EMAIL">
<Feature type="policy" code="EMAIL">
<Name>Email</Name>
<Description>Configure email settings</Description>
</Feature>
<Feature code="DEVICE_INFO">
<Feature type="operation" code="DEVICE_INFO">
<Name>Device info</Name>
<Description>Request device information</Description>
</Feature>
<Feature code="APPLICATION_LIST">
<Feature type="operation" code="APPLICATION_LIST">
<Name>Application List</Name>
<Description>Request list of current installed applications</Description>
</Feature>
<Feature code="INSTALL_APPLICATION">
<Feature type="operation" code="INSTALL_APPLICATION">
<Name>Install App</Name>
<Description>Install App</Description>
</Feature>
<Feature code="UNINSTALL_APPLICATION">
<Feature type="operation" code="UNINSTALL_APPLICATION">
<Name>Uninstall App</Name>
<Description>Uninstall App</Description>
</Feature>
<Feature code="BLACKLIST_APPLICATIONS">
<Feature type="policy" code="BLACKLIST_APPLICATIONS">
<Name>Blacklist app</Name>
<Description>Blacklist applications</Description>
</Feature>
<Feature code="ENCRYPT_STORAGE">
<Feature type="policy" code="ENCRYPT_STORAGE">
<Name>Encrypt Storage</Name>
<Description>Encrypt storage</Description>
</Feature>
<Feature code="PASSCODE_POLICY">
<Feature type="policy" code="PASSCODE_POLICY">
<Name>Password Policy</Name>
<Description>Set passcode policy</Description>
</Feature>
<Feature code="VPN">
<Feature type="policy" code="VPN">
<Name>Configure VPN</Name>
<Description>Configure VPN settings</Description>
</Feature>
<Feature code="DISALLOW_ADJUST_VOLUME">
<Feature type="policy" code="DISALLOW_ADJUST_VOLUME">
<Name>Disallow user to change volume</Name>
<Description>Allow or disallow user to change volume"</Description>
</Feature>
<Feature code="DISALLOW_CONFIG_BLUETOOTH">
<Feature type="policy" code="DISALLOW_CONFIG_BLUETOOTH">
<Name>Disallow bluetooth configuration</Name>
<Description>Allow or disallow bluetooth configuration</Description>
</Feature>
<Feature code="DISALLOW_CONFIG_CELL_BROADCASTS">
<Feature type="policy" code="DISALLOW_CONFIG_CELL_BROADCASTS">
<Name>Disallow user to change cell broadcast configurations</Name>
<Description>Allow or disallow user to change cell broadcast configurations</Description>
</Feature>
<Feature code="DISALLOW_CONFIG_CREDENTIALS">
<Feature type="policy" code="DISALLOW_CONFIG_CREDENTIALS">
<Name>Disallow user to change user credentials</Name>
<Description>Allow or disallow user to change user credentials</Description>
</Feature>
<Feature code="DISALLOW_CONFIG_MOBILE_NETWORKS">
<Feature type="policy" code="DISALLOW_CONFIG_MOBILE_NETWORKS">
<Name>Disallow user to change mobile networks configurations</Name>
<Description>Allow or disallow user to change mobile networks configurations</Description>
</Feature>
<Feature code="DISALLOW_CONFIG_TETHERING">
<Feature type="policy" code="DISALLOW_CONFIG_TETHERING">
<Name>Disallow user to change tethering configurations</Name>
<Description>Allow or disallow user to change tethering configurations</Description>
</Feature>
<Feature code="DISALLOW_CONFIG_VPN">
<Feature type="policy" code="DISALLOW_CONFIG_VPN">
<Name>Disallow user to change VPN configurations</Name>
<Description>Allow or disallow user to change VPN configurations</Description>
</Feature>
<Feature code="DISALLOW_CONFIG_WIFI">
<Feature type="policy" code="DISALLOW_CONFIG_WIFI">
<Name>Disallow user to change WIFI configurations</Name>
<Description>Allow or disallow user to change WIFI configurations</Description>
</Feature>
<Feature code="DISALLOW_APPS_CONTROL">
<Feature type="policy" code="DISALLOW_APPS_CONTROL">
<Name>Disallow user to change app control</Name>
<Description>Allow or disallow user to change app control</Description>
</Feature>
<Feature code="DISALLOW_CREATE_WINDOWS">
<Feature type="policy" code="DISALLOW_CREATE_WINDOWS">
<Name>Disallow window creation</Name>
<Description>Allow or disallow window creation</Description>
</Feature>
<Feature code="DISALLOW_APPS_CONTROL">
<Feature type="policy" code="DISALLOW_APPS_CONTROL">
<Name>Disallow user to change app control configurations</Name>
<Description>Allow or disallow user to change app control configurations</Description>
</Feature>
<Feature code="DISALLOW_CROSS_PROFILE_COPY_PASTE">
<Feature type="policy" code="DISALLOW_CROSS_PROFILE_COPY_PASTE">
<Name>Disallow cross profile copy paste</Name>
<Description>Allow or disallow cross profile copy paste</Description>
</Feature>
<Feature code="DISALLOW_DEBUGGING_FEATURES">
<Feature type="policy" code="DISALLOW_DEBUGGING_FEATURES">
<Name>Disallow debugging features</Name>
<Description>Allow or disallow debugging features</Description>
</Feature>
<Feature code="DISALLOW_FACTORY_RESET">
<Feature type="policy" code="DISALLOW_FACTORY_RESET">
<Name>Disallow factory reset</Name>
<Description>Allow or disallow factory reset</Description>
</Feature>
<Feature code="DISALLOW_ADD_USER">
<Feature type="policy" code="DISALLOW_ADD_USER">
<Name>Disallow add user</Name>
<Description>Allow or disallow add user</Description>
</Feature>
<Feature code="DISALLOW_INSTALL_APPS">
<Feature type="policy" code="DISALLOW_INSTALL_APPS">
<Name>Disallow install apps</Name>
<Description>Allow or disallow install apps</Description>
</Feature>
<Feature code="DISALLOW_INSTALL_UNKNOWN_SOURCES">
<Feature type="policy" code="DISALLOW_INSTALL_UNKNOWN_SOURCES">
<Name>Disallow install unknown sources</Name>
<Description>Allow or disallow install unknown sources</Description>
</Feature>
<Feature code="DISALLOW_MODIFY_ACCOUNTS">
<Feature type="policy" code="DISALLOW_MODIFY_ACCOUNTS">
<Name>Disallow modify account</Name>
<Description>Allow or disallow modify account</Description>
</Feature>
<Feature code="DISALLOW_MOUNT_PHYSICAL_MEDIA">
<Feature type="policy" code="DISALLOW_MOUNT_PHYSICAL_MEDIA">
<Name>Disallow mount physical media</Name>
<Description>Allow or disallow mount physical media</Description>
</Feature>
<Feature code="DISALLOW_NETWORK_RESET">
<Feature type="policy" code="DISALLOW_NETWORK_RESET">
<Name>Disallow network reset</Name>
<Description>Allow or disallow network reset</Description>
</Feature>
<Feature code="DISALLOW_OUTGOING_BEAM">
<Feature type="policy" code="DISALLOW_OUTGOING_BEAM">
<Name>Disallow outgoing beam</Name>
<Description>Allow or disallow outgoing beam</Description>
</Feature>
<Feature code="DISALLOW_OUTGOING_CALLS">
<Feature type="policy" code="DISALLOW_OUTGOING_CALLS">
<Name>Disallow outgoing calls</Name>
<Description>Allow or disallow outgoing calls</Description>
</Feature>
<Feature code="DISALLOW_REMOVE_USER">
<Feature type="policy" code="DISALLOW_REMOVE_USER">
<Name>Disallow remove users</Name>
<Description>Allow or disallow remove users</Description>
</Feature>
<Feature code="DISALLOW_SAFE_BOOT">
<Feature type="policy" code="DISALLOW_SAFE_BOOT">
<Name>Disallow safe boot</Name>
<Description>Allow or disallow safe boot</Description>
</Feature>
<Feature code="DISALLOW_SHARE_LOCATION">
<Feature type="policy" code="DISALLOW_SHARE_LOCATION">
<Name>Disallow share location</Name>
<Description>Allow or disallow share location</Description>
</Feature>
<Feature code="DISALLOW_SMS">
<Feature type="policy" code="DISALLOW_SMS">
<Name>Disallow sms</Name>
<Description>Allow or disallow sms</Description>
</Feature>
<Feature code="DISALLOW_UNINSTALL_APPS">
<Feature type="policy" code="DISALLOW_UNINSTALL_APPS">
<Name>Disallow uninstall app</Name>
<Description>Allow or disallow uninstall app</Description>
</Feature>
<Feature code="DISALLOW_UNMUTE_MICROPHONE">
<Feature type="policy" code="DISALLOW_UNMUTE_MICROPHONE">
<Name>Disallow unmute mic</Name>
<Description>Allow or disallow unmute mic</Description>
</Feature>
<Feature code="DISALLOW_USB_FILE_TRANSFER">
<Feature type="policy" code="DISALLOW_USB_FILE_TRANSFER">
<Name>Disallow usb file transfer</Name>
<Description>Allow or disallow usb file transfer</Description>
</Feature>
<Feature code="ALLOW_PARENT_PROFILE_APP_LINKING">
<Feature type="policy" code="ALLOW_PARENT_PROFILE_APP_LINKING">
<Name>Disallow parent profile app linking</Name>
<Description>Allow or disallow parent profile app linking</Description>
</Feature>
<Feature code="ENSURE_VERIFY_APPS">
<Feature type="policy" code="ENSURE_VERIFY_APPS">
<Name>Disallow ensure verify apps</Name>
<Description>Allow or disallow ensure verify apps</Description>
</Feature>
<Feature code="AUTO_TIME">
<Feature type="policy" code="AUTO_TIME">
<Name>Disallow auto timing</Name>
<Description>Allow or disallow auto timing</Description>
</Feature>
<Feature code="REMOVE_DEVICE_OWNER">
<Feature type="policy" code="REMOVE_DEVICE_OWNER">
<Name>Remove device owner</Name>
<Description>Remove device owner</Description>
</Feature>
<Feature code="LOGCAT">
<Feature type="policy" code="LOGCAT">
<Name>Fetch device logcat</Name>
<Description>Fetch device logcat</Description>
</Feature>
<Feature code="DEVICE_UNLOCK">
<Feature type="operation" hidden="false" code="DEVICE_UNLOCK">
<Name>Unlock the device</Name>
<Description>Unlock the device</Description>
</Feature>

@ -19,15 +19,15 @@
-->
<DeviceTypeConfiguration name="android_sense">
<Features>
<Feature code="keywords">
<Feature type="operation" code="keywords">
<Name>Add Keywords</Name>
<Description>Send keywords to the device</Description>
</Feature>
<Feature code="threshold">
<Feature type="operation" code="threshold">
<Name>Add Threshold</Name>
<Description>Send Threshold to the device</Description>
</Feature>
<Feature code="remove_words">
<Feature type="operation" code="remove_words">
<Name>Remove words</Name>
<Description>Remove Threshold from the device</Description>
</Feature>

@ -19,13 +19,19 @@
-->
<DeviceTypeConfiguration name="arduino">
<Features>
<Feature code="bulb">
<Feature type="operation" code="bulb">
<Name>Control Bulb</Name>
<Description>Control Bulb on Arduino Uno</Description>
<Operation context="/arduino/device/{deviceId}/bulb" method="POST">
<QueryParameters>
<Parameter>state</Parameter>
</QueryParameters>
<Operation hidden="true">
<params>
<queryParams>
<Parameter>state</Parameter>
</queryParams>
</params>
<metadata>
<uri>/arduino/device/{deviceId}/bulb</uri>
<method>POST</method>
</metadata>
</Operation>
</Feature>
</Features>

@ -21,13 +21,19 @@
<DeviceDetails table-id="DEFECTIVE_DEVICE"/>
<Features>
<Feature code="bulb">
<Feature type="operation" code="bulb">
<Name>Control Bulb</Name>
<Description>Control Bulb on Arduino Uno</Description>
<Operation context="/arduino/device/{deviceId}/bulb" method="POST">
<QueryParameters>
<Parameter>state</Parameter>
</QueryParameters>
<Operation hidden="true">
<params>
<queryParams>
<Parameter>state</Parameter>
</queryParams>
</params>
<metadata>
<uri>/arduino/device/{deviceId}/bulb</uri>
<method>POST</method>
</metadata>
</Operation>
</Feature>
</Features>

@ -27,13 +27,19 @@
</DeviceDetails>
<Features>
<Feature code="bulb">
<Feature type="operation" code="bulb">
<Name>Control Bulb</Name>
<Description>Control Bulb on Arduino Uno</Description>
<Operation context="/arduino/device/{deviceId}/bulb" method="POST">
<QueryParameters>
<Parameter>state</Parameter>
</QueryParameters>
<Operation hidden="false">
<params>
<queryParams>
<Parameter>state</Parameter>
</queryParams>
</params>
<metadata>
<uri>/arduino/device/{deviceId}/bulb</uri>
<method>POST</method>
</metadata>
</Operation>
</Feature>
</Features>

@ -19,13 +19,19 @@
-->
<DeviceTypeConfiguration name="raspberrypi">
<Features>
<Feature code="bulb">
<Feature type="operation" code="bulb">
<Name>Control Bulb</Name>
<Description>Control Bulb on Raspberrypi</Description>
<Operation context="/raspberrypi/device/{deviceId}/bulb" method="POST">
<QueryParameters>
<Parameter>state</Parameter>
</QueryParameters>
<Operation hidden="false">
<params>
<queryParams>
<Parameter>state</Parameter>
</queryParams>
</params>
<metadata>
<uri>/raspberrypi/device/{deviceId}/bulb</uri>
<method>POST</method>
</metadata>
</Operation>
</Feature>
</Features>

@ -31,16 +31,23 @@
<!--END-->
<Features>
<Feature code="abc">
<Feature type="operation" hidden="true" code="abc">
<Name>abc</Name>
<Description>this is a feature</Description>
<Operation context="/bulb/{state}" method="PUT" type="application/json">
<QueryParameters>
<Parameter>deviceId</Parameter>
</QueryParameters>
<FormParameters>
<Parameter>test</Parameter>
</FormParameters>
<Operation hidden="true">
<params>
<queryParams>
<Parameter>deviceId</Parameter>
</queryParams>
<formParams>
<Parameter>test</Parameter>
</formParams>
</params>
<metadata>
<uri>/bulb/{state}</uri>
<method>POST</method>
<contentType>application/json</contentType>
</metadata>
</Operation>
</Feature>
</Features>

@ -400,7 +400,7 @@ CREATE TABLE IF NOT EXISTS DM_DEVICE_INFO (
ID INTEGER AUTO_INCREMENT NOT NULL,
DEVICE_ID INT NULL,
KEY_FIELD VARCHAR(45) NULL,
VALUE_FIELD VARCHAR(100) NULL,
VALUE_FIELD VARCHAR(1000) NULL,
PRIMARY KEY (ID),
CONSTRAINT DM_DEVICE_INFO_DEVICE
FOREIGN KEY (DEVICE_ID)

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save