Compare commits

Invalid templates have been ignored

1 invalid template(s) found pull_request_template.md: frontmatter must start with a separator line

..

19 Commits

Author SHA1 Message Date
Arshana 30837f2f3d Add missing cope
3 months ago
Lasantha Dharmakeerthi a42e4ec411 Add special warning message for Factory Reset, Enterprise Wipe, Disneroll operations.
3 months ago
Nipuni Kavindya 77a521e550 Add special warning message for Factory Reset, Enterprise Wipe, disneroll operations.
3 months ago
Lasantha Dharmakeerthi 00686e75d1 Update operations status when serve startup
3 months ago
Pasindu Rupasinghe 0272bda2ce Get server startup handlers to a single point in device-mgt core
3 months ago
Pasindu Rupasinghe 87b98a6cb5 Use try with resources for dao layer
3 months ago
Pasindu Rupasinghe 6d324c084a Throw msg and the exception in relevent places
3 months ago
Pasindu Rupasinghe f59208f6e7 Save OperationStartupHandler in data holder
3 months ago
Lasantha Dharmakeerthi f14e2cecdf Add tool tip component to operation features
3 months ago
Oshani Silva 21290dfba6 Merge branch 'master' of ssh://repository.entgra.net:222/community/device-mgt-core into secure-folder-policy
3 months ago
Pasindu Rupasinghe c37cf31ffe Update operations status when serve startup
3 months ago
Lasantha Dharmakeerthi f58721b3b6 Implement the search API for Subscription details view
3 months ago
Lasantha Dharmakeerthi 470f9c52a3 Fix search by middle part of the username is not working in uninstall table in app store
3 months ago
Nipuni Kavindya 320d5215de Implement the search API for Subscription details view
3 months ago
Lasantha Dharmakeerthi dec953b638 Update release rating data type
3 months ago
Rajitha Kumara 9ce605d883 Update release rating data type
3 months ago
Lasantha Dharmakeerthi 974fc46e54 Fix data type inconsistency in tag db scripts
3 months ago
Nipuni Kavindya afa3294555 Fix search by middle part of the username is not working in uninstall table in app store.
3 months ago
Gimhan Wijayawardana b8542bfffd Fix data type inconsistency in tag db scripts
3 months ago

@ -22,7 +22,7 @@ package io.entgra.device.mgt.core.application.mgt.common;
public class ReleaseVersionInfo { public class ReleaseVersionInfo {
private String version; private String version;
private String releaseType; private String releaseType;
private String rating; private double rating;
private String state; private String state;
private String uuid; private String uuid;
@ -38,11 +38,11 @@ public class ReleaseVersionInfo {
return releaseType; return releaseType;
} }
public String getRating() { public double getRating() {
return rating; return rating;
} }
public void setRating(String rating) { public void setRating(double rating) {
this.rating = rating; this.rating = rating;
} }

@ -187,11 +187,14 @@ public interface SubscriptionManager {
* @param subType subscription type of the application. * @param subType subscription type of the application.
* @param offsetValue offset value for get paginated request. * @param offsetValue offset value for get paginated request.
* @param limitValue limit value for get paginated request. * @param limitValue limit value for get paginated request.
* @param uninstalled a Boolean flag indicating the filter criteria for retrieve subscription data
* @param searchName an optional search term to filter the results by name. If null or empty, no filtering by name is applied.
* @return {@link PaginationResult} pagination result of the category details. * @return {@link PaginationResult} pagination result of the category details.
* @throws {@link ApplicationManagementException} Exception of the application management * @throws {@link ApplicationManagementException} Exception of the application management
*/ */
PaginationResult getAppInstalledSubscribers(int offsetValue, int limitValue, String appUUID, PaginationResult getAppInstalledSubscribers(int offsetValue, int limitValue, String appUUID,
String subType) throws ApplicationManagementException; String subType, Boolean uninstalled, String searchName)
throws ApplicationManagementException;
/** /**
* This method is responsible to provide application subscription data for given application release UUID. * This method is responsible to provide application subscription data for given application release UUID.

@ -198,14 +198,33 @@ public interface SubscriptionDAO {
* @param offsetValue offset value for get paginated result * @param offsetValue offset value for get paginated result
* @param limitValue limit value for get paginated result * @param limitValue limit value for get paginated result
* @param appReleaseId id of the application release. * @param appReleaseId id of the application release.
* @param uninstalled a Boolean flag indicating the filter criteria for getting users:
* - `true` to get only unsubscribed users,
* - `false` to get only subscribed users,
* - `null` to get all users regardless of their unsubscription status.
* @param searchName an optional search term to filter the results by username.
* @return subscribedUsers - list of app subscribed users. * @return subscribedUsers - list of app subscribed users.
* @throws {@link ApplicationManagementDAOException} if connections establishment fails. * @throws {@link ApplicationManagementDAOException} if connections establishment fails.
*/ */
List<String> getAppSubscribedUsers(int offsetValue, int limitValue, int appReleaseId, List<String> getAppSubscribedUsers(int offsetValue, int limitValue, int appReleaseId,
int tenantId) int tenantId, Boolean uninstalled, String searchName)
throws ApplicationManagementDAOException; throws ApplicationManagementDAOException;
int getSubscribedUserCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException; /**
* This method is used to get the count of users who are subscribed or unsubscribed to a specific application release.
*
* @param appReleaseId the ID of the application release for which the user count is to be retrieved.
* @param tenantId the ID of the current tenant.
* @param uninstalled a Boolean flag indicating the filter criteria for counting users:
* - `true` to count only unsubscribed users,
* - `false` to count only subscribed users,
* - `null` to count all users regardless of their unsubscription status.
* @param searchName an optional search term to filter the results by username.
* @return the count of users based on the specified criteria.
* @throws ApplicationManagementDAOException if an error occurs while establishing a database connection or executing the query.
*/
int getSubscribedUserCount(int appReleaseId, int tenantId, Boolean uninstalled, String searchName)
throws ApplicationManagementDAOException;
/** /**
* This method is used to get the details of roles * This method is used to get the details of roles
@ -214,14 +233,34 @@ public interface SubscriptionDAO {
* @param offsetValue offset value for get paginated request. * @param offsetValue offset value for get paginated request.
* @param limitValue limit value for get paginated request. * @param limitValue limit value for get paginated request.
* @param appReleaseId id of the application release. * @param appReleaseId id of the application release.
* @param uninstalled a Boolean flag indicating the filter criteria for getting roles:
* - `true` to get only unsubscribed roles,
* - `false` to get only subscribed roles,
* - `null` to get all roles regardless of their unsubscription status.
* @param searchName an optional search term to filter the results by role name.
* @return subscribedRoles - list of app subscribed roles. * @return subscribedRoles - list of app subscribed roles.
* @throws {@link ApplicationManagementDAOException} if connections establishment fails. * @throws {@link ApplicationManagementDAOException} if connections establishment fails.
*/ */
List<String> getAppSubscribedRoles(int offsetValue, int limitValue, int appReleaseId, List<String> getAppSubscribedRoles(int offsetValue, int limitValue, int appReleaseId,
int tenantId) int tenantId, Boolean uninstalled, String searchName)
throws ApplicationManagementDAOException; throws ApplicationManagementDAOException;
int getSubscribedRoleCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException; /**
* This method retrieves the count of roles subscribed to a given application release.
* The count can be filtered based on the unsubscription status.
*
* @param appReleaseId the ID of the application release for which the subscribed roles are counted.
* @param tenantId the ID of the current tenant.
* @param uninstalled a Boolean flag indicating the filter criteria for counting roles:
* - `true` to count only unsubscribed roles,
* - `false` to count only subscribed roles,
* - `null` to count all roles regardless of their unsubscription status.
* @param searchName an optional search term to filter the results by role name.
* @return the count of roles that match the specified criteria.
* @throws ApplicationManagementDAOException if there is an error while accessing the database or processing the request.
*/
int getSubscribedRoleCount(int appReleaseId, int tenantId, Boolean uninstalled, String searchName)
throws ApplicationManagementDAOException;
/** /**
* This method is used to get the details of subscribed groups * This method is used to get the details of subscribed groups
@ -230,13 +269,33 @@ public interface SubscriptionDAO {
* @param offsetValue offset value for get paginated request. * @param offsetValue offset value for get paginated request.
* @param limitValue limit value for get paginated request. * @param limitValue limit value for get paginated request.
* @param appReleaseId id of the application release. * @param appReleaseId id of the application release.
* @param uninstalled a Boolean flag indicating the filter criteria for getting groups:
* - `true` to get only unsubscribed groups,
* - `false` to get only subscribed groups,
* - `null` to get all groups regardless of their unsubscription status.
* @param searchName an optional search term to filter the results by group name.
* @return subscribedGroups - list of app subscribed groups. * @return subscribedGroups - list of app subscribed groups.
* @throws {@link ApplicationManagementDAOException} if connections establishment fails. * @throws {@link ApplicationManagementDAOException} if connections establishment fails.
*/ */
List<String> getAppSubscribedGroups(int offsetValue, int limitValue, int appReleaseId, int tenantId) List<String> getAppSubscribedGroups(int offsetValue, int limitValue, int appReleaseId, int tenantId,
Boolean uninstalled, String searchName)
throws ApplicationManagementDAOException; throws ApplicationManagementDAOException;
int getSubscribedGroupCount(int appReleaseId, int tenantId) throws ApplicationManagementDAOException; /**
* This method is used to get the count of subscribed groups
*
* @param tenantId id of the current tenant
* @param appReleaseId id of the application release.
* @param uninstalled a Boolean flag indicating the filter criteria for counting groups:
* - `true` to count only unsubscribed groups,
* - `false` to count only subscribed groups,
* - `null` to count all groups regardless of their unsubscription status.
* @param searchName an optional search term to filter the results by group name.
* @return subscribedGroups - list of app subscribed groups.
* @throws {@link ApplicationManagementDAOException} if connections establishment fails.
*/
int getSubscribedGroupCount(int appReleaseId, int tenantId,Boolean uninstalled, String searchName)
throws ApplicationManagementDAOException;
/** /**
* This method is used to get the details of subscribed groups * This method is used to get the details of subscribed groups

@ -2075,7 +2075,7 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
releaseVersionInfo = new ReleaseVersionInfo(); releaseVersionInfo = new ReleaseVersionInfo();
releaseVersionInfo.setVersion(resultSet.getString("VERSION")); releaseVersionInfo.setVersion(resultSet.getString("VERSION"));
releaseVersionInfo.setReleaseType(resultSet.getString("RELEASE_TYPE")); releaseVersionInfo.setReleaseType(resultSet.getString("RELEASE_TYPE"));
releaseVersionInfo.setRating(resultSet.getString("RATING")); releaseVersionInfo.setRating(resultSet.getDouble("RATING"));
releaseVersionInfo.setState(resultSet.getString("CURRENT_STATE")); releaseVersionInfo.setState(resultSet.getString("CURRENT_STATE"));
releaseVersionInfo.setUuid(resultSet.getString("UUID")); releaseVersionInfo.setUuid(resultSet.getString("UUID"));
releaseVersionInfos.add(releaseVersionInfo); releaseVersionInfos.add(releaseVersionInfo);

@ -967,25 +967,37 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
@Override @Override
public List<String> getAppSubscribedUsers(int offsetValue, int limitValue, int appReleaseId, public List<String> getAppSubscribedUsers(int offsetValue, int limitValue, int appReleaseId,
int tenantId) int tenantId, Boolean uninstalled, String searchName)
throws ApplicationManagementDAOException { throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to get already subscribed users for " + log.debug("Request received in DAO Layer to get subscribed/unsubscribed users for the given app release ID.");
"given app release id.");
} }
try { try {
Connection conn = this.getDBConnection(); Connection conn = this.getDBConnection();
List<String> subscribedUsers = new ArrayList<>(); List<String> subscribedUsers = new ArrayList<>();
String sql = "SELECT " String sql = "SELECT US.USER_NAME AS USER_NAME " +
+ "US.USER_NAME AS USER_NAME " "FROM AP_USER_SUBSCRIPTION US " +
+ "FROM AP_USER_SUBSCRIPTION US " "WHERE AP_APP_RELEASE_ID = ? " +
+ "WHERE " "AND TENANT_ID = ? ";
+ "AP_APP_RELEASE_ID = ? AND TENANT_ID = ? LIMIT ? OFFSET ?"; if (uninstalled != null) {
sql += "AND UNSUBSCRIBED = ? ";
}
if (searchName != null && !searchName.trim().isEmpty()) {
sql += "AND US.USER_NAME LIKE ? ";
}
sql += "LIMIT ? OFFSET ?";
try (PreparedStatement stmt = conn.prepareStatement(sql)) { try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setInt(1, appReleaseId); int index = 1;
stmt.setInt(2, tenantId); stmt.setInt(index++, appReleaseId);
stmt.setInt(3, limitValue); stmt.setInt(index++, tenantId);
stmt.setInt(4, offsetValue); if (uninstalled != null) {
stmt.setBoolean(index++, uninstalled);
}
if (searchName != null && !searchName.trim().isEmpty()) {
stmt.setString(index++, "%" + searchName + "%");
}
stmt.setInt(index++, limitValue);
stmt.setInt(index, offsetValue);
try (ResultSet rs = stmt.executeQuery()) { try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) { while (rs.next()) {
subscribedUsers.add(rs.getString("USER_NAME")); subscribedUsers.add(rs.getString("USER_NAME"));
@ -994,50 +1006,62 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
return subscribedUsers; return subscribedUsers;
} }
} catch (DBConnectionException e) { } catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to get already " + String msg = "Error occurred while obtaining the DB connection to get subscribed/unsubscribed users for the " +
"subscribed users for given app release id."; "given app release ID.";
log.error(msg, e); log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e); throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) { } catch (SQLException e) {
String msg = "SQL Error occurred while getting subscribed users for given app release id."; String msg = "SQL Error occurred while getting subscribed/unsubscribed users for the given app release ID.";
log.error(msg, e); log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e); throw new ApplicationManagementDAOException(msg, e);
} }
} }
@Override @Override
public int getSubscribedUserCount(int appReleaseId, int tenantId) public int getSubscribedUserCount(int appReleaseId, int tenantId, Boolean uninstalled, String searchName)
throws ApplicationManagementDAOException { throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to get already subscribed users for " + log.debug("Request received in DAO Layer to get already subscribed/unsubscribed users for " +
"given app release id."); "given app release id.");
} }
try { try {
Connection conn = this.getDBConnection(); Connection conn = this.getDBConnection();
String sql = "SELECT " String sql = "SELECT COUNT(US.USER_NAME) AS USER_COUNT " +
+ "COUNT(US.USER_NAME) AS USER_NAME " "FROM AP_USER_SUBSCRIPTION US " +
+ "FROM AP_USER_SUBSCRIPTION US " "WHERE AP_APP_RELEASE_ID = ? " +
+ "WHERE " "AND TENANT_ID = ?";
+ "AP_APP_RELEASE_ID = ? AND TENANT_ID = ?"; if (uninstalled != null) {
sql += " AND UNSUBSCRIBED = ?";
}
if (searchName != null && !searchName.trim().isEmpty()) {
sql += " AND US.USER_NAME LIKE ?";
}
try (PreparedStatement stmt = conn.prepareStatement(sql)) { try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setInt(1, appReleaseId); int index = 1;
stmt.setInt(2, tenantId); stmt.setInt(index++, appReleaseId);
stmt.setInt(index++, tenantId);
if (uninstalled != null) {
stmt.setBoolean(index++, uninstalled);
}
if (searchName != null && !searchName.trim().isEmpty()) {
stmt.setString(index++, "%" + searchName + "%");
}
try (ResultSet rs = stmt.executeQuery()) { try (ResultSet rs = stmt.executeQuery()) {
if (rs.next()) { if (rs.next()) {
return rs.getInt("USER_NAME"); return rs.getInt("USER_COUNT");
} }
} }
return 0; return 0;
} }
} catch (DBConnectionException e) { } catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to get already " + String msg = "Error occurred while obtaining the DB connection to get already " +
"subscribed users count for given app release id."; "subscribed/unsubscribed users count for given app release id.";
log.error(msg, e); log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e); throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) { } catch (SQLException e) {
String msg = "SQL Error occurred while getting subscribed users for given app release id."; String msg = "SQL Error occurred while getting subscribed/unsubscribed users count for given app release id.";
log.error(msg, e); log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e); throw new ApplicationManagementDAOException(msg, e);
} }
@ -1151,25 +1175,40 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
@Override @Override
public List<String> getAppSubscribedRoles(int offsetValue, int limitValue, int appReleaseId, public List<String> getAppSubscribedRoles(int offsetValue, int limitValue, int appReleaseId,
int tenantId) int tenantId, Boolean uninstalled, String searchName)
throws ApplicationManagementDAOException { throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to get already subscribed roles for " + log.debug("Request received in DAO Layer to get already subscribed/unsubscribed roles for " +
"given app release id."); "given app release id.");
} }
try { try {
Connection conn = this.getDBConnection(); Connection conn = this.getDBConnection();
List<String> subscribedRoles = new ArrayList<>(); List<String> subscribedRoles = new ArrayList<>();
String sql = "SELECT " String sql = "SELECT "
+ "RS.ROLE_NAME AS ROLE " + "RS.ROLE_NAME AS ROLE "
+ "FROM AP_ROLE_SUBSCRIPTION RS " + "FROM AP_ROLE_SUBSCRIPTION RS "
+ "WHERE " + "WHERE AP_APP_RELEASE_ID = ? "
+ "AP_APP_RELEASE_ID = ? AND TENANT_ID = ? LIMIT ? OFFSET ?"; + "AND TENANT_ID = ?";
if (uninstalled != null) {
sql += " AND UNSUBSCRIBED = ?";
}
if (searchName != null && !searchName.trim().isEmpty()) {
sql += " AND RS.ROLE_NAME LIKE ?";
}
sql += " LIMIT ? OFFSET ?";
try (PreparedStatement ps = conn.prepareStatement(sql)) { try (PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setInt(1, appReleaseId); int paramIndex = 1;
ps.setInt(2, tenantId); ps.setInt(paramIndex++, appReleaseId);
ps.setInt(3, limitValue); ps.setInt(paramIndex++, tenantId);
ps.setInt(4, offsetValue);
if (uninstalled != null) {
ps.setBoolean(paramIndex++, uninstalled);
}
if (searchName != null && !searchName.trim().isEmpty()) {
ps.setString(paramIndex++, "%" + searchName + "%");
}
ps.setInt(paramIndex++, limitValue);
ps.setInt(paramIndex, offsetValue);
try (ResultSet rs = ps.executeQuery()) { try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) { while (rs.next()) {
subscribedRoles.add(rs.getString("ROLE")); subscribedRoles.add(rs.getString("ROLE"));
@ -1179,49 +1218,61 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
} }
} catch (DBConnectionException e) { } catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to get already " + String msg = "Error occurred while obtaining the DB connection to get already " +
"subscribed roles for given app release id."; "subscribed/unsubscribed roles for given app release id.";
log.error(msg, e); log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e); throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) { } catch (SQLException e) {
String msg = "SQL Error occurred while getting subscribed roles for given app release id."; String msg = "SQL Error occurred while getting subscribed/unsubscribed roles for given app release id.";
log.error(msg, e); log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e); throw new ApplicationManagementDAOException(msg, e);
} }
} }
@Override @Override
public int getSubscribedRoleCount(int appReleaseId, int tenantId) public int getSubscribedRoleCount(int appReleaseId, int tenantId, Boolean uninstalled, String searchName)
throws ApplicationManagementDAOException { throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to get already subscribed roles for " + log.debug("Request received in DAO Layer to get already subscribed/unsubscribed roles for " +
"given app release id."); "given app release id.");
} }
try { try {
Connection conn = this.getDBConnection(); Connection conn = this.getDBConnection();
String sql = "SELECT " String sql = "SELECT "
+ "COUNT(RS.ROLE_NAME) AS ROLE_NAME " + "COUNT(RS.ROLE_NAME) AS ROLE_COUNT "
+ "FROM AP_ROLE_SUBSCRIPTION RS " + "FROM AP_ROLE_SUBSCRIPTION RS "
+ "WHERE " + "WHERE AP_APP_RELEASE_ID = ? "
+ "AP_APP_RELEASE_ID = ? AND TENANT_ID = ?"; + "AND TENANT_ID = ?";
if (uninstalled != null) {
sql += " AND UNSUBSCRIBED = ?";
}
if (searchName != null && !searchName.trim().isEmpty()) {
sql += " AND RS.ROLE_NAME LIKE ?";
}
try (PreparedStatement stmt = conn.prepareStatement(sql)) { try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setInt(1, appReleaseId); int paramIndex = 1;
stmt.setInt(2, tenantId); stmt.setInt(paramIndex++, appReleaseId);
stmt.setInt(paramIndex++, tenantId);
if (uninstalled != null) {
stmt.setBoolean(paramIndex++, uninstalled);
}
if (searchName != null && !searchName.trim().isEmpty()) {
stmt.setString(paramIndex++, "%" + searchName + "%");
}
try (ResultSet rs = stmt.executeQuery()) { try (ResultSet rs = stmt.executeQuery()) {
if (rs.next()) { if (rs.next()) {
return rs.getInt("ROLE_NAME"); return rs.getInt("ROLE_COUNT");
} }
return 0;
} }
return 0;
} }
} catch (DBConnectionException e) { } catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to get already " + String msg = "Error occurred while obtaining the DB connection to get already " +
"subscribed roles count for given app release id."; "subscribed/unsubscribed roles count for given app release id.";
log.error(msg, e); log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e); throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) { } catch (SQLException e) {
String msg = "SQL Error occurred while getting subscribed roles for given app release id."; String msg = "SQL Error occurred while getting subscribed/unsubscribed roles count for given app release id.";
log.error(msg, e); log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e); throw new ApplicationManagementDAOException(msg, e);
} }
@ -1269,25 +1320,37 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
@Override @Override
public List<String> getAppSubscribedGroups(int offsetValue, int limitValue, int appReleaseId, public List<String> getAppSubscribedGroups(int offsetValue, int limitValue, int appReleaseId,
int tenantId) int tenantId, Boolean uninstalled, String searchName)
throws ApplicationManagementDAOException { throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to get already subscribed groups for " + log.debug("Request received in DAO Layer to get already subscribed/unsubscribed groups for " +
"given app release id."); "given app release id.");
} }
try { try {
Connection conn = this.getDBConnection(); Connection conn = this.getDBConnection();
List<String> subscribedGroups = new ArrayList<>(); List<String> subscribedGroups = new ArrayList<>();
String sql = "SELECT " String sql = "SELECT GS.GROUP_NAME AS APP_GROUPS " +
+ "GS.GROUP_NAME AS APP_GROUPS " "FROM AP_GROUP_SUBSCRIPTION GS " +
+ "FROM AP_GROUP_SUBSCRIPTION GS " "WHERE AP_APP_RELEASE_ID = ? AND TENANT_ID = ?";
+ "WHERE " if (uninstalled != null) {
+ "AP_APP_RELEASE_ID = ? AND TENANT_ID = ? LIMIT ? OFFSET ?"; sql += " AND UNSUBSCRIBED = ?";
}
if (searchName != null && !searchName.trim().isEmpty()) {
sql += " AND GS.GROUP_NAME LIKE ?";
}
sql += " LIMIT ? OFFSET ?";
try (PreparedStatement ps = conn.prepareStatement(sql)) { try (PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setInt(1, appReleaseId); int paramIndex = 1;
ps.setInt(2, tenantId); ps.setInt(paramIndex++, appReleaseId);
ps.setInt(3, limitValue); ps.setInt(paramIndex++, tenantId);
ps.setInt(4, offsetValue); if (uninstalled != null) {
ps.setBoolean(paramIndex++, uninstalled);
}
if (searchName != null && !searchName.trim().isEmpty()) {
ps.setString(paramIndex++, "%" + searchName + "%");
}
ps.setInt(paramIndex++, limitValue);
ps.setInt(paramIndex, offsetValue);
try (ResultSet rs = ps.executeQuery()) { try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) { while (rs.next()) {
subscribedGroups.add(rs.getString("APP_GROUPS")); subscribedGroups.add(rs.getString("APP_GROUPS"));
@ -1297,11 +1360,11 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
} }
} catch (DBConnectionException e) { } catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to get already " + String msg = "Error occurred while obtaining the DB connection to get already " +
"subscribed groups for given app release id."; "subscribed/unsubscribed groups for given app release id.";
log.error(msg, e); log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e); throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) { } catch (SQLException e) {
String msg = "SQL Error occurred while getting subscribed groups for given " + String msg = "SQL Error occurred while getting subscribed/unsubscribed groups for given " +
"app release id."; "app release id.";
log.error(msg, e); log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e); throw new ApplicationManagementDAOException(msg, e);
@ -1309,24 +1372,34 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
} }
@Override @Override
public int getSubscribedGroupCount(int appReleaseId, int tenantId) public int getSubscribedGroupCount(int appReleaseId, int tenantId, Boolean uninstalled, String searchName)
throws ApplicationManagementDAOException { throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to get already subscribed groups for " + log.debug("Request received in DAO Layer to get the count of subscribed/unsubscribed groups for " +
"given app release id."); "given app release id.");
} }
try { try {
Connection conn = this.getDBConnection(); Connection conn = this.getDBConnection();
String sql = "SELECT " String sql = "SELECT COUNT(GS.GROUP_NAME) AS APP_GROUPS_COUNT " +
+ "COUNT(GS.GROUP_NAME) AS APP_GROUPS_COUNT " "FROM AP_GROUP_SUBSCRIPTION GS " +
+ "FROM AP_GROUP_SUBSCRIPTION GS " "WHERE AP_APP_RELEASE_ID = ? AND TENANT_ID = ?";
+ "WHERE " if (uninstalled != null) {
+ "AP_APP_RELEASE_ID = ? AND TENANT_ID = ?"; sql += " AND UNSUBSCRIBED = ?";
}
if (searchName != null && !searchName.trim().isEmpty()) {
sql += " AND GS.GROUP_NAME LIKE ?";
}
try (PreparedStatement stmt = conn.prepareStatement(sql)) { try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setInt(1, appReleaseId); int paramIndex = 1;
stmt.setInt(2, tenantId); stmt.setInt(paramIndex++, appReleaseId);
stmt.setInt(paramIndex++, tenantId);
if (uninstalled != null) {
stmt.setBoolean(paramIndex++, uninstalled);
}
if (searchName != null && !searchName.trim().isEmpty()) {
stmt.setString(paramIndex++, "%" + searchName + "%");
}
try (ResultSet rs = stmt.executeQuery()) { try (ResultSet rs = stmt.executeQuery()) {
if (rs.next()) { if (rs.next()) {
return rs.getInt("APP_GROUPS_COUNT"); return rs.getInt("APP_GROUPS_COUNT");
@ -1335,12 +1408,13 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
return 0; return 0;
} }
} catch (DBConnectionException e) { } catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to get already " + String msg = "Error occurred while obtaining the DB connection to get the count of " +
"subscribed groups count for given app release id."; "subscribed/unsubscribed groups for given app release id.";
log.error(msg, e); log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e); throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) { } catch (SQLException e) {
String msg = "SQL Error occurred while getting subscribed groups for given app release id."; String msg = "SQL Error occurred while getting the count of subscribed/unsubscribed groups for given " +
"app release id.";
log.error(msg, e); log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e); throw new ApplicationManagementDAOException(msg, e);
} }

@ -43,10 +43,10 @@ public class OracleSubscriptionDAOImpl extends GenericSubscriptionDAOImpl {
@Override @Override
public List<String> getAppSubscribedUsers(int offsetValue, int limitValue, int appReleaseId, public List<String> getAppSubscribedUsers(int offsetValue, int limitValue, int appReleaseId,
int tenantId) int tenantId, Boolean uninstalled, String searchName)
throws ApplicationManagementDAOException { throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to get already subscribed users for " + log.debug("Request received in DAO Layer to get already subscribed/unsubscribed users for " +
"given app release id."); "given app release id.");
} }
try { try {
@ -55,13 +55,28 @@ public class OracleSubscriptionDAOImpl extends GenericSubscriptionDAOImpl {
String sql = "SELECT " String sql = "SELECT "
+ "US.USER_NAME AS USER " + "US.USER_NAME AS USER "
+ "FROM AP_USER_SUBSCRIPTION US " + "FROM AP_USER_SUBSCRIPTION US "
+ "WHERE " + "WHERE AP_APP_RELEASE_ID = ? "
+ "AP_APP_RELEASE_ID = ? AND TENANT_ID = ? ORDER BY US.ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; + "AND TENANT_ID = ? ";
if (uninstalled != null) {
sql += "AND UNSUBSCRIBED = ? ";
}
if (searchName != null && !searchName.trim().isEmpty()) {
sql += "AND US.USER_NAME LIKE ? ";
}
sql += "ORDER BY US.ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
try (PreparedStatement stmt = conn.prepareStatement(sql)) { try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setInt(1, appReleaseId); int index = 1;
stmt.setInt(2, tenantId); stmt.setInt(index++, appReleaseId);
stmt.setInt(3, offsetValue); stmt.setInt(index++, tenantId);
stmt.setInt(4, limitValue); if (uninstalled != null) {
stmt.setBoolean(index++, uninstalled);
}
if (searchName != null && !searchName.trim().isEmpty()) {
stmt.setString(index++, "%" + searchName + "%");
}
stmt.setInt(index++, offsetValue);
stmt.setInt(index, limitValue);
try (ResultSet rs = stmt.executeQuery()) { try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) { while (rs.next()) {
subscribedUsers.add(rs.getString("USER")); subscribedUsers.add(rs.getString("USER"));
@ -71,11 +86,11 @@ public class OracleSubscriptionDAOImpl extends GenericSubscriptionDAOImpl {
} }
} catch (DBConnectionException e) { } catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to get already " + String msg = "Error occurred while obtaining the DB connection to get already " +
"subscribed users for given app release id."; "subscribed/unsubscribed users for given app release id.";
log.error(msg, e); log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e); throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) { } catch (SQLException e) {
String msg = "SQL Error occurred while getting subscribed users for given app release id."; String msg = "SQL Error occurred while getting subscribed/unsubscribed users for given app release id.";
log.error(msg, e); log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e); throw new ApplicationManagementDAOException(msg, e);
} }
@ -83,10 +98,10 @@ public class OracleSubscriptionDAOImpl extends GenericSubscriptionDAOImpl {
@Override @Override
public List<String> getAppSubscribedRoles(int offsetValue, int limitValue, int appReleaseId, public List<String> getAppSubscribedRoles(int offsetValue, int limitValue, int appReleaseId,
int tenantId) int tenantId, Boolean uninstalled, String searchName)
throws ApplicationManagementDAOException { throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to get already subscribed roles for " + log.debug("Request received in DAO Layer to get already subscribed/unsubscribed roles for " +
"given app release id."); "given app release id.");
} }
try { try {
@ -95,13 +110,27 @@ public class OracleSubscriptionDAOImpl extends GenericSubscriptionDAOImpl {
String sql = "SELECT " String sql = "SELECT "
+ "RS.ROLE_NAME AS ROLE " + "RS.ROLE_NAME AS ROLE "
+ "FROM AP_ROLE_SUBSCRIPTION RS " + "FROM AP_ROLE_SUBSCRIPTION RS "
+ "WHERE " + "WHERE AP_APP_RELEASE_ID = ? "
+ "AP_APP_RELEASE_ID = ? AND TENANT_ID = ? ORDER BY RS.ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; + "AND TENANT_ID = ? ";
if (uninstalled != null) {
sql += "AND UNSUBSCRIBED = ? ";
}
if (searchName != null && !searchName.trim().isEmpty()) {
sql += "AND RS.ROLE_NAME LIKE ? ";
}
sql += "ORDER BY RS.ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
try (PreparedStatement ps = conn.prepareStatement(sql)) { try (PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setInt(1, appReleaseId); int paramIndex = 1;
ps.setInt(2, tenantId); ps.setInt(paramIndex++, appReleaseId);
ps.setInt(3, offsetValue); ps.setInt(paramIndex++, tenantId);
ps.setInt(4, limitValue); if (uninstalled != null) {
ps.setBoolean(paramIndex++, uninstalled);
}
if (searchName != null && !searchName.trim().isEmpty()) {
ps.setString(paramIndex++, "%" + searchName + "%");
}
ps.setInt(paramIndex++, offsetValue);
ps.setInt(paramIndex, limitValue);
try (ResultSet rs = ps.executeQuery()) { try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) { while (rs.next()) {
subscribedRoles.add(rs.getString("ROLE")); subscribedRoles.add(rs.getString("ROLE"));
@ -111,11 +140,11 @@ public class OracleSubscriptionDAOImpl extends GenericSubscriptionDAOImpl {
} }
} catch (DBConnectionException e) { } catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to get already " + String msg = "Error occurred while obtaining the DB connection to get already " +
"subscribed roles for given app release id."; "subscribed/unsubscribed roles for given app release id.";
log.error(msg, e); log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e); throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) { } catch (SQLException e) {
String msg = "SQL Error occurred while getting subscribed roles for given app release id."; String msg = "SQL Error occurred while getting subscribed/unsubscribed roles for given app release id.";
log.error(msg, e); log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e); throw new ApplicationManagementDAOException(msg, e);
} }
@ -123,11 +152,10 @@ public class OracleSubscriptionDAOImpl extends GenericSubscriptionDAOImpl {
@Override @Override
public List<String> getAppSubscribedGroups(int offsetValue, int limitValue, int appReleaseId, public List<String> getAppSubscribedGroups(int offsetValue, int limitValue, int appReleaseId,
int tenantId) int tenantId, Boolean uninstalled, String searchName)
throws ApplicationManagementDAOException { throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to get already subscribed groups for " + log.debug("Request received in DAO Layer to get subscribed/unsubscribed groups for the given app release ID.");
"given app release id.");
} }
try { try {
Connection conn = this.getDBConnection(); Connection conn = this.getDBConnection();
@ -135,13 +163,26 @@ public class OracleSubscriptionDAOImpl extends GenericSubscriptionDAOImpl {
String sql = "SELECT " String sql = "SELECT "
+ "GS.GROUP_NAME AS GROUPS " + "GS.GROUP_NAME AS GROUPS "
+ "FROM AP_GROUP_SUBSCRIPTION GS " + "FROM AP_GROUP_SUBSCRIPTION GS "
+ "WHERE " + "WHERE AP_APP_RELEASE_ID = ? AND TENANT_ID = ?";
+ "AP_APP_RELEASE_ID = ? AND TENANT_ID = ? ORDER BY GS.ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; if (uninstalled != null) {
sql += " AND UNSUBSCRIBED = ?";
}
if (searchName != null && !searchName.trim().isEmpty()) {
sql += " AND GS.GROUP_NAME LIKE ?";
}
sql += " ORDER BY GS.ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
try (PreparedStatement ps = conn.prepareStatement(sql)) { try (PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setInt(1, appReleaseId); int paramIndex = 1;
ps.setInt(2, tenantId); ps.setInt(paramIndex++, appReleaseId);
ps.setInt(3, offsetValue); ps.setInt(paramIndex++, tenantId);
ps.setInt(4, limitValue); if (uninstalled != null) {
ps.setBoolean(paramIndex++, uninstalled);
}
if (searchName != null && !searchName.trim().isEmpty()) {
ps.setString(paramIndex++, "%" + searchName + "%");
}
ps.setInt(paramIndex++, offsetValue);
ps.setInt(paramIndex, limitValue);
try (ResultSet rs = ps.executeQuery()) { try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) { while (rs.next()) {
subscribedGroups.add(rs.getString("GROUPS")); subscribedGroups.add(rs.getString("GROUPS"));
@ -150,13 +191,12 @@ public class OracleSubscriptionDAOImpl extends GenericSubscriptionDAOImpl {
return subscribedGroups; return subscribedGroups;
} }
} catch (DBConnectionException e) { } catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to get already " + String msg = "Error occurred while obtaining the DB connection to get subscribed/unsubscribed groups" +
"subscribed groups for given app release id."; " for the given app release ID.";
log.error(msg, e); log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e); throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) { } catch (SQLException e) {
String msg = "SQL Error occurred while getting subscribed groups for given " + String msg = "SQL Error occurred while getting subscribed/unsubscribed groups for the given app release ID.";
"app release id.";
log.error(msg, e); log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e); throw new ApplicationManagementDAOException(msg, e);
} }

@ -39,10 +39,10 @@ public class SQLServerSubscriptionDAOImpl extends GenericSubscriptionDAOImpl {
@Override @Override
public List<String> getAppSubscribedUsers(int offsetValue, int limitValue, int appReleaseId, public List<String> getAppSubscribedUsers(int offsetValue, int limitValue, int appReleaseId,
int tenantId) int tenantId, Boolean uninstalled, String searchName)
throws ApplicationManagementDAOException { throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to get already subscribed users for " + log.debug("Request received in DAO Layer to get already subscribed/unsubscribed users for " +
"given app release id."); "given app release id.");
} }
try { try {
@ -51,13 +51,28 @@ public class SQLServerSubscriptionDAOImpl extends GenericSubscriptionDAOImpl {
String sql = "SELECT " String sql = "SELECT "
+ "US.USER_NAME AS USER_NAME " + "US.USER_NAME AS USER_NAME "
+ "FROM AP_USER_SUBSCRIPTION US " + "FROM AP_USER_SUBSCRIPTION US "
+ "WHERE " + "WHERE AP_APP_RELEASE_ID = ? "
+ "AP_APP_RELEASE_ID = ? AND TENANT_ID = ? ORDER BY US.ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; + "AND TENANT_ID = ? ";
if (uninstalled != null) {
sql += "AND UNSUBSCRIBED = ? ";
}
if (searchName != null && !searchName.trim().isEmpty()) {
sql += "AND US.USER_NAME LIKE ? ";
}
sql += "ORDER BY US.ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
try (PreparedStatement stmt = conn.prepareStatement(sql)) { try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setInt(1, appReleaseId); int index = 1;
stmt.setInt(2, tenantId); stmt.setInt(index++, appReleaseId);
stmt.setInt(3, offsetValue); stmt.setInt(index++, tenantId);
stmt.setInt(4, limitValue); if (uninstalled != null) {
stmt.setBoolean(index++, uninstalled);
}
if (searchName != null && !searchName.trim().isEmpty()) {
stmt.setString(index++, "%" + searchName + "%");
}
stmt.setInt(index++, offsetValue);
stmt.setInt(index, limitValue);
try (ResultSet rs = stmt.executeQuery()) { try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) { while (rs.next()) {
subscribedUsers.add(rs.getString("USER_NAME")); subscribedUsers.add(rs.getString("USER_NAME"));
@ -67,11 +82,11 @@ public class SQLServerSubscriptionDAOImpl extends GenericSubscriptionDAOImpl {
} }
} catch (DBConnectionException e) { } catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to get already " + String msg = "Error occurred while obtaining the DB connection to get already " +
"subscribed users for given app release id."; "subscribed/unsubscribed users for given app release id.";
log.error(msg, e); log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e); throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) { } catch (SQLException e) {
String msg = "SQL Error occurred while getting subscribed users for given app release id."; String msg = "SQL Error occurred while getting subscribed/unsubscribed users for given app release id.";
log.error(msg, e); log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e); throw new ApplicationManagementDAOException(msg, e);
} }
@ -79,10 +94,10 @@ public class SQLServerSubscriptionDAOImpl extends GenericSubscriptionDAOImpl {
@Override @Override
public List<String> getAppSubscribedRoles(int offsetValue, int limitValue, int appReleaseId, public List<String> getAppSubscribedRoles(int offsetValue, int limitValue, int appReleaseId,
int tenantId) int tenantId, Boolean uninstalled, String searchName)
throws ApplicationManagementDAOException { throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to get already subscribed roles for " + log.debug("Request received in DAO Layer to get already subscribed/unsubscribed roles for " +
"given app release id."); "given app release id.");
} }
try { try {
@ -91,13 +106,29 @@ public class SQLServerSubscriptionDAOImpl extends GenericSubscriptionDAOImpl {
String sql = "SELECT " String sql = "SELECT "
+ "RS.ROLE_NAME AS ROLE " + "RS.ROLE_NAME AS ROLE "
+ "FROM AP_ROLE_SUBSCRIPTION RS " + "FROM AP_ROLE_SUBSCRIPTION RS "
+ "WHERE " + "WHERE AP_APP_RELEASE_ID = ? "
+ "AP_APP_RELEASE_ID = ? AND TENANT_ID = ? ORDER BY RS.ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; + "AND TENANT_ID = ? ";
if (uninstalled != null) {
sql += "AND UNSUBSCRIBED = ? ";
}
if (searchName != null && !searchName.trim().isEmpty()) {
sql += "AND RS.ROLE_NAME LIKE ? ";
}
sql += "ORDER BY RS.ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
try (PreparedStatement ps = conn.prepareStatement(sql)) { try (PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setInt(1, appReleaseId); int paramIndex = 1;
ps.setInt(2, tenantId); ps.setInt(paramIndex++, appReleaseId);
ps.setInt(3, offsetValue); ps.setInt(paramIndex++, tenantId);
ps.setInt(4, limitValue); if (uninstalled != null) {
ps.setBoolean(paramIndex++, uninstalled);
}
if (searchName != null && !searchName.trim().isEmpty()) {
ps.setString(paramIndex++, "%" + searchName + "%");
}
ps.setInt(paramIndex++, offsetValue);
ps.setInt(paramIndex, limitValue);
try (ResultSet rs = ps.executeQuery()) { try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) { while (rs.next()) {
subscribedRoles.add(rs.getString("ROLE")); subscribedRoles.add(rs.getString("ROLE"));
@ -107,11 +138,11 @@ public class SQLServerSubscriptionDAOImpl extends GenericSubscriptionDAOImpl {
} }
} catch (DBConnectionException e) { } catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to get already " + String msg = "Error occurred while obtaining the DB connection to get already " +
"subscribed roles for given app release id."; "subscribed/unsubscribed roles for given app release id.";
log.error(msg, e); log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e); throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) { } catch (SQLException e) {
String msg = "SQL Error occurred while getting subscribed roles for given app release id."; String msg = "SQL Error occurred while getting subscribed/unsubscribed roles for given app release id.";
log.error(msg, e); log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e); throw new ApplicationManagementDAOException(msg, e);
} }
@ -119,11 +150,10 @@ public class SQLServerSubscriptionDAOImpl extends GenericSubscriptionDAOImpl {
@Override @Override
public List<String> getAppSubscribedGroups(int offsetValue, int limitValue, int appReleaseId, public List<String> getAppSubscribedGroups(int offsetValue, int limitValue, int appReleaseId,
int tenantId) int tenantId, Boolean uninstalled, String searchName)
throws ApplicationManagementDAOException { throws ApplicationManagementDAOException {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Request received in DAO Layer to get already subscribed groups for " + log.debug("Request received in DAO Layer to get subscribed/unsubscribed groups for the given app release ID.");
"given app release id.");
} }
try { try {
Connection conn = this.getDBConnection(); Connection conn = this.getDBConnection();
@ -131,13 +161,26 @@ public class SQLServerSubscriptionDAOImpl extends GenericSubscriptionDAOImpl {
String sql = "SELECT " String sql = "SELECT "
+ "GS.GROUP_NAME AS GROUPS " + "GS.GROUP_NAME AS GROUPS "
+ "FROM AP_GROUP_SUBSCRIPTION GS " + "FROM AP_GROUP_SUBSCRIPTION GS "
+ "WHERE " + "WHERE AP_APP_RELEASE_ID = ? AND TENANT_ID = ?";
+ "AP_APP_RELEASE_ID = ? AND TENANT_ID = ? ORDER BY GS.ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; if (uninstalled != null) {
sql += " AND UNSUBSCRIBED = ?";
}
if (searchName != null && !searchName.trim().isEmpty()) {
sql += " AND GS.GROUP_NAME LIKE ?";
}
sql += " ORDER BY GS.ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
try (PreparedStatement ps = conn.prepareStatement(sql)) { try (PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setInt(1, appReleaseId); int paramIndex = 1;
ps.setInt(2, tenantId); ps.setInt(paramIndex++, appReleaseId);
ps.setInt(3, offsetValue); ps.setInt(paramIndex++, tenantId);
ps.setInt(4, limitValue); if (uninstalled != null) {
ps.setBoolean(paramIndex++, uninstalled);
}
if (searchName != null && !searchName.trim().isEmpty()) {
ps.setString(paramIndex++, "%" + searchName + "%");
}
ps.setInt(paramIndex++, offsetValue);
ps.setInt(paramIndex, limitValue);
try (ResultSet rs = ps.executeQuery()) { try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) { while (rs.next()) {
subscribedGroups.add(rs.getString("GROUPS")); subscribedGroups.add(rs.getString("GROUPS"));
@ -146,13 +189,11 @@ public class SQLServerSubscriptionDAOImpl extends GenericSubscriptionDAOImpl {
return subscribedGroups; return subscribedGroups;
} }
} catch (DBConnectionException e) { } catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the DB connection to get already " + String msg = "Error occurred while obtaining the DB connection to get subscribed/unsubscribed groups for the given app release ID.";
"subscribed groups for given app release id.";
log.error(msg, e); log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e); throw new ApplicationManagementDAOException(msg, e);
} catch (SQLException e) { } catch (SQLException e) {
String msg = "SQL Error occurred while getting subscribed groups for given " + String msg = "SQL Error occurred while getting subscribed/unsubscribed groups for the given app release ID.";
"app release id.";
log.error(msg, e); log.error(msg, e);
throw new ApplicationManagementDAOException(msg, e); throw new ApplicationManagementDAOException(msg, e);
} }

@ -1498,7 +1498,8 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
} }
@Override @Override
public PaginationResult getAppInstalledSubscribers(int offsetValue, int limitValue, String appUUID, String subType) public PaginationResult getAppInstalledSubscribers(int offsetValue, int limitValue, String appUUID, String subType,
Boolean uninstalled, String searchName)
throws ApplicationManagementException { throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
@ -1513,20 +1514,16 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
if (SubscriptionType.USER.toString().equalsIgnoreCase(subType)) { if (SubscriptionType.USER.toString().equalsIgnoreCase(subType)) {
subscriptionList = subscriptionDAO subscriptionList = subscriptionDAO
.getAppSubscribedUsers(offsetValue, limitValue, applicationReleaseId, tenantId); .getAppSubscribedUsers(offsetValue, limitValue, applicationReleaseId, tenantId, uninstalled, searchName);
count = subscriptionDAO.getSubscribedUserCount(applicationReleaseId, tenantId); count = subscriptionDAO.getSubscribedUserCount(applicationReleaseId, tenantId, uninstalled, searchName);
} else { } else if (SubscriptionType.ROLE.toString().equalsIgnoreCase(subType)) {
if (SubscriptionType.ROLE.toString().equalsIgnoreCase(subType)) { subscriptionList = subscriptionDAO
subscriptionList = subscriptionDAO .getAppSubscribedRoles(offsetValue, limitValue, applicationReleaseId, tenantId, uninstalled, searchName);
.getAppSubscribedRoles(offsetValue, limitValue, applicationReleaseId, tenantId); count = subscriptionDAO.getSubscribedRoleCount(applicationReleaseId, tenantId, uninstalled, searchName);
count = subscriptionDAO.getSubscribedRoleCount(applicationReleaseId, tenantId); } else if (SubscriptionType.GROUP.toString().equalsIgnoreCase(subType)) {
} else { subscriptionList = subscriptionDAO
if (SubscriptionType.GROUP.toString().equalsIgnoreCase(subType)) { .getAppSubscribedGroups(offsetValue, limitValue, applicationReleaseId, tenantId, uninstalled, searchName);
subscriptionList = subscriptionDAO count = subscriptionDAO.getSubscribedGroupCount(applicationReleaseId, tenantId, uninstalled, searchName);
.getAppSubscribedGroups(offsetValue, limitValue, applicationReleaseId, tenantId);
count = subscriptionDAO.getSubscribedGroupCount(applicationReleaseId, tenantId);
}
}
} }
paginationResult.setData(subscriptionList); paginationResult.setData(subscriptionList);

@ -93,6 +93,20 @@ public class Feature implements Serializable {
) )
private List<MetadataEntry> metadataEntries; private List<MetadataEntry> metadataEntries;
@ApiModelProperty(
name = "confirmationTexts",
value = "Disenroll delete confirmation modal texts.",
required = false
)
private ConfirmationTexts confirmationTexts;
@ApiModelProperty(
name = "dangerZoneTooltipTexts",
value = "Danger zone tooltip texts.",
required = false
)
private DangerZoneTooltipTexts dangerZoneTooltipTexts;
@XmlElement @XmlElement
public int getId() { public int getId() {
return id; return id;
@ -173,6 +187,24 @@ public class Feature implements Serializable {
this.hidden = hidden; this.hidden = hidden;
} }
@XmlElement
public ConfirmationTexts getConfirmationTexts() {
return confirmationTexts;
}
public void setConfirmationTexts(ConfirmationTexts confirmationTexts) {
this.confirmationTexts = confirmationTexts;
}
@XmlElement
public DangerZoneTooltipTexts getDangerZoneTooltipTexts() {
return dangerZoneTooltipTexts;
}
public void setDangerZoneTooltipTexts(DangerZoneTooltipTexts dangerZoneTooltipTexts) {
this.dangerZoneTooltipTexts = dangerZoneTooltipTexts;
}
public static class MetadataEntry implements Serializable { public static class MetadataEntry implements Serializable {
private int id; private int id;
@ -203,4 +235,136 @@ public class Feature implements Serializable {
this.value = value; this.value = value;
} }
} }
public static class ConfirmationTexts implements Serializable {
private int id;
private String deleteConfirmModalTitle;
private String deleteConfirmModalText;
private String deleteConfirmationTextDescribe;
private String deleteConfirmationText;
private String cancelText;
private String confirmText;
private String inputLabel;
private String inputRequireMessage;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCancelText() {
return cancelText;
}
public void setCancelText(String cancelText) {
this.cancelText = cancelText;
}
public String getConfirmText() {
return confirmText;
}
public void setConfirmText(String confirmText) {
this.confirmText = confirmText;
}
public String getInputLabel() {
return inputLabel;
}
public void setInputLabel(String inputLabel) {
this.inputLabel = inputLabel;
}
public String getInputRequireMessage() {
return inputRequireMessage;
}
public void setInputRequireMessage(String inputRequireMessage) {
this.inputRequireMessage = inputRequireMessage;
}
public String getDeleteConfirmModalTitle() {
return deleteConfirmModalTitle;
}
public void setDeleteConfirmModalTitle(String deleteConfirmModalTitle) {
this.deleteConfirmModalTitle = deleteConfirmModalTitle;
}
public String getDeleteConfirmModalText() {
return deleteConfirmModalText;
}
public void setDeleteConfirmModalText(String deleteConfirmModalText) {
this.deleteConfirmModalText = deleteConfirmModalText;
}
public String getDeleteConfirmationTextDescribe() {
return deleteConfirmationTextDescribe;
}
public void setDeleteConfirmationTextDescribe(String deleteConfirmationTextDescribe) {
this.deleteConfirmationTextDescribe = deleteConfirmationTextDescribe;
}
public String getDeleteConfirmationText() {
return deleteConfirmationText;
}
public void setDeleteConfirmationText(String deleteConfirmationText) {
this.deleteConfirmationText = deleteConfirmationText;
}
}
public static class DangerZoneTooltipTexts implements Serializable {
private String toolTipTitle;
private String toolTipPopConfirmText;
private String confirmText;
private String cancelText;
private String toolTipAvailable;
public String getToolTipAvailable() {
return toolTipAvailable;
}
public void setToolTipAvailable(String toolTipAvailable) {
this.toolTipAvailable = toolTipAvailable;
}
public String getToolTipTitle() {
return toolTipTitle;
}
public void setToolTipTitle(String toolTipTitle) {
this.toolTipTitle = toolTipTitle;
}
public String getToolTipPopConfirmText() {
return toolTipPopConfirmText;
}
public void setToolTipPopConfirmText(String toolTipPopConfirmText) {
this.toolTipPopConfirmText = toolTipPopConfirmText;
}
public String getConfirmText() {
return confirmText;
}
public void setConfirmText(String confirmText) {
this.confirmText = confirmText;
}
public String getCancelText() {
return cancelText;
}
public void setCancelText(String cancelText) {
this.cancelText = cancelText;
}
}
} }

@ -25,6 +25,7 @@ import io.entgra.device.mgt.core.device.mgt.common.configuration.mgt.DeviceConfi
import io.entgra.device.mgt.core.device.mgt.common.general.TenantDetail; import io.entgra.device.mgt.core.device.mgt.common.general.TenantDetail;
import io.entgra.device.mgt.core.device.mgt.config.api.beans.ErrorResponse; import io.entgra.device.mgt.core.device.mgt.config.api.beans.ErrorResponse;
import io.swagger.annotations.*; import io.swagger.annotations.*;
import io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.dto.OperationConfig;
import javax.ws.rs.*; import javax.ws.rs.*;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
@ -77,6 +78,13 @@ import java.util.List;
key = "admin:permissions:add", key = "admin:permissions:add",
roles = {"Internal/devicemgt-user"}, roles = {"Internal/devicemgt-user"},
permissions = {"/permissions/add"} permissions = {"/permissions/add"}
),
@Scope(
name = "Manage operation configuration",
description = "Add or update operation configuration",
key = "admin:operation_config:manage",
roles = {"Internal/devicemgt-user"},
permissions = {"/operation-configuration/manage"}
) )
} }
) )
@ -319,4 +327,173 @@ public interface DeviceManagementConfigService {
}) })
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
Response addPermission(List<String> permissions); Response addPermission(List<String> permissions);
@GET
@Path("/operation-configuration")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = HttpMethod.GET,
value = "Getting operation configuration",
notes = "Retrieve the operation configuration",
tags = "Device Management Configuration",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = "scope", value = "admin:operation_config:manage")
})
}
)
@ApiResponses(value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully fetched the operation configuration.",
response = OperationConfig.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests."),
}),
@ApiResponse(
code = 400,
message = "Bad Request.",
response = ErrorResponse.class),
@ApiResponse(
code = 401,
message = "Unauthorized. \n Unauthorized operation! Only admin role can perform this operation."),
@ApiResponse(
code = 404,
message = "Not Found. \n No operation found",
response = ErrorResponse.class),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Server error occurred while adding operation configuration.",
response = ErrorResponse.class)
})
Response getOperationConfiguration();
@POST
@Path("/operation-configuration")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = HttpMethod.POST,
value = "Add operation configuration",
notes = "Add operation configuration.",
tags = "Device Management Configuration",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = "scope", value =
"admin:operation_config:manage")
})
}
)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK. \n Successfully added the operation configuration.",
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests."),
}),
@ApiResponse(
code = 400,
message = "The incoming request has wrong operation configuration.",
response = ErrorResponse.class),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Server error occurred while adding operation configuration",
response = ErrorResponse.class)
})
@Produces(MediaType.APPLICATION_JSON)
Response addOperationConfiguration(OperationConfig config);
@PUT
@Path("/operation-configuration")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = HttpMethod.PUT,
value = "Update operation configuration",
notes = "Update operation configuration.",
tags = "Device Management Configuration",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = "scope", value = "admin:operation_config:manage")
})
}
)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK. \n Successfully Update the operation configuration.",
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests."),
}),
@ApiResponse(
code = 400,
message = "The incoming request has wrong operation configuration.",
response = ErrorResponse.class),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Server error occurred while adding operation configuration.",
response = ErrorResponse.class)
})
@Produces(MediaType.APPLICATION_JSON)
Response updateOperationConfiguration(OperationConfig config);
@DELETE
@Path("/operation-configuration")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = HttpMethod.DELETE,
value = "Delete operation configuration",
notes = "Delete operation configuration",
tags = {"Device Management Configuration"},
extensions = {
@Extension(properties = {
@ExtensionProperty(name = "scope", value = "admin:operation_config:manage")
})
}
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully deleted the operation configuration",
response = Response.class),
@ApiResponse(
code = 400,
message = "Bad Request.",
response = Response.class),
@ApiResponse(
code = 404,
message = "Not Found. \n Operation configuration not provided",
response = Response.class),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Server error occurred while deleting the operation configuration.",
response = Response.class)
}
)
Response deleteOperationConfiguration();
} }

@ -22,6 +22,12 @@ import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.OTPManagementException;
import io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.OperationConfigurationService;
import io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.dto.OperationConfig;
import io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.exceptions.OperationConfigAlreadyExistsException;
import io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.exceptions.OperationConfigException;
import io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.exceptions.OperationConfigNotFoundException;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.base.MultitenantConstants; import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext;
@ -61,6 +67,7 @@ import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam; import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST; import javax.ws.rs.POST;
import javax.ws.rs.PUT; import javax.ws.rs.PUT;
import javax.ws.rs.DELETE;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import javax.ws.rs.Produces; import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam; import javax.ws.rs.QueryParam;
@ -313,4 +320,89 @@ public class DeviceManagementConfigServiceImpl implements DeviceManagementConfig
return Response.status(Response.Status.OK).build(); return Response.status(Response.Status.OK).build();
} }
@GET
@Path("/operation-configuration")
@Produces({MediaType.APPLICATION_JSON})
public Response getOperationConfiguration() {
OperationConfig config;
try {
config = OperationConfigurationService.getOperationConfig();
} catch (OperationConfigException e) {
String msg = "Error occurred getting operation configuration";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
if (config == null) {
String msg = "Operation configuration not provided";
log.error(msg);
return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
} else {
return Response.status(Response.Status.OK).entity(config).build();
}
}
@POST
@Path("/operation-configuration")
@Produces({MediaType.APPLICATION_JSON})
public Response addOperationConfiguration(OperationConfig config) {
try {
if (config != null) {
OperationConfigurationService.addOperationConfiguration(config);
} else {
String msg = "Operation configuration not provided";
log.error(msg);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
}
} catch (OperationConfigException e) {
String msg = "Error occurred adding operation configuration";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (OperationConfigAlreadyExistsException e) {
String msg = "Operation configuration already exists";
log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
}
return Response.status(Response.Status.OK).entity(config).build();
}
@PUT
@Path("/operation-configuration")
@Produces({MediaType.APPLICATION_JSON})
public Response updateOperationConfiguration(OperationConfig config) {
try {
if (config != null) {
OperationConfigurationService.updateOperationConfiguration(config);
} else {
String msg = "Operation configuration body not provided";
log.error(msg);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
}
} catch (OperationConfigException e) {
String msg = "Error occurred adding operation configuration";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
return Response.status(Response.Status.OK).entity(config).build();
}
@DELETE
@Path("/operation-configuration")
@Produces({MediaType.APPLICATION_JSON})
public Response deleteOperationConfiguration() {
String msg;
try {
OperationConfigurationService.deleteOperationConfiguration();
} catch (OperationConfigException e) {
msg = "Error occurred while deleting operation configuration";
log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} catch (OperationConfigNotFoundException e) {
msg = "Operation configuration not provided";
log.error(msg, e);
return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
}
msg = "Operation configuration deleted successfully";
log.info(msg);
return Response.status(Response.Status.OK).entity(msg).build();
}
} }

@ -1365,7 +1365,7 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl {
query += " AND i.VALUE_FIELD LIKE ?" ; query += " AND i.VALUE_FIELD LIKE ?" ;
} }
if (user != null && !user.isEmpty()) { if (user != null && !user.isEmpty()) {
query += " AND e.OWNER = ?"; query += " AND e.OWNER LIKE ?";
isOwnerProvided = true; isOwnerProvided = true;
} }
if (status != null && !status.isEmpty()) { if (status != null && !status.isEmpty()) {
@ -1395,7 +1395,7 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl {
ps.setString(index++, EnrolmentInfo.Status.REMOVED.toString()); ps.setString(index++, EnrolmentInfo.Status.REMOVED.toString());
ps.setString(index++, EnrolmentInfo.Status.DELETED.toString()); ps.setString(index++, EnrolmentInfo.Status.DELETED.toString());
if (isDeviceNameProvided) { if (isDeviceNameProvided) {
ps.setString(index++, name + "%"); ps.setString(index++, "%" + name + "%");
} }
if (isOwnershipProvided) { if (isOwnershipProvided) {
ps.setString(index++, ownership); ps.setString(index++, ownership);
@ -1404,7 +1404,7 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl {
ps.setString(index++, "%" + serial + "%"); ps.setString(index++, "%" + serial + "%");
} }
if (isOwnerProvided) { if (isOwnerProvided) {
ps.setString(index++, user); ps.setString(index++, "%" + user + "%");
} }
if (isStatusProvided) { if (isStatusProvided) {
for (String deviceStatus : status) { for (String deviceStatus : status) {

@ -1105,7 +1105,7 @@ public class PostgreSQLDeviceDAOImpl extends GenericDeviceDAOImpl {
isOwnershipProvided = true; isOwnershipProvided = true;
} }
if (user != null && !user.isEmpty()) { if (user != null && !user.isEmpty()) {
query += " AND e.OWNER = ?"; query += " AND e.OWNER LIKE ?";
isOwnerProvided = true; isOwnerProvided = true;
} }
if (status != null && !status.isEmpty()) { if (status != null && !status.isEmpty()) {
@ -1136,13 +1136,13 @@ public class PostgreSQLDeviceDAOImpl extends GenericDeviceDAOImpl {
ps.setString(index++, EnrolmentInfo.Status.REMOVED.toString()); ps.setString(index++, EnrolmentInfo.Status.REMOVED.toString());
ps.setString(index++, EnrolmentInfo.Status.DELETED.toString()); ps.setString(index++, EnrolmentInfo.Status.DELETED.toString());
if (isDeviceNameProvided) { if (isDeviceNameProvided) {
ps.setString(index++, name + "%"); ps.setString(index++, "%" + name + "%");
} }
if (isOwnershipProvided) { if (isOwnershipProvided) {
ps.setString(index++, ownership); ps.setString(index++, ownership);
} }
if (isOwnerProvided) { if (isOwnerProvided) {
ps.setString(index++, user); ps.setString(index++, "%" + user + "%");
} }
if (isStatusProvided) { if (isStatusProvided) {
for (String deviceStatus : status) { for (String deviceStatus : status) {

@ -977,7 +977,7 @@ public class SQLServerDeviceDAOImpl extends GenericDeviceDAOImpl {
isOwnershipProvided = true; isOwnershipProvided = true;
} }
if (user != null && !user.isEmpty()) { if (user != null && !user.isEmpty()) {
query += " AND e.OWNER = ?"; query += " AND e.OWNER LIKE ?";
isOwnerProvided = true; isOwnerProvided = true;
} }
if (status != null && !status.isEmpty()) { if (status != null && !status.isEmpty()) {
@ -1008,13 +1008,13 @@ public class SQLServerDeviceDAOImpl extends GenericDeviceDAOImpl {
ps.setString(index++, EnrolmentInfo.Status.REMOVED.toString()); ps.setString(index++, EnrolmentInfo.Status.REMOVED.toString());
ps.setString(index++, EnrolmentInfo.Status.DELETED.toString()); ps.setString(index++, EnrolmentInfo.Status.DELETED.toString());
if (isDeviceNameProvided) { if (isDeviceNameProvided) {
ps.setString(index++, name + "%"); ps.setString(index++, "%" + name + "%");
} }
if (isOwnershipProvided) { if (isOwnershipProvided) {
ps.setString(index++, ownership); ps.setString(index++, ownership);
} }
if (isOwnerProvided) { if (isOwnerProvided) {
ps.setString(index++, user); ps.setString(index++, "%" + user + "%");
} }
if (isStatusProvided) { if (isStatusProvided) {
for (String deviceStatus : status) { for (String deviceStatus : status) {

@ -100,6 +100,7 @@ public class DeviceManagementDataHolder {
private DeviceStatusManagementService deviceStatusManagementService; private DeviceStatusManagementService deviceStatusManagementService;
private APIApplicationServices apiApplicationServices; private APIApplicationServices apiApplicationServices;
private PublisherRESTAPIServices publisherRESTAPIServices; private PublisherRESTAPIServices publisherRESTAPIServices;
private DeviceManagementStartupHandler deviceManagementStartupHandler;
private final Map<DeviceType, DeviceStatusTaskPluginConfig> deviceStatusTaskPluginConfigs = Collections.synchronizedMap( private final Map<DeviceType, DeviceStatusTaskPluginConfig> deviceStatusTaskPluginConfigs = Collections.synchronizedMap(
new HashMap<>()); new HashMap<>());
@ -457,4 +458,12 @@ public class DeviceManagementDataHolder {
public void setGroupAccessAuthorizationService(GroupAccessAuthorizationService groupAccessAuthorizationService) { public void setGroupAccessAuthorizationService(GroupAccessAuthorizationService groupAccessAuthorizationService) {
this.groupAccessAuthorizationService = groupAccessAuthorizationService; this.groupAccessAuthorizationService = groupAccessAuthorizationService;
} }
public DeviceManagementStartupHandler getDeviceManagementStartupHandler() {
return deviceManagementStartupHandler;
}
public void setDeviceManagementStartupHandler(DeviceManagementStartupHandler deviceManagementStartupHandler) {
this.deviceManagementStartupHandler = deviceManagementStartupHandler;
}
} }

@ -259,8 +259,10 @@ public class DeviceManagementServiceComponent {
TenantCreateObserver listener = new TenantCreateObserver(); TenantCreateObserver listener = new TenantCreateObserver();
bundleContext.registerService(Axis2ConfigurationContextObserver.class.getName(), listener, null); bundleContext.registerService(Axis2ConfigurationContextObserver.class.getName(), listener, null);
UserRoleCreateObserver userRoleCreateObserver = new UserRoleCreateObserver(); /* Registering Device Management Startup Handler */
bundleContext.registerService(ServerStartupObserver.class.getName(), userRoleCreateObserver, null); DeviceManagementStartupHandler deviceManagementStartupHandler = new DeviceManagementStartupHandler();
DeviceManagementDataHolder.getInstance().setDeviceManagementStartupHandler(deviceManagementStartupHandler);
bundleContext.registerService(ServerStartupObserver.class.getName(), deviceManagementStartupHandler, null);
/* Registering Device Management Service */ /* Registering Device Management Service */
DeviceManagementProviderService deviceManagementProvider = new DeviceManagementProviderServiceImpl(); DeviceManagementProviderService deviceManagementProvider = new DeviceManagementProviderServiceImpl();

@ -0,0 +1,149 @@
/*
* Copyright (c) 2018 - 2024, 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 io.entgra.device.mgt.core.device.mgt.core.internal;
import com.google.gson.Gson;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataManagementException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.TransactionManagementException;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.Metadata;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.MetadataManagementService;
import io.entgra.device.mgt.core.device.mgt.core.DeviceManagementConstants;
import io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.dto.OperationConfig;
import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationDAO;
import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationManagementDAOException;
import io.entgra.device.mgt.core.device.mgt.core.operation.mgt.dao.OperationManagementDAOFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.core.ServerStartupObserver;
import org.wso2.carbon.user.api.AuthorizationManager;
import org.wso2.carbon.user.api.Permission;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.api.UserStoreManager;
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
public class DeviceManagementStartupHandler implements ServerStartupObserver {
private static final Log log = LogFactory.getLog(DeviceManagementStartupHandler.class);
private static final Gson gson = new Gson();
private static final String OPERATION_CONFIG = "OPERATION_CONFIG";
private static final String tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME;
@Override
public void completingServerStartup() {
}
@Override
public void completedServerStartup() {
userRoleCreateObserver();
operationStatusChangeObserver();
}
private void userRoleCreateObserver() {
try {
UserStoreManager userStoreManager =
DeviceManagementDataHolder.getInstance().getRealmService().getTenantUserRealm(
MultitenantConstants.SUPER_TENANT_ID).getUserStoreManager();
String tenantAdminName =
DeviceManagementDataHolder.getInstance().getRealmService().getTenantUserRealm(
MultitenantConstants.SUPER_TENANT_ID).getRealmConfiguration().getAdminUserName();
AuthorizationManager authorizationManager = DeviceManagementDataHolder.getInstance().getRealmService()
.getTenantUserRealm(MultitenantConstants.SUPER_TENANT_ID).getAuthorizationManager();
if (!userStoreManager.isExistingRole(DeviceManagementConstants.User.DEFAULT_DEVICE_ADMIN)) {
userStoreManager.addRole(
DeviceManagementConstants.User.DEFAULT_DEVICE_ADMIN,
null,
DeviceManagementConstants.User.PERMISSIONS_FOR_DEVICE_ADMIN);
} else {
for (Permission permission : DeviceManagementConstants.User.PERMISSIONS_FOR_DEVICE_ADMIN) {
authorizationManager.authorizeRole(DeviceManagementConstants.User.DEFAULT_DEVICE_ADMIN,
permission.getResourceId(), permission.getAction());
}
}
if (!userStoreManager.isExistingRole(DeviceManagementConstants.User.DEFAULT_DEVICE_USER)) {
userStoreManager.addRole(
DeviceManagementConstants.User.DEFAULT_DEVICE_USER,
null,
DeviceManagementConstants.User.PERMISSIONS_FOR_DEVICE_USER);
} else {
for (Permission permission : DeviceManagementConstants.User.PERMISSIONS_FOR_DEVICE_USER) {
authorizationManager.authorizeRole(DeviceManagementConstants.User.DEFAULT_DEVICE_USER,
permission.getResourceId(), permission.getAction());
}
}
userStoreManager.updateRoleListOfUser(tenantAdminName, null,
new String[]{DeviceManagementConstants.User.DEFAULT_DEVICE_ADMIN,
DeviceManagementConstants.User.DEFAULT_DEVICE_USER});
if (log.isDebugEnabled()) {
log.debug("Device management roles: " + DeviceManagementConstants.User.DEFAULT_DEVICE_USER + ", " +
DeviceManagementConstants.User.DEFAULT_DEVICE_ADMIN + " created for the tenant:" + tenantDomain + "."
);
log.debug("Tenant administrator: " + tenantAdminName + "@" + tenantDomain +
" is assigned to the role:" + DeviceManagementConstants.User.DEFAULT_DEVICE_ADMIN + "."
);
}
} catch (UserStoreException e) {
log.error("Error occurred while creating roles for the tenant: " + tenantDomain + ".");
}
}
private void operationStatusChangeObserver () {
MetadataManagementService metadataManagementService = DeviceManagementDataHolder
.getInstance().getMetadataManagementService();
OperationDAO operationDAO = OperationManagementDAOFactory.getOperationDAO();
Metadata metadata;
int numOfRecordsUpdated;
try {
metadata = metadataManagementService.retrieveMetadata(OPERATION_CONFIG);
if (metadata != null) {
OperationConfig operationConfiguration = gson.fromJson(metadata.getMetaValue(), OperationConfig.class);
String[] deviceTypes = operationConfiguration.getDeviceTypes();
String initialOperationStatus = operationConfiguration.getInitialOperationStatus();
String requiredStatusChange = operationConfiguration.getRequiredStatusChange();
for (String deviceType : deviceTypes) {
try {
OperationManagementDAOFactory.beginTransaction();
try {
numOfRecordsUpdated = operationDAO.updateOperationByDeviceTypeAndInitialStatus(deviceType,
initialOperationStatus, requiredStatusChange);
log.info(numOfRecordsUpdated + " operations updated successfully for the" + deviceType);
OperationManagementDAOFactory.commitTransaction();
} catch (OperationManagementDAOException e) {
OperationManagementDAOFactory.rollbackTransaction();
String msg = "Error occurred while updating operation status. DeviceType : " + deviceType + ", " +
"Initial operation status: " + initialOperationStatus + ", Required status:" + requiredStatusChange;
log.error(msg, e);
}
} catch (TransactionManagementException e) {
String msg = "Transactional error occurred while updating the operation status";
log.error(msg, e);
} finally {
OperationManagementDAOFactory.closeConnection();
}
}
} else {
log.info("Operation configuration not provided");
}
} catch (MetadataManagementException e) {
String msg = "Error occurred while retrieving the operation configuration";
log.error(msg, e);
}
}
}

@ -1,89 +0,0 @@
/*
* Copyright (c) 2018 - 2023, 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 io.entgra.device.mgt.core.device.mgt.core.internal;
import io.entgra.device.mgt.core.device.mgt.core.DeviceManagementConstants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.core.ServerStartupObserver;
import org.wso2.carbon.user.api.AuthorizationManager;
import org.wso2.carbon.user.api.Permission;
import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.api.UserStoreManager;
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
public class UserRoleCreateObserver implements ServerStartupObserver {
private static final Log log = LogFactory.getLog(UserRoleCreateObserver.class);
@Override
public void completingServerStartup() {
}
@Override
public void completedServerStartup() {
String tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME;
try {
UserStoreManager userStoreManager =
DeviceManagementDataHolder.getInstance().getRealmService().getTenantUserRealm(
MultitenantConstants.SUPER_TENANT_ID).getUserStoreManager();
String tenantAdminName =
DeviceManagementDataHolder.getInstance().getRealmService().getTenantUserRealm(
MultitenantConstants.SUPER_TENANT_ID).getRealmConfiguration().getAdminUserName();
AuthorizationManager authorizationManager = DeviceManagementDataHolder.getInstance().getRealmService()
.getTenantUserRealm(MultitenantConstants.SUPER_TENANT_ID).getAuthorizationManager();
if (!userStoreManager.isExistingRole(DeviceManagementConstants.User.DEFAULT_DEVICE_ADMIN)) {
userStoreManager.addRole(
DeviceManagementConstants.User.DEFAULT_DEVICE_ADMIN,
null,
DeviceManagementConstants.User.PERMISSIONS_FOR_DEVICE_ADMIN);
} else {
for (Permission permission : DeviceManagementConstants.User.PERMISSIONS_FOR_DEVICE_ADMIN) {
authorizationManager.authorizeRole(DeviceManagementConstants.User.DEFAULT_DEVICE_ADMIN,
permission.getResourceId(), permission.getAction());
}
}
if (!userStoreManager.isExistingRole(DeviceManagementConstants.User.DEFAULT_DEVICE_USER)) {
userStoreManager.addRole(
DeviceManagementConstants.User.DEFAULT_DEVICE_USER,
null,
DeviceManagementConstants.User.PERMISSIONS_FOR_DEVICE_USER);
} else {
for (Permission permission : DeviceManagementConstants.User.PERMISSIONS_FOR_DEVICE_USER) {
authorizationManager.authorizeRole(DeviceManagementConstants.User.DEFAULT_DEVICE_USER,
permission.getResourceId(), permission.getAction());
}
}
userStoreManager.updateRoleListOfUser(tenantAdminName, null,
new String[] {DeviceManagementConstants.User.DEFAULT_DEVICE_ADMIN,
DeviceManagementConstants.User.DEFAULT_DEVICE_USER});
if (log.isDebugEnabled()) {
log.debug("Device management roles: " + DeviceManagementConstants.User.DEFAULT_DEVICE_USER + ", " +
DeviceManagementConstants.User.DEFAULT_DEVICE_ADMIN + " created for the tenant:" + tenantDomain + "."
);
log.debug("Tenant administrator: " + tenantAdminName + "@" + tenantDomain +
" is assigned to the role:" + DeviceManagementConstants.User.DEFAULT_DEVICE_ADMIN + "."
);
}
} catch (UserStoreException e) {
log.error("Error occurred while creating roles for the tenant: " + tenantDomain + ".");
}
}
}

@ -0,0 +1,113 @@
/*
* Copyright (c) 2018 - 2024, 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 io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task;
import com.google.gson.Gson;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataKeyAlreadyExistsException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataKeyNotFoundException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataManagementException;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.Metadata;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.MetadataManagementService;
import io.entgra.device.mgt.core.device.mgt.core.internal.DeviceManagementDataHolder;
import io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.dto.OperationConfig;
import io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.exceptions.OperationConfigAlreadyExistsException;
import io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.exceptions.OperationConfigException;
import io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.exceptions.OperationConfigNotFoundException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class OperationConfigurationService {
private static final Log log = LogFactory.getLog(OperationConfigurationService.class);
private static final Gson gson = new Gson();
private static final String STRING = "STRING";
private static final String OPERATION_CONFIG = "OPERATION_CONFIG";
static MetadataManagementService metadataManagementService = DeviceManagementDataHolder.getInstance().getMetadataManagementService();
public static OperationConfig getOperationConfig() throws OperationConfigException {
Metadata metadata;
try {
metadata = metadataManagementService.retrieveMetadata(OPERATION_CONFIG);
} catch (MetadataManagementException e) {
String msg = "Error occurred while retrieving operation configuration";
log.error(msg, e);
throw new OperationConfigException(msg, e);
}
if (metadata != null) {
return gson.fromJson(metadata.getMetaValue(), OperationConfig.class);
} else {
return null;
}
}
public static void addOperationConfiguration(OperationConfig config) throws OperationConfigException,
OperationConfigAlreadyExistsException {
Metadata metadata = new Metadata();
metadata.setDataType(STRING);
metadata.setMetaKey(OPERATION_CONFIG);
metadata.setMetaValue(gson.toJson(config));
try {
metadataManagementService.createMetadata(metadata);
} catch (MetadataManagementException e) {
String msg = "Error occurred while adding operation configuration";
log.error(msg, e);
throw new OperationConfigException(msg, e);
} catch (MetadataKeyAlreadyExistsException e) {
String msg = "Operation configuration already exists";
log.error(msg, e);
throw new OperationConfigAlreadyExistsException(msg, e);
}
}
public static void updateOperationConfiguration(OperationConfig config) throws OperationConfigException {
Metadata metadata = new Metadata();
metadata.setDataType(STRING);
metadata.setMetaKey(OPERATION_CONFIG);
metadata.setMetaValue(gson.toJson(config));
try {
metadataManagementService.updateMetadata(metadata);
} catch (MetadataManagementException e) {
String msg = "Error occurred while updating operation configuration";
log.error(msg, e);
throw new OperationConfigException(msg, e);
}
}
public static void deleteOperationConfiguration() throws OperationConfigException, OperationConfigNotFoundException {
try {
metadataManagementService.deleteMetadata(OPERATION_CONFIG);
} catch (MetadataManagementException e) {
String msg = "Error occurred while deleting operation configuration";
log.error(msg, e);
throw new OperationConfigException(msg, e);
} catch (MetadataKeyNotFoundException e) {
String msg = "Operation configuration already exists";
log.error(msg, e);
throw new OperationConfigNotFoundException(msg, e);
}
}
}

@ -0,0 +1,55 @@
/*
* Copyright (c) 2018 - 2024, 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 io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.dto;
/**
* DTO for Operation configuration.
*/
public class OperationConfig {
private String[] deviceTypes;
private String initialOperationStatus;
private String requiredStatusChange;
public String[] getDeviceTypes() {
return deviceTypes;
}
public void setDeviceTypes(String[] deviceTypes) {
this.deviceTypes = deviceTypes;
}
public String getInitialOperationStatus() {
return initialOperationStatus;
}
public void setInitialOperationStatus(String initialOperationStatus) {
this.initialOperationStatus = initialOperationStatus;
}
public String getRequiredStatusChange() {
return requiredStatusChange;
}
public void setRequiredStatusChange(String requiredStatusChange) {
this.requiredStatusChange = requiredStatusChange;
}
}

@ -0,0 +1,60 @@
/*
* Copyright (c) 2018 - 2024, 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 io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.exceptions;
/**
* Custom exception class to be used in operation configuration service related functionalities.
*/
public class OperationConfigAlreadyExistsException extends Exception {
private static final long serialVersionUID = -1814347544027733436L;
private String errorMessage;
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public OperationConfigAlreadyExistsException(String msg, Exception nestedEx) {
super(msg, nestedEx);
setErrorMessage(msg);
}
public OperationConfigAlreadyExistsException(String message, Throwable cause) {
super(message, cause);
setErrorMessage(message);
}
public OperationConfigAlreadyExistsException(String msg) {
super(msg);
setErrorMessage(msg);
}
public OperationConfigAlreadyExistsException() {
super();
}
public OperationConfigAlreadyExistsException(Throwable cause) {
super(cause);
}
}

@ -0,0 +1,60 @@
/*
* Copyright (c) 2018 - 2024, 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 io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.exceptions;
/**
* Custom exception class to be used in operation configuration related functionalities.
*/
public class OperationConfigException extends Exception {
private static final long serialVersionUID = -8933146283800122661L;
private String errorMessage;
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public OperationConfigException(String msg, Exception nestedEx) {
super(msg, nestedEx);
setErrorMessage(msg);
}
public OperationConfigException(String message, Throwable cause) {
super(message, cause);
setErrorMessage(message);
}
public OperationConfigException(String msg) {
super(msg);
setErrorMessage(msg);
}
public OperationConfigException() {
super();
}
public OperationConfigException(Throwable cause) {
super(cause);
}
}

@ -0,0 +1,60 @@
/*
* Copyright (c) 2018 - 2023, 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 io.entgra.device.mgt.core.device.mgt.core.operation.change.status.task.exceptions;
/**
* Custom exception class to be used in Operation configuration related functionalities.
*/
public class OperationConfigNotFoundException extends Exception {
private static final long serialVersionUID = 5260831982626354815L;
private String errorMessage;
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public OperationConfigNotFoundException(String msg, Exception nestedEx) {
super(msg, nestedEx);
setErrorMessage(msg);
}
public OperationConfigNotFoundException(String message, Throwable cause) {
super(message, cause);
setErrorMessage(message);
}
public OperationConfigNotFoundException(String msg) {
super(msg);
setErrorMessage(msg);
}
public OperationConfigNotFoundException() {
super();
}
public OperationConfigNotFoundException(Throwable cause) {
super(cause);
}
}

@ -61,6 +61,9 @@ public interface OperationDAO {
boolean updateOperationStatus(int enrolmentId, int operationId,Operation.Status status) boolean updateOperationStatus(int enrolmentId, int operationId,Operation.Status status)
throws OperationManagementDAOException; throws OperationManagementDAOException;
int updateOperationByDeviceTypeAndInitialStatus(String deiceType, String initialStatus, String requiredStatus)
throws OperationManagementDAOException;
void updateEnrollmentOperationsStatus(int enrolmentId, String operationCode, Operation.Status existingStatus, void updateEnrollmentOperationsStatus(int enrolmentId, String operationCode, Operation.Status existingStatus,
Operation.Status newStatus) throws OperationManagementDAOException; Operation.Status newStatus) throws OperationManagementDAOException;

@ -128,6 +128,38 @@ public class GenericOperationDAOImpl implements OperationDAO {
return isUpdated; return isUpdated;
} }
public int updateOperationByDeviceTypeAndInitialStatus(String deiceType, String initialStatus, String requiredStatus)
throws OperationManagementDAOException {
int numOfRecordsUpdated;
long time = DeviceManagementDAOUtil.getCurrentUTCTime();
String sql = "UPDATE DM_ENROLMENT_OP_MAPPING SET STATUS=?, UPDATED_TIMESTAMP=? WHERE DEVICE_TYPE=?";
if (initialStatus == null) {
sql += " AND STATUS IS NULL";
} else {
sql += " AND STATUS=?";
}
try (
Connection connection = OperationManagementDAOFactory.getConnection();
PreparedStatement stmt = connection.prepareStatement(sql)
) {
stmt.setString(1, requiredStatus);
stmt.setLong(2, time);
stmt.setString(3, deiceType);
if (initialStatus != null) {
stmt.setString(4, initialStatus);
}
numOfRecordsUpdated = stmt.executeUpdate();
} catch (SQLException e) {
throw new OperationManagementDAOException("Error occurred while update device mapping operation status " +
e.getMessage(), e);
}
return numOfRecordsUpdated;
}
@Override @Override
public void updateEnrollmentOperationsStatus(int enrolmentId, String operationCode, Operation.Status existingStatus, public void updateEnrollmentOperationsStatus(int enrolmentId, String operationCode, Operation.Status existingStatus,
Operation.Status newStatus) throws OperationManagementDAOException { Operation.Status newStatus) throws OperationManagementDAOException {

@ -672,7 +672,7 @@ CREATE TABLE IF NOT EXISTS DM_METADATA (
-- DM_TAG TABLE -- -- DM_TAG TABLE --
CREATE TABLE IF NOT EXISTS DM_TAG ( CREATE TABLE IF NOT EXISTS DM_TAG (
ID BIGINT AUTO_INCREMENT, ID INTEGER AUTO_INCREMENT,
NAME VARCHAR(255) NOT NULL, NAME VARCHAR(255) NOT NULL,
DESCRIPTION VARCHAR(255) NULL, DESCRIPTION VARCHAR(255) NULL,
TENANT_ID INTEGER NOT NULL, TENANT_ID INTEGER NOT NULL,
@ -683,8 +683,8 @@ CREATE TABLE IF NOT EXISTS DM_TAG (
-- DM_DEVICE_TAG_MAPPING TABLE -- -- DM_DEVICE_TAG_MAPPING TABLE --
CREATE TABLE IF NOT EXISTS DM_DEVICE_TAG_MAPPING ( CREATE TABLE IF NOT EXISTS DM_DEVICE_TAG_MAPPING (
ENROLMENT_ID BIGINT NOT NULL, ENROLMENT_ID INTEGER NOT NULL,
TAG_ID BIGINT NOT NULL, TAG_ID INTEGER NOT NULL,
TENANT_ID INTEGER NOT NULL, TENANT_ID INTEGER NOT NULL,
PRIMARY KEY (ENROLMENT_ID, TAG_ID, TENANT_ID), PRIMARY KEY (ENROLMENT_ID, TAG_ID, TENANT_ID),
FOREIGN KEY (ENROLMENT_ID) REFERENCES DM_ENROLMENT(ID), FOREIGN KEY (ENROLMENT_ID) REFERENCES DM_ENROLMENT(ID),

@ -79,6 +79,29 @@ public class HTTPDeviceTypeManagerService extends DeviceTypeManagerService imple
} }
configFeature.setMetaData(metaValues); configFeature.setMetaData(metaValues);
} }
if (feature.getConfirmationTexts() != null) {
List<String> confirmationTextValues = new ArrayList<>();
Feature.ConfirmationTexts confirmationText = feature.getConfirmationTexts();
confirmationTextValues.add(confirmationText.getDeleteConfirmModalTitle());
confirmationTextValues.add(confirmationText.getDeleteConfirmModalText());
confirmationTextValues.add(confirmationText.getDeleteConfirmationTextDescribe());
confirmationTextValues.add(confirmationText.getDeleteConfirmationText());
confirmationTextValues.add(confirmationText.getCancelText());
confirmationTextValues.add(confirmationText.getConfirmText());
confirmationTextValues.add(confirmationText.getInputLabel());
confirmationTextValues.add(confirmationText.getInputRequireMessage());
configFeature.setConfirmationTexts(confirmationTextValues);
}
if (feature.getDangerZoneTooltipTexts() != null) {
List<String> dangerZoneTextValues = new ArrayList<>();
Feature.DangerZoneTooltipTexts dangerZoneText = feature.getDangerZoneTooltipTexts();
dangerZoneTextValues.add(dangerZoneText.getToolTipTitle());
dangerZoneTextValues.add(dangerZoneText.getToolTipPopConfirmText());
dangerZoneTextValues.add(dangerZoneText.getConfirmText());
dangerZoneTextValues.add(dangerZoneText.getCancelText());
dangerZoneTextValues.add(dangerZoneText.getToolTipAvailable());
configFeature.setDangerZoneTooltipTexts(dangerZoneTextValues);
}
featureList.add(configFeature); featureList.add(configFeature);
} }
} }

@ -0,0 +1,127 @@
/*
* Copyright (c) 2018 - 2024, 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 io.entgra.device.mgt.core.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;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "confirmationTexts", propOrder = {
"deleteConfirmModalTitle",
"deleteConfirmModalText",
"deleteConfirmationTextDescribe",
"deleteConfirmationText",
"cancelText",
"confirmText",
"inputLabel",
"inputRequireMessage"
})
public class ConfirmationTexts {
@XmlElement(name = "deleteConfirmModalTitle")
private String deleteConfirmModalTitle;
@XmlElement(name = "deleteConfirmModalText")
private String deleteConfirmModalText;
@XmlElement(name = "deleteConfirmationTextDescribe")
private String deleteConfirmationTextDescribe;
@XmlElement(name = "deleteConfirmationText")
private String deleteConfirmationText;
@XmlElement(name = "cancelText")
private String cancelText;
@XmlElement(name = "confirmText")
private String confirmText;
@XmlElement(name = "inputLabel")
private String inputLabel;
@XmlElement(name = "inputRequireMessage")
private String inputRequireMessage;
public String getCancelText() {
return cancelText;
}
public void setCancelText(String cancelText) {
this.cancelText = cancelText;
}
public String getInputRequireMessage() {
return inputRequireMessage;
}
public void setInputRequireMessage(String inputRequireMessage) {
this.inputRequireMessage = inputRequireMessage;
}
public String getInputLabel() {
return inputLabel;
}
public void setInputLabel(String inputLabel) {
this.inputLabel = inputLabel;
}
public String getConfirmText() {
return confirmText;
}
public void setConfirmText(String confirmText) {
this.confirmText = confirmText;
}
public String getDeleteConfirmModalTitle() {
return deleteConfirmModalTitle;
}
public void setDeleteConfirmModalTitle(String deleteConfirmModalTitle) {
this.deleteConfirmModalTitle = deleteConfirmModalTitle;
}
public String getDeleteConfirmModalText() {
return deleteConfirmModalText;
}
public void setDeleteConfirmModalText(String deleteConfirmModalText) {
this.deleteConfirmModalText = deleteConfirmModalText;
}
public String getDeleteConfirmationTextDescribe() {
return deleteConfirmationTextDescribe;
}
public void setDeleteConfirmationTextDescribe(String deleteConfirmationTextDescribe) {
this.deleteConfirmationTextDescribe = deleteConfirmationTextDescribe;
}
public String getDeleteConfirmationText() {
return deleteConfirmationText;
}
public void setDeleteConfirmationText(String deleteConfirmationText) {
this.deleteConfirmationText = deleteConfirmationText;
}
}

@ -0,0 +1,90 @@
/*
* Copyright (c) 2018 - 2024, 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 io.entgra.device.mgt.core.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;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "dangerZoneTooltipTexts", propOrder = {
"toolTipTitle",
"toolTipPopConfirmText",
"confirmText",
"cancelText",
"toolTipAvailable"
})
public class DangerZoneTooltipTexts {
@XmlElement(name = "toolTipTitle")
private String toolTipTitle;
@XmlElement(name = "toolTipPopConfirmText")
private String toolTipPopConfirmText;
@XmlElement(name = "confirmText")
private String confirmText;
@XmlElement(name = "cancelText")
private String cancelText;
@XmlElement(name = "toolTipAvailable")
private String toolTipAvailable;
public String getToolTipAvailable() {
return toolTipAvailable;
}
public void setToolTipAvailable(String toolTipAvailable) {
this.toolTipAvailable = toolTipAvailable;
}
public String getToolTipTitle() {
return toolTipTitle;
}
public void setToolTipTitle(String toolTipTitle) {
this.toolTipTitle = toolTipTitle;
}
public String getToolTipPopConfirmText() {
return toolTipPopConfirmText;
}
public void setToolTipPopConfirmText(String toolTipPopConfirmText) {
this.toolTipPopConfirmText = toolTipPopConfirmText;
}
public String getConfirmText() {
return confirmText;
}
public void setConfirmText(String confirmText) {
this.confirmText = confirmText;
}
public String getCancelText() {
return cancelText;
}
public void setCancelText(String cancelText) {
this.cancelText = cancelText;
}
}

@ -47,7 +47,9 @@ import java.util.List;
"description", "description",
"tooltip", "tooltip",
"operation", "operation",
"metaData" "metaData",
"confirmationTexts",
"dangerZoneTooltipTexts"
}) })
public class Feature { public class Feature {
@ -73,6 +75,12 @@ public class Feature {
@XmlElement(name = "Property", required = true) @XmlElement(name = "Property", required = true)
private List<String> metaData; private List<String> metaData;
@XmlElement(name = "ConfirmationTexts", required = false)
private List<String> confirmationTexts;
@XmlElement(name = "DangerZoneTooltipTexts", required = false)
private List<String> dangerZoneTooltipTexts;
/** /**
* Gets the value of the name property. * Gets the value of the name property.
* *
@ -209,4 +217,20 @@ public class Feature {
public void setType(String type) { public void setType(String type) {
this.type = type; this.type = type;
} }
public List<String> getConfirmationTexts() {
return confirmationTexts;
}
public void setConfirmationTexts(List<String> confirmationTexts) {
this.confirmationTexts = confirmationTexts;
}
public List<String> getDangerZoneTooltipTexts() {
return dangerZoneTooltipTexts;
}
public void setDangerZoneTooltipTexts(List<String> dangerZoneTooltipTexts) {
this.dangerZoneTooltipTexts = dangerZoneTooltipTexts;
}
} }

@ -41,8 +41,10 @@ import javax.xml.bind.annotation.*;
*/ */
@XmlAccessorType(XmlAccessType.FIELD) @XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Operation", propOrder = { @XmlType(name = "Operation", propOrder = {
"params", "params",
"metadata" "metadata",
"confirmationTexts",
"tooltipTexts"
}) })
public class Operation { public class Operation {
@ -58,6 +60,28 @@ public class Operation {
@XmlAttribute(name = "icon") @XmlAttribute(name = "icon")
private String icon; private String icon;
@XmlElement(name = "tooltipTexts", required = false)
private DangerZoneTooltipTexts tooltipTexts;
@XmlElement(name = "confirmationTexts", required = false)
private ConfirmationTexts confirmationTexts;
public DangerZoneTooltipTexts getTooltipTexts() {
return tooltipTexts;
}
public void setTooltipTexts(DangerZoneTooltipTexts tooltipTexts) {
this.tooltipTexts = tooltipTexts;
}
public ConfirmationTexts getConfirmationTexts() {
return confirmationTexts;
}
public void setConfirmationTexts(ConfirmationTexts confirmationTexts) {
this.confirmationTexts = confirmationTexts;
}
public Params getParams() { public Params getParams() {
return params; return params;
} }

@ -116,7 +116,32 @@ public class ConfigurationBasedFeatureManager implements FeatureManager {
operationMeta.put(UI_PARAMS, uiParams); operationMeta.put(UI_PARAMS, uiParams);
operationMeta.put(FORM_PARAMS, formParams); operationMeta.put(FORM_PARAMS, formParams);
} }
if (operation.getConfirmationTexts() != null) {
Feature.ConfirmationTexts confirmationTexts = new Feature.ConfirmationTexts();
confirmationTexts.setDeleteConfirmModalTitle(
operation.getConfirmationTexts().getDeleteConfirmModalTitle());
confirmationTexts.setDeleteConfirmModalText(
operation.getConfirmationTexts().getDeleteConfirmModalText());
confirmationTexts.setDeleteConfirmationTextDescribe(
operation.getConfirmationTexts().getDeleteConfirmationTextDescribe());
confirmationTexts.setDeleteConfirmationText(
operation.getConfirmationTexts().getDeleteConfirmationText());
confirmationTexts.setCancelText(operation.getConfirmationTexts().getCancelText());
confirmationTexts.setConfirmText(operation.getConfirmationTexts().getConfirmText());
confirmationTexts.setInputLabel(operation.getConfirmationTexts().getInputLabel());
confirmationTexts.setInputRequireMessage(
operation.getConfirmationTexts().getInputRequireMessage());
deviceFeature.setConfirmationTexts(confirmationTexts);
}
if (operation.getTooltipTexts() != null) {
Feature.DangerZoneTooltipTexts tooltipTexts = new Feature.DangerZoneTooltipTexts();
tooltipTexts.setToolTipTitle(operation.getTooltipTexts().getToolTipTitle());
tooltipTexts.setToolTipPopConfirmText(operation.getTooltipTexts().getToolTipPopConfirmText());
tooltipTexts.setConfirmText(operation.getTooltipTexts().getConfirmText());
tooltipTexts.setCancelText(operation.getTooltipTexts().getCancelText());
tooltipTexts.setToolTipAvailable(operation.getTooltipTexts().getToolTipAvailable());
deviceFeature.setDangerZoneTooltipTexts(tooltipTexts);
}
if (metadataEntries == null) { if (metadataEntries == null) {
metadataEntries = new ArrayList<>(); metadataEntries = new ArrayList<>();
} }

@ -362,6 +362,7 @@
<Scope>and:ops:change-lock-code</Scope> <Scope>and:ops:change-lock-code</Scope>
<Scope>and:ops:upgrade-firmware</Scope> <Scope>and:ops:upgrade-firmware</Scope>
<Scope>and:ops:send-notif</Scope> <Scope>and:ops:send-notif</Scope>
<Scope>and:ops:secure-folder</Scope>
<Scope>dm:geo:geo-fence:manage</Scope> <Scope>dm:geo:geo-fence:manage</Scope>
<Scope>dm:whitelable:view</Scope> <Scope>dm:whitelable:view</Scope>
<Scope>dm:whitelable:update</Scope> <Scope>dm:whitelable:update</Scope>

@ -878,7 +878,7 @@ CREATE TABLE IF NOT EXISTS DM_CEA_POLICIES (
-- DM_TAG TABLE -- -- DM_TAG TABLE --
CREATE TABLE IF NOT EXISTS DM_TAG ( CREATE TABLE IF NOT EXISTS DM_TAG (
ID BIGINT AUTO_INCREMENT, ID INTEGER AUTO_INCREMENT,
NAME VARCHAR(255) NOT NULL, NAME VARCHAR(255) NOT NULL,
DESCRIPTION VARCHAR(255) NULL, DESCRIPTION VARCHAR(255) NULL,
TENANT_ID INTEGER NOT NULL, TENANT_ID INTEGER NOT NULL,
@ -889,8 +889,8 @@ CREATE TABLE IF NOT EXISTS DM_TAG (
-- DM_DEVICE_TAG_MAPPING TABLE -- -- DM_DEVICE_TAG_MAPPING TABLE --
CREATE TABLE IF NOT EXISTS DM_DEVICE_TAG_MAPPING ( CREATE TABLE IF NOT EXISTS DM_DEVICE_TAG_MAPPING (
ENROLMENT_ID BIGINT NOT NULL, ENROLMENT_ID INTEGER NOT NULL,
TAG_ID BIGINT NOT NULL, TAG_ID INTEGER NOT NULL,
TENANT_ID INTEGER NOT NULL, TENANT_ID INTEGER NOT NULL,
PRIMARY KEY (ENROLMENT_ID, TAG_ID, TENANT_ID), PRIMARY KEY (ENROLMENT_ID, TAG_ID, TENANT_ID),
FOREIGN KEY (ENROLMENT_ID) REFERENCES DM_ENROLMENT(ID), FOREIGN KEY (ENROLMENT_ID) REFERENCES DM_ENROLMENT(ID),

@ -954,19 +954,19 @@ END;
-- DM_TAG TABLE -- -- DM_TAG TABLE --
CREATE TABLE IF NOT EXISTS DM_TAG ( CREATE TABLE IF NOT EXISTS DM_TAG (
ID BIGINT IDENTITY(1,1) PRIMARY KEY, ID INTEGER IDENTITY(1,1) PRIMARY KEY,
NAME NVARCHAR(255) NOT NULL, NAME NVARCHAR(255) NOT NULL,
DESCRIPTION NVARCHAR(255) NULL, DESCRIPTION NVARCHAR(255) NULL,
TENANT_ID INT NOT NULL, TENANT_ID INTEGER NOT NULL,
CONSTRAINT DM_TAG_NAME_TENANT_UNIQUE UNIQUE (NAME, TENANT_ID) CONSTRAINT DM_TAG_NAME_TENANT_UNIQUE UNIQUE (NAME, TENANT_ID)
); );
-- END OF DM_TAG TABLE -- -- END OF DM_TAG TABLE --
-- DM_DEVICE_TAG_MAPPING TABLE -- -- DM_DEVICE_TAG_MAPPING TABLE --
CREATE TABLE IF NOT EXISTS DM_DEVICE_TAG_MAPPING ( CREATE TABLE IF NOT EXISTS DM_DEVICE_TAG_MAPPING (
ENROLMENT_ID BIGINT NOT NULL, ENROLMENT_ID INTEGER NOT NULL,
TAG_ID BIGINT NOT NULL, TAG_ID INTEGER NOT NULL,
TENANT_ID INT NOT NULL, TENANT_ID INTEGER NOT NULL,
PRIMARY KEY (ENROLMENT_ID, TAG_ID, TENANT_ID), PRIMARY KEY (ENROLMENT_ID, TAG_ID, TENANT_ID),
FOREIGN KEY (ENROLMENT_ID) REFERENCES DM_ENROLMENT(ID), FOREIGN KEY (ENROLMENT_ID) REFERENCES DM_ENROLMENT(ID),
FOREIGN KEY (TAG_ID) REFERENCES DM_TAG(ID) ON DELETE CASCADE FOREIGN KEY (TAG_ID) REFERENCES DM_TAG(ID) ON DELETE CASCADE

@ -953,19 +953,19 @@ CREATE TABLE IF NOT EXISTS DM_CEA_POLICIES (
-- DM_TAG TABLE -- -- DM_TAG TABLE --
CREATE TABLE IF NOT EXISTS DM_TAG ( CREATE TABLE IF NOT EXISTS DM_TAG (
ID BIGINT AUTO_INCREMENT PRIMARY KEY, ID INTEGER AUTO_INCREMENT PRIMARY KEY,
NAME VARCHAR(255) NOT NULL, NAME VARCHAR(255) NOT NULL,
DESCRIPTION VARCHAR(255) NULL, DESCRIPTION VARCHAR(255) NULL,
TENANT_ID INT NOT NULL, TENANT_ID INTEGER NOT NULL,
CONSTRAINT DM_TAG_NAME_TENANT_UNIQUE UNIQUE (NAME, TENANT_ID) CONSTRAINT DM_TAG_NAME_TENANT_UNIQUE UNIQUE (NAME, TENANT_ID)
); );
-- END OF DM_TAG TABLE -- -- END OF DM_TAG TABLE --
-- DM_DEVICE_TAG_MAPPING TABLE -- -- DM_DEVICE_TAG_MAPPING TABLE --
CREATE TABLE IF NOT EXISTS DM_DEVICE_TAG_MAPPING ( CREATE TABLE IF NOT EXISTS DM_DEVICE_TAG_MAPPING (
ENROLMENT_ID BIGINT NOT NULL, ENROLMENT_ID INTEGER NOT NULL,
TAG_ID BIGINT NOT NULL, TAG_ID INTEGER NOT NULL,
TENANT_ID INT NOT NULL, TENANT_ID INTEGER NOT NULL,
PRIMARY KEY (ENROLMENT_ID, TAG_ID, TENANT_ID), PRIMARY KEY (ENROLMENT_ID, TAG_ID, TENANT_ID),
FOREIGN KEY (ENROLMENT_ID) REFERENCES DM_ENROLMENT(ID), FOREIGN KEY (ENROLMENT_ID) REFERENCES DM_ENROLMENT(ID),
FOREIGN KEY (TAG_ID) REFERENCES DM_TAG(ID) ON DELETE CASCADE FOREIGN KEY (TAG_ID) REFERENCES DM_TAG(ID) ON DELETE CASCADE

@ -1258,7 +1258,7 @@ END;
-- DM_TAG TABLE -- -- DM_TAG TABLE --
CREATE TABLE DM_TAG ( CREATE TABLE DM_TAG (
ID NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY PRIMARY KEY, ID NUMBER(10) GENERATED BY DEFAULT ON NULL AS IDENTITY PRIMARY KEY,
NAME VARCHAR2(255) NOT NULL, NAME VARCHAR2(255) NOT NULL,
DESCRIPTION VARCHAR2(255) NULL, DESCRIPTION VARCHAR2(255) NULL,
TENANT_ID NUMBER(10) NOT NULL, TENANT_ID NUMBER(10) NOT NULL,
@ -1268,8 +1268,8 @@ CREATE TABLE DM_TAG (
-- DM_DEVICE_TAG_MAPPING TABLE -- -- DM_DEVICE_TAG_MAPPING TABLE --
CREATE TABLE DM_DEVICE_TAG_MAPPING ( CREATE TABLE DM_DEVICE_TAG_MAPPING (
ENROLMENT_ID NUMBER(19) NOT NULL, ENROLMENT_ID NUMBER(10) NOT NULL,
TAG_ID NUMBER(19) NOT NULL, TAG_ID NUMBER(10) NOT NULL,
TENANT_ID NUMBER(10) NOT NULL, TENANT_ID NUMBER(10) NOT NULL,
PRIMARY KEY (ENROLMENT_ID, TAG_ID, TENANT_ID), PRIMARY KEY (ENROLMENT_ID, TAG_ID, TENANT_ID),
FOREIGN KEY (ENROLMENT_ID) REFERENCES DM_ENROLMENT(ID), FOREIGN KEY (ENROLMENT_ID) REFERENCES DM_ENROLMENT(ID),

@ -884,7 +884,7 @@ CREATE TABLE IF NOT EXISTS DM_CEA_POLICIES (
-- DM_TAG TABLE -- -- DM_TAG TABLE --
CREATE TABLE IF NOT EXISTS DM_TAG ( CREATE TABLE IF NOT EXISTS DM_TAG (
ID BIGSERIAL PRIMARY KEY, ID INTEGER PRIMARY KEY,
NAME VARCHAR(255) NOT NULL, NAME VARCHAR(255) NOT NULL,
DESCRIPTION VARCHAR(255) NULL, DESCRIPTION VARCHAR(255) NULL,
TENANT_ID INTEGER NOT NULL, TENANT_ID INTEGER NOT NULL,
@ -894,8 +894,8 @@ CREATE TABLE IF NOT EXISTS DM_TAG (
-- DM_DEVICE_TAG_MAPPING TABLE -- -- DM_DEVICE_TAG_MAPPING TABLE --
CREATE TABLE IF NOT EXISTS DM_DEVICE_TAG_MAPPING ( CREATE TABLE IF NOT EXISTS DM_DEVICE_TAG_MAPPING (
ENROLMENT_ID BIGINT NOT NULL, ENROLMENT_ID INTEGER NOT NULL,
TAG_ID BIGINT NOT NULL, TAG_ID INTEGER NOT NULL,
TENANT_ID INTEGER NOT NULL, TENANT_ID INTEGER NOT NULL,
PRIMARY KEY (ENROLMENT_ID, TAG_ID, TENANT_ID), PRIMARY KEY (ENROLMENT_ID, TAG_ID, TENANT_ID),
FOREIGN KEY (ENROLMENT_ID) REFERENCES DM_ENROLMENT(ID), FOREIGN KEY (ENROLMENT_ID) REFERENCES DM_ENROLMENT(ID),

Loading…
Cancel
Save