updated from master and fixed conf copying issue

This commit is contained in:
Amalka Subasinghe 2021-05-24 16:40:05 +05:30
commit 83b31f0d02
71 changed files with 1401 additions and 437 deletions

View File

@ -24,7 +24,7 @@ import java.sql.Timestamp;
public class DeviceSubscriptionData { public class DeviceSubscriptionData {
private String action; private String action;
private Timestamp actionTriggeredTimestamp; private long actionTriggeredTimestamp;
private String actionTriggeredBy; private String actionTriggeredBy;
private String actionType; private String actionType;
private String status; private String status;
@ -38,11 +38,11 @@ public class DeviceSubscriptionData {
this.action = action; this.action = action;
} }
public Timestamp getActionTriggeredTimestamp() { public long getActionTriggeredTimestamp() {
return actionTriggeredTimestamp; return actionTriggeredTimestamp;
} }
public void setActionTriggeredTimestamp(Timestamp actionTriggeredTimestamp) { public void setActionTriggeredTimestamp(long actionTriggeredTimestamp) {
this.actionTriggeredTimestamp = actionTriggeredTimestamp; this.actionTriggeredTimestamp = actionTriggeredTimestamp;
} }

View File

@ -69,7 +69,7 @@ public class ScheduledSubscriptionDTO {
/** /**
* Scheduled time of subscription. * Scheduled time of subscription.
*/ */
private LocalDateTime scheduledAt; private long scheduledAt;
/** /**
* Username of the scheduler. * Username of the scheduler.
@ -86,7 +86,7 @@ public class ScheduledSubscriptionDTO {
} }
public ScheduledSubscriptionDTO(String taskName, String applicationUUID, LocalDateTime scheduledAt, public ScheduledSubscriptionDTO(String taskName, String applicationUUID, long scheduledAt,
List<?> subscriberList, String scheduledBy) { List<?> subscriberList, String scheduledBy) {
this.taskName = taskName; this.taskName = taskName;
this.applicationUUID = applicationUUID; this.applicationUUID = applicationUUID;
@ -135,11 +135,11 @@ public class ScheduledSubscriptionDTO {
this.status = status; this.status = status;
} }
public LocalDateTime getScheduledAt() { public long getScheduledAt() {
return scheduledAt; return scheduledAt;
} }
public void setScheduledAt(LocalDateTime scheduledAt) { public void setScheduledAt(long scheduledAt) {
this.scheduledAt = scheduledAt; this.scheduledAt = scheduledAt;
} }

View File

@ -22,6 +22,7 @@ import org.wso2.carbon.device.application.mgt.common.dto.ScheduledSubscriptionDT
import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException;
import org.wso2.carbon.device.application.mgt.common.exception.SubscriptionManagementException; import org.wso2.carbon.device.application.mgt.common.exception.SubscriptionManagementException;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.PaginationRequest;
import org.wso2.carbon.device.mgt.common.PaginationResult; import org.wso2.carbon.device.mgt.common.PaginationResult;
import java.util.List; import java.util.List;
@ -127,14 +128,11 @@ public interface SubscriptionManager {
* This method used to get the app id ,device ids and pass them to DM service method. * This method used to get the app id ,device ids and pass them to DM service method.
* *
* @param appUUID UUID of the application release. * @param appUUID UUID of the application release.
* @param offsetValue offset value for get paginated request. * @param request paginated request object.
* @param limitValue limit value for get paginated request.
* @param status status of the devices.
* @return deviceDetails - device details for given application release. * @return deviceDetails - device details for given application release.
* @throws {@link ApplicationManagementException} Exception of the application management * @throws {@link ApplicationManagementException} Exception of the application management
*/ */
PaginationResult getAppInstalledDevices(int offsetValue, int limitValue, String appUUID, PaginationResult getAppInstalledDevices(PaginationRequest request, String appUUID) throws ApplicationManagementException;
List<String> status) throws ApplicationManagementException;
/*** /***
* This method used to get category details. * This method used to get category details.
@ -152,14 +150,15 @@ public interface SubscriptionManager {
/** /**
* 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.
* *
* @param offsetValue offset * @param request paginated request object.
* @param limitValue limit * @param actionStatus status of the operation.
* @param action action related to the device.
* @param appUUID application release UUID * @param appUUID application release UUID
* @return {@link PaginationResult} * @return {@link PaginationResult}
* @throws ApplicationManagementException if offset or limit contains incorrect values, if it couldn't find an * @throws ApplicationManagementException if offset or limit contains incorrect values, if it couldn't find an
* application release for given UUID, if an error occurred while getting device details of subscribed device ids, * application release for given UUID, if an error occurred while getting device details of subscribed device ids,
* if an error occurred while getting subscription details of given application release UUID. * if an error occurred while getting subscription details of given application release UUID.
*/ */
PaginationResult getAppSubscriptionDetails(int offsetValue, int limitValue, String appUUID) PaginationResult getAppSubscriptionDetails(PaginationRequest request, String appUUID, String actionStatus, String action)
throws ApplicationManagementException; throws ApplicationManagementException;
} }

View File

@ -81,7 +81,7 @@ public interface SubscriptionDAO {
void addGroupSubscriptions(int tenantId, String subscribedBy, List<String> groups, int releaseId, String action) void addGroupSubscriptions(int tenantId, String subscribedBy, List<String> groups, int releaseId, String action)
throws ApplicationManagementDAOException; throws ApplicationManagementDAOException;
List<DeviceSubscriptionDTO> getDeviceSubscriptions(int appReleaseId, int tenantId) throws List<DeviceSubscriptionDTO> getDeviceSubscriptions(int appReleaseId, int tenantId, String actionStatus, String action) throws
ApplicationManagementDAOException; ApplicationManagementDAOException;
Map<Integer, DeviceSubscriptionDTO> getDeviceSubscriptions(List<Integer> deviceIds, int appReleaseId, int tenantId) Map<Integer, DeviceSubscriptionDTO> getDeviceSubscriptions(List<Integer> deviceIds, int appReleaseId, int tenantId)
@ -124,7 +124,7 @@ public interface SubscriptionDAO {
* @param scheduledBy username of the user who scheduled the subscription * @param scheduledBy username of the user who scheduled the subscription
* @throws ApplicationManagementDAOException if error occurred while updating the entry * @throws ApplicationManagementDAOException if error occurred while updating the entry
*/ */
boolean updateScheduledSubscription(int id, LocalDateTime scheduledAt, String scheduledBy) boolean updateScheduledSubscription(int id, long scheduledAt, String scheduledBy)
throws ApplicationManagementDAOException; throws ApplicationManagementDAOException;
/** /**

View File

@ -134,7 +134,8 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
+ "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, " + "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, "
+ "AP_APP_RELEASE.RATING AS RELEASE_RATING, " + "AP_APP_RELEASE.RATING AS RELEASE_RATING, "
+ "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, " + "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, "
+ "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT " + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT, "
+ "NEW_AP_APP_LIFECYCLE_STATE.UPDATED_AT AS LATEST_UPDATE "
+ "FROM AP_APP " + "FROM AP_APP "
+ "INNER JOIN AP_APP_RELEASE ON " + "INNER JOIN AP_APP_RELEASE ON "
+ "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID " + "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID "
@ -181,7 +182,17 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
if (filter.getLimit() != -1) { if (filter.getLimit() != -1) {
sql += "LIMIT ? OFFSET ? "; sql += "LIMIT ? OFFSET ? ";
} }
sql += ") AS app_data ON app_data.ID = AP_APP.ID WHERE AP_APP.TENANT_ID = ? ORDER BY AP_APP.ID"; sql += ") AS app_data ON app_data.ID = AP_APP.ID "
+ "INNER JOIN ("
+ "SELECT AP_APP_LIFECYCLE_STATE.UPDATED_AT, AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID "
+ "FROM AP_APP_LIFECYCLE_STATE WHERE AP_APP_LIFECYCLE_STATE.ID "
+ "IN(SELECT MAX(AP_APP_LIFECYCLE_STATE.ID) "
+ "FROM AP_APP_LIFECYCLE_STATE "
+ "GROUP BY AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID)) AS NEW_AP_APP_LIFECYCLE_STATE "
+ "ON AP_APP_RELEASE.ID = NEW_AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID "
+ "WHERE AP_APP.TENANT_ID = ? "
+ "ORDER BY AP_APP.ID, LATEST_UPDATE DESC";
try { try {
Connection conn = this.getDBConnection(); Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)) { try (PreparedStatement stmt = conn.prepareStatement(sql)) {

View File

@ -80,7 +80,8 @@ public class OracleApplicationDAOImpl extends GenericApplicationDAOImpl {
+ "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, " + "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, "
+ "AP_APP_RELEASE.RATING AS RELEASE_RATING, " + "AP_APP_RELEASE.RATING AS RELEASE_RATING, "
+ "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, " + "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, "
+ "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT " + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT, "
+ "NEW_AP_APP_LIFECYCLE_STATE.UPDATED_AT AS LATEST_UPDATE "
+ "FROM AP_APP " + "FROM AP_APP "
+ "INNER JOIN AP_APP_RELEASE ON " + "INNER JOIN AP_APP_RELEASE ON "
+ "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID " + "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID "
@ -125,7 +126,17 @@ public class OracleApplicationDAOImpl extends GenericApplicationDAOImpl {
if (filter.getLimit() != -1) { if (filter.getLimit() != -1) {
sql += "OFFSET ? ROWS FETCH NEXT ? ROWS ONLY "; sql += "OFFSET ? ROWS FETCH NEXT ? ROWS ONLY ";
} }
sql += ") AS app_data ON app_data.ID = AP_APP.ID WHERE AP_APP.TENANT_ID = ? ORDER BY AP_APP.ID"; sql += ") AS app_data ON app_data.ID = AP_APP.ID "
+ "INNER JOIN ("
+ "SELECT AP_APP_LIFECYCLE_STATE.UPDATED_AT, AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID "
+ "FROM AP_APP_LIFECYCLE_STATE WHERE AP_APP_LIFECYCLE_STATE.ID "
+ "IN(SELECT MAX(AP_APP_LIFECYCLE_STATE.ID) "
+ "FROM AP_APP_LIFECYCLE_STATE "
+ "GROUP BY AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID)) AS NEW_AP_APP_LIFECYCLE_STATE "
+ "ON AP_APP_RELEASE.ID = NEW_AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID "
+ "WHERE AP_APP.TENANT_ID = ? "
+ "ORDER BY AP_APP.ID, LATEST_UPDATE DESC";
try { try {
Connection conn = this.getDBConnection(); Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)) { try (PreparedStatement stmt = conn.prepareStatement(sql)) {

View File

@ -79,7 +79,8 @@ public class SQLServerApplicationDAOImpl extends GenericApplicationDAOImpl {
+ "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, " + "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, "
+ "AP_APP_RELEASE.RATING AS RELEASE_RATING, " + "AP_APP_RELEASE.RATING AS RELEASE_RATING, "
+ "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, " + "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, "
+ "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT " + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT, "
+ "NEW_AP_APP_LIFECYCLE_STATE.UPDATED_AT AS LATEST_UPDATE "
+ "FROM AP_APP " + "FROM AP_APP "
+ "INNER JOIN AP_APP_RELEASE ON " + "INNER JOIN AP_APP_RELEASE ON "
+ "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID " + "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID "
@ -124,7 +125,17 @@ public class SQLServerApplicationDAOImpl extends GenericApplicationDAOImpl {
if (filter.getLimit() != -1) { if (filter.getLimit() != -1) {
sql += "ORDER BY ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY "; sql += "ORDER BY ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY ";
} }
sql += ") AS app_data ON app_data.ID = AP_APP.ID WHERE AP_APP.TENANT_ID = ? ORDER BY AP_APP.ID"; sql += ") AS app_data ON app_data.ID = AP_APP.ID "
+ "INNER JOIN ("
+ "SELECT AP_APP_LIFECYCLE_STATE.UPDATED_AT, AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID "
+ "FROM AP_APP_LIFECYCLE_STATE WHERE AP_APP_LIFECYCLE_STATE.ID "
+ "IN(SELECT MAX(AP_APP_LIFECYCLE_STATE.ID) "
+ "FROM AP_APP_LIFECYCLE_STATE "
+ "GROUP BY AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID)) AS NEW_AP_APP_LIFECYCLE_STATE "
+ "ON AP_APP_RELEASE.ID = NEW_AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID "
+ "WHERE AP_APP.TENANT_ID = ? "
+ "ORDER BY AP_APP.ID, LATEST_UPDATE DESC";
try { try {
Connection conn = this.getDBConnection(); Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)) { try (PreparedStatement stmt = conn.prepareStatement(sql)) {

View File

@ -332,12 +332,15 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
} }
@Override @Override
public List<DeviceSubscriptionDTO> getDeviceSubscriptions(int appReleaseId, int tenantId) throws public List<DeviceSubscriptionDTO> getDeviceSubscriptions(int appReleaseId, int tenantId, String actionStatus, String action) throws
ApplicationManagementDAOException { ApplicationManagementDAOException {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Getting device subscriptions for the application release id " + appReleaseId log.debug("Getting device subscriptions for the application release id " + appReleaseId
+ " from the database"); + " from the database");
} }
boolean isActionStatusProvided = false;
boolean isActionProvided = false;
int index = 1;
String sql = "SELECT " String sql = "SELECT "
+ "DS.ID AS ID, " + "DS.ID AS ID, "
+ "DS.SUBSCRIBED_BY AS SUBSCRIBED_BY, " + "DS.SUBSCRIBED_BY AS SUBSCRIBED_BY, "
@ -350,11 +353,30 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
+ "DS.DM_DEVICE_ID AS DEVICE_ID " + "DS.DM_DEVICE_ID AS DEVICE_ID "
+ "FROM AP_DEVICE_SUBSCRIPTION DS " + "FROM AP_DEVICE_SUBSCRIPTION DS "
+ "WHERE DS.AP_APP_RELEASE_ID = ? AND DS.TENANT_ID=?"; + "WHERE DS.AP_APP_RELEASE_ID = ? AND DS.TENANT_ID=?";
if (actionStatus != null && !actionStatus.isEmpty()) {
sql += " AND DS.STATUS= ?";
isActionStatusProvided = true;
}
if (action != null && !action.isEmpty()) {
sql += " AND DS.UNSUBSCRIBED= ?";
isActionProvided = true;
}
try { try {
Connection conn = this.getDBConnection(); Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)) { try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setInt(1, appReleaseId); stmt.setInt(index++, appReleaseId);
stmt.setInt(2, tenantId); stmt.setInt(index++, tenantId);
if (isActionStatusProvided) {
stmt.setString(index++, actionStatus);
}
if (isActionProvided) {
if (action.equals("SUBSCRIBED")) {
stmt.setString(index, "FALSE");
} else {
stmt.setString(index, "TRUE");
}
}
try (ResultSet rs = stmt.executeQuery()) { try (ResultSet rs = stmt.executeQuery()) {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Successfully retrieved device subscriptions for application release id " log.debug("Successfully retrieved device subscriptions for application release id "
@ -765,7 +787,7 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
stmt.setString(2, subscriptionDTO.getApplicationUUID()); stmt.setString(2, subscriptionDTO.getApplicationUUID());
stmt.setString(3, subscriptionDTO.getSubscribersString()); stmt.setString(3, subscriptionDTO.getSubscribersString());
stmt.setString(4, ExecutionStatus.PENDING.toString()); stmt.setString(4, ExecutionStatus.PENDING.toString());
stmt.setTimestamp(5, Timestamp.valueOf(subscriptionDTO.getScheduledAt())); stmt.setLong(5, subscriptionDTO.getScheduledAt());
stmt.setTimestamp(6, new Timestamp(calendar.getTime().getTime())); stmt.setTimestamp(6, new Timestamp(calendar.getTime().getTime()));
stmt.setString(7, subscriptionDTO.getScheduledBy()); stmt.setString(7, subscriptionDTO.getScheduledBy());
stmt.setBoolean(8, false); stmt.setBoolean(8, false);
@ -785,7 +807,7 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
} }
@Override @Override
public boolean updateScheduledSubscription(int id, LocalDateTime scheduledAt, String scheduledBy) public boolean updateScheduledSubscription(int id, long scheduledAt, String scheduledBy)
throws ApplicationManagementDAOException { throws ApplicationManagementDAOException {
String sql = "UPDATE AP_SCHEDULED_SUBSCRIPTION " String sql = "UPDATE AP_SCHEDULED_SUBSCRIPTION "
+ "SET " + "SET "
@ -797,7 +819,7 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
Connection conn = this.getDBConnection(); Connection conn = this.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)) { try (PreparedStatement stmt = conn.prepareStatement(sql)) {
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
stmt.setTimestamp(1, Timestamp.valueOf(scheduledAt)); stmt.setLong(1, scheduledAt);
stmt.setString(2, scheduledBy); stmt.setString(2, scheduledBy);
stmt.setTimestamp(3, new Timestamp(calendar.getTime().getTime())); stmt.setTimestamp(3, new Timestamp(calendar.getTime().getTime()));
stmt.setInt(4, id); stmt.setInt(4, id);
@ -1037,7 +1059,7 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
try (PreparedStatement stmt = conn.prepareStatement(sql)) { try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, ExecutionStatus.PENDING.toString()); stmt.setString(1, ExecutionStatus.PENDING.toString());
stmt.setBoolean(2, false); stmt.setBoolean(2, false);
stmt.setTimestamp(3, new Timestamp(Calendar.getInstance().getTime().getTime())); stmt.setLong(3, Calendar.getInstance().getTime().getTime() / 1000);
try (ResultSet rs = stmt.executeQuery()) { try (ResultSet rs = stmt.executeQuery()) {
return DAOUtil.loadScheduledSubscriptions(rs); return DAOUtil.loadScheduledSubscriptions(rs);
} }

View File

@ -1445,7 +1445,7 @@ ApplicationManagerImpl implements ApplicationManager {
log.error(msg); log.error(msg);
throw new ForbiddenException(msg); throw new ForbiddenException(msg);
} }
if (!subscriptionDAO.getDeviceSubscriptions(applicationReleaseDTO.getId(), tenantId).isEmpty()) { if (!subscriptionDAO.getDeviceSubscriptions(applicationReleaseDTO.getId(), tenantId, null, null).isEmpty()) {
String msg = "Application release which has UUID: " + applicationReleaseDTO.getUuid() String msg = "Application release which has UUID: " + applicationReleaseDTO.getUuid()
+ " either subscribed to device/s or it had subscribed to device/s. Therefore you are not " + " either subscribed to device/s or it had subscribed to device/s. Therefore you are not "
+ "permitted to delete the application release."; + "permitted to delete the application release.";
@ -1580,7 +1580,7 @@ ApplicationManagerImpl implements ApplicationManager {
try { try {
ConnectionManagerUtil.beginDBTransaction(); ConnectionManagerUtil.beginDBTransaction();
List<DeviceSubscriptionDTO> deviceSubscriptionDTOS = subscriptionDAO List<DeviceSubscriptionDTO> deviceSubscriptionDTOS = subscriptionDAO
.getDeviceSubscriptions(applicationReleaseDTO.getId(), tenantId); .getDeviceSubscriptions(applicationReleaseDTO.getId(), tenantId, null, null);
if (!deviceSubscriptionDTOS.isEmpty()) { if (!deviceSubscriptionDTOS.isEmpty()) {
String msg = "Application release which has UUID: " + applicationReleaseDTO.getUuid() String msg = "Application release which has UUID: " + applicationReleaseDTO.getUuid()
+ " either subscribed to device/s or it had subscribed to device/s. Therefore you " + " either subscribed to device/s or it had subscribed to device/s. Therefore you "

View File

@ -65,10 +65,7 @@ import org.wso2.carbon.device.application.mgt.core.util.ConnectionManagerUtil;
import org.wso2.carbon.device.application.mgt.core.util.Constants; import org.wso2.carbon.device.application.mgt.core.util.Constants;
import org.wso2.carbon.device.application.mgt.core.util.HelperUtil; import org.wso2.carbon.device.application.mgt.core.util.HelperUtil;
import org.wso2.carbon.device.application.mgt.core.util.OAuthUtils; import org.wso2.carbon.device.application.mgt.core.util.OAuthUtils;
import org.wso2.carbon.device.mgt.common.Device; import org.wso2.carbon.device.mgt.common.*;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.MDMAppConstants;
import org.wso2.carbon.device.mgt.common.app.mgt.App; import org.wso2.carbon.device.mgt.common.app.mgt.App;
import org.wso2.carbon.device.mgt.common.app.mgt.MobileAppTypes; import org.wso2.carbon.device.mgt.common.app.mgt.MobileAppTypes;
import org.wso2.carbon.device.mgt.common.app.mgt.android.CustomApplication; import org.wso2.carbon.device.mgt.common.app.mgt.android.CustomApplication;
@ -88,7 +85,6 @@ import org.wso2.carbon.device.mgt.core.util.MDMIOSOperationUtil;
import org.wso2.carbon.device.mgt.core.util.MDMWindowsOperationUtil; import org.wso2.carbon.device.mgt.core.util.MDMWindowsOperationUtil;
import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo; import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.device.mgt.common.PaginationResult;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import java.io.BufferedReader; import java.io.BufferedReader;
@ -381,7 +377,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
if (applicationDTO != null) { if (applicationDTO != null) {
List<DeviceSubscriptionDTO> deviceSubscriptionDTOS = this.subscriptionDAO List<DeviceSubscriptionDTO> deviceSubscriptionDTOS = this.subscriptionDAO
.getDeviceSubscriptions(applicationDTO.getApplicationReleaseDTOs().get(0).getId(), .getDeviceSubscriptions(applicationDTO.getApplicationReleaseDTOs().get(0).getId(),
tenantId); tenantId, null, null);
AtomicBoolean isAppSubscribable = new AtomicBoolean(true); AtomicBoolean isAppSubscribable = new AtomicBoolean(true);
for (DeviceSubscriptionDTO deviceSubscriptionDTO : deviceSubscriptionDTOS) { for (DeviceSubscriptionDTO deviceSubscriptionDTO : deviceSubscriptionDTOS) {
@ -1223,7 +1219,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
} }
@Override @Override
public PaginationResult getAppInstalledDevices(int offsetValue, int limitValue, String appUUID, List<String> status) public PaginationResult getAppInstalledDevices(PaginationRequest request, String appUUID)
throws ApplicationManagementException { throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
DeviceManagementProviderService deviceManagementProviderService = HelperUtil DeviceManagementProviderService deviceManagementProviderService = HelperUtil
@ -1235,7 +1231,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
int applicationReleaseId = applicationDTO.getApplicationReleaseDTOs().get(0).getId(); int applicationReleaseId = applicationDTO.getApplicationReleaseDTOs().get(0).getId();
List<DeviceSubscriptionDTO> deviceSubscriptionDTOS = subscriptionDAO List<DeviceSubscriptionDTO> deviceSubscriptionDTOS = subscriptionDAO
.getDeviceSubscriptions(applicationReleaseId, tenantId); .getDeviceSubscriptions(applicationReleaseId, tenantId, null, null);
if (deviceSubscriptionDTOS.isEmpty()) { if (deviceSubscriptionDTOS.isEmpty()) {
PaginationResult paginationResult = new PaginationResult(); PaginationResult paginationResult = new PaginationResult();
paginationResult.setData(new ArrayList<>()); paginationResult.setData(new ArrayList<>());
@ -1262,8 +1258,8 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
} }
//pass the device id list to device manager service method //pass the device id list to device manager service method
try { try {
PaginationResult deviceDetails = deviceManagementProviderService PaginationResult deviceDetails = deviceManagementProviderService.getAppSubscribedDevices
.getAppSubscribedDevices(offsetValue, limitValue, deviceIdList, status); (request, deviceIdList);
if (deviceDetails == null) { if (deviceDetails == null) {
String msg = "Couldn't found an subscribed devices details for device ids: " + deviceIdList; String msg = "Couldn't found an subscribed devices details for device ids: " + deviceIdList;
@ -1342,8 +1338,10 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
} }
@Override @Override
public PaginationResult getAppSubscriptionDetails(int offsetValue, int limitValue, String appUUID) public PaginationResult getAppSubscriptionDetails(PaginationRequest request, String appUUID, String actionStatus,
throws ApplicationManagementException { String action) throws ApplicationManagementException {
int limitValue = request.getRowCount();
int offsetValue = request.getStartIndex();
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
DeviceManagementProviderService deviceManagementProviderService = HelperUtil DeviceManagementProviderService deviceManagementProviderService = HelperUtil
.getDeviceManagementProviderService(); .getDeviceManagementProviderService();
@ -1365,7 +1363,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
int applicationReleaseId = applicationDTO.getApplicationReleaseDTOs().get(0).getId(); int applicationReleaseId = applicationDTO.getApplicationReleaseDTOs().get(0).getId();
List<DeviceSubscriptionDTO> deviceSubscriptionDTOS = subscriptionDAO List<DeviceSubscriptionDTO> deviceSubscriptionDTOS = subscriptionDAO
.getDeviceSubscriptions(applicationReleaseId, tenantId); .getDeviceSubscriptions(applicationReleaseId, tenantId, actionStatus, action);
if (deviceSubscriptionDTOS.isEmpty()) { if (deviceSubscriptionDTOS.isEmpty()) {
PaginationResult paginationResult = new PaginationResult(); PaginationResult paginationResult = new PaginationResult();
paginationResult.setData(new ArrayList<>()); paginationResult.setData(new ArrayList<>());
@ -1377,8 +1375,8 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
.collect(Collectors.toList()); .collect(Collectors.toList());
try { try {
//pass the device id list to device manager service method //pass the device id list to device manager service method
PaginationResult paginationResult = deviceManagementProviderService PaginationResult paginationResult = deviceManagementProviderService.getAppSubscribedDevices
.getAppSubscribedDevices(offsetValue, limitValue, deviceIdList, null); (request, deviceIdList);
List<DeviceSubscriptionData> deviceSubscriptionDataList = new ArrayList<>(); List<DeviceSubscriptionData> deviceSubscriptionDataList = new ArrayList<>();
if (!paginationResult.getData().isEmpty()) { if (!paginationResult.getData().isEmpty()) {
@ -1392,12 +1390,12 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
deviceSubscriptionData.setAction(Constants.UNSUBSCRIBED); deviceSubscriptionData.setAction(Constants.UNSUBSCRIBED);
deviceSubscriptionData.setActionTriggeredBy(subscription.getUnsubscribedBy()); deviceSubscriptionData.setActionTriggeredBy(subscription.getUnsubscribedBy());
deviceSubscriptionData deviceSubscriptionData
.setActionTriggeredTimestamp(subscription.getUnsubscribedTimestamp()); .setActionTriggeredTimestamp(subscription.getUnsubscribedTimestamp().getTime() / 1000);
} else { } else {
deviceSubscriptionData.setAction(Constants.SUBSCRIBED); deviceSubscriptionData.setAction(Constants.SUBSCRIBED);
deviceSubscriptionData.setActionTriggeredBy(subscription.getSubscribedBy()); deviceSubscriptionData.setActionTriggeredBy(subscription.getSubscribedBy());
deviceSubscriptionData deviceSubscriptionData
.setActionTriggeredTimestamp(subscription.getSubscribedTimestamp()); .setActionTriggeredTimestamp(subscription.getSubscribedTimestamp().getTime() / 1000);
} }
deviceSubscriptionData.setActionType(subscription.getActionTriggeredFrom()); deviceSubscriptionData.setActionType(subscription.getActionTriggeredFrom());
deviceSubscriptionData.setStatus(subscription.getStatus()); deviceSubscriptionData.setStatus(subscription.getStatus());

View File

@ -40,7 +40,7 @@ public class ScheduledAppSubscriptionCleanupTask extends RandomlyAssignedSchedul
@Override @Override
public void executeRandomlyAssignedTask() { public void executeRandomlyAssignedTask() {
try { try {
if(super.isQualifiedToExecuteTask()) { if(isQualifiedToExecuteTask()) {
subscriptionManager.cleanScheduledSubscriptions(); subscriptionManager.cleanScheduledSubscriptions();
} }
} catch (SubscriptionManagementException e) { } catch (SubscriptionManagementException e) {

View File

@ -68,7 +68,7 @@ public class ScheduledAppSubscriptionTask extends RandomlyAssignedScheduleTask {
@Override @Override
public void executeRandomlyAssignedTask() { public void executeRandomlyAssignedTask() {
if(super.isQualifiedToExecuteTask()) { if(isQualifiedToExecuteTask()) {
try { try {
ScheduledSubscriptionDTO subscriptionDTO = subscriptionManager.getPendingScheduledSubscription( ScheduledSubscriptionDTO subscriptionDTO = subscriptionManager.getPendingScheduledSubscription(
this.taskName); this.taskName);

View File

@ -40,6 +40,8 @@ import org.wso2.carbon.ntask.core.service.TaskService;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.TextStyle; import java.time.format.TextStyle;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -64,24 +66,27 @@ public class ScheduledAppSubscriptionTaskManager {
* either {@link org.wso2.carbon.device.mgt.common.DeviceIdentifier} if {@param subType} is * either {@link org.wso2.carbon.device.mgt.common.DeviceIdentifier} if {@param subType} is
* equal to DEVICE or {@link String} if {@param subType} is USER, ROLE or GROUP * equal to DEVICE or {@link String} if {@param subType} is USER, ROLE or GROUP
* @param subscriptionType subscription type. E.g. <code>DEVICE, USER, ROLE, GROUP</code> * @param subscriptionType subscription type. E.g. <code>DEVICE, USER, ROLE, GROUP</code>
* {@see {@link org.wso2.carbon.device.application.mgt.common.SubscriptionType}} * {@see {@link SubscriptionType}}
* @param action action subscription action. E.g. {@code INSTALL/UNINSTALL} * @param action action subscription action. E.g. {@code INSTALL/UNINSTALL}
* {@see {@link org.wso2.carbon.device.application.mgt.common.SubAction}} * {@see {@link SubAction}}
* @param timestamp timestamp to schedule the application subscription * @param timestamp timestamp to schedule the application subscription
* @throws ApplicationOperationTaskException if error occurred while scheduling the subscription * @throws ApplicationOperationTaskException if error occurred while scheduling the subscription
*/ */
public void scheduleAppSubscriptionTask(String applicationUUID, List<?> subscribers, public void scheduleAppSubscriptionTask(String applicationUUID, List<?> subscribers,
SubscriptionType subscriptionType, SubAction action, LocalDateTime timestamp) SubscriptionType subscriptionType, SubAction action, long timestamp)
throws ApplicationOperationTaskException { throws ApplicationOperationTaskException {
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date(timestamp * 1000));
String space = " "; String space = " ";
String cronExpression = String cronExpression =
String.valueOf(timestamp.getSecond()) + space + timestamp.getMinute() + space + timestamp.getHour() calendar.get(Calendar.SECOND) + space + calendar.get(Calendar.MINUTE) + space
+ space + timestamp.getDayOfMonth() + space + timestamp.getMonth().getDisplayName(TextStyle.SHORT, + calendar.get(Calendar.HOUR_OF_DAY) + space + calendar.get(Calendar.DAY_OF_MONTH) + space
Locale.getDefault()).toUpperCase() + " ? " + timestamp.getYear(); + calendar.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.getDefault()).toUpperCase() + " ? "
+ calendar.get(Calendar.YEAR);
if (!CronExpression.isValidExpression(cronExpression)) { if (!CronExpression.isValidExpression(cronExpression)) {
String msg = "The cron expression [" + cronExpression + "] generated by the" + " timestamp [" + timestamp String msg = "The cron expression [" + cronExpression + "] generated by the" + " timestamp [" + timestamp
.toString() + "] is invalid"; + "] is invalid";
log.error(msg); log.error(msg);
throw new ApplicationOperationTaskException(msg); throw new ApplicationOperationTaskException(msg);
} }

View File

@ -274,7 +274,7 @@ public class DAOUtil {
} }
subscription.setStatus(ExecutionStatus.valueOf(rs.getString("STATUS"))); subscription.setStatus(ExecutionStatus.valueOf(rs.getString("STATUS")));
subscription.setScheduledAt(rs.getTimestamp("SCHEDULED_AT").toLocalDateTime()); subscription.setScheduledAt(rs.getLong("SCHEDULED_AT"));
subscription.setScheduledBy(rs.getString("SCHEDULED_BY")); subscription.setScheduledBy(rs.getString("SCHEDULED_BY"));
subscription.setDeleted(rs.getBoolean("DELETED")); subscription.setDeleted(rs.getBoolean("DELETED"));
subscriptionDTOS.add(subscription); subscriptionDTOS.add(subscription);

View File

@ -32,6 +32,7 @@ import org.wso2.carbon.device.application.mgt.common.ErrorResponse;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import javax.validation.Valid; import javax.validation.Valid;
import javax.validation.constraints.Size;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.Produces; import javax.ws.rs.Produces;
@ -129,7 +130,7 @@ public interface SubscriptionManagementAPI {
name = "timestamp", name = "timestamp",
value = "Timestamp of scheduled install/uninstall operation" value = "Timestamp of scheduled install/uninstall operation"
) )
@QueryParam("timestamp") String timestamp @QueryParam("timestamp") long timestamp
); );
@POST @POST
@ -182,7 +183,7 @@ public interface SubscriptionManagementAPI {
name = "timestamp", name = "timestamp",
value = "Timestamp of scheduled install/uninstall operation" value = "Timestamp of scheduled install/uninstall operation"
) )
@QueryParam("timestamp") String timestamp @QueryParam("timestamp") long timestamp
); );
@POST @POST
@ -229,7 +230,7 @@ public interface SubscriptionManagementAPI {
name = "timestamp", name = "timestamp",
value = "Timestamp of scheduled ent. install operation" value = "Timestamp of scheduled ent. install operation"
) )
@QueryParam("timestamp") String timestamp, @QueryParam("timestamp") long timestamp,
@ApiParam( @ApiParam(
name = "requiresUpdatingExternal", name = "requiresUpdatingExternal",
value = "Should external system such as Google EMM APIs need to be updated." value = "Should external system such as Google EMM APIs need to be updated."
@ -287,7 +288,7 @@ public interface SubscriptionManagementAPI {
name = "timestamp", name = "timestamp",
value = "Timestamp of scheduled ent app install operation" value = "Timestamp of scheduled ent app install operation"
) )
@QueryParam("timestamp") String timestamp, @QueryParam("timestamp") long timestamp,
@ApiParam( @ApiParam(
name = "requiresUpdatingExternal", name = "requiresUpdatingExternal",
value = "Should external system such as Google EMM APIs need to be updated." value = "Should external system such as Google EMM APIs need to be updated."
@ -337,6 +338,28 @@ public interface SubscriptionManagementAPI {
response = ErrorResponse.class) response = ErrorResponse.class)
}) })
Response getAppInstalledDevices( Response getAppInstalledDevices(
@ApiParam(
name = "name",
value = "The device name. For example, Nexus devices can have names, suhc as shamu, bullhead or angler.",
required = false)
@Size(max = 45)
String name,
@ApiParam(
name = "user",
value = "The username of the owner of the device.",
required = false)
@QueryParam("user")
String user,
@ApiParam(
name = "ownership",
allowableValues = "BYOD, COPE",
value = "Provide the ownership status of the device. The following values can be assigned:\n" +
"- BYOD: Bring Your Own Device\n" +
"- COPE: Corporate-Owned, Personally-Enabled",
required = false)
@QueryParam("ownership")
@Size(max = 45)
String ownership,
@ApiParam( @ApiParam(
name="uuid", name="uuid",
value="uuid of the application release.", value="uuid of the application release.",

View File

@ -31,6 +31,7 @@ import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.apimgt.annotations.api.Scopes; import org.wso2.carbon.apimgt.annotations.api.Scopes;
import org.wso2.carbon.device.application.mgt.common.ErrorResponse; import org.wso2.carbon.device.application.mgt.common.ErrorResponse;
import javax.validation.constraints.Size;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.GET; import javax.ws.rs.GET;
import javax.ws.rs.Path; import javax.ws.rs.Path;
@ -111,6 +112,32 @@ public interface SubscriptionManagementAdminAPI {
response = ErrorResponse.class) response = ErrorResponse.class)
}) })
Response getAppInstalledDevices( Response getAppInstalledDevices(
@ApiParam(
name = "name",
value = "The device name. For example, Nexus devices can have names, suhc as shamu, bullhead or angler.",
required = false)
@Size(max = 45)
String name,
@ApiParam(
name = "user",
value = "The username of the owner of the device.",
required = false)
@QueryParam("user")
String user,
@ApiParam(
name = "action",
value = "The action, subscribed or unsubscribed.",
required = false)
@Size(max = 45)
@QueryParam("action") String action,
@ApiParam(
name = "actionStatus",
value = "Provide the action status details")
@QueryParam("actionStatus") String actionStatus,
@ApiParam(
name = "status",
value = "Provide the device status details, such as active or inactive.")
@QueryParam("status") List<String> status,
@ApiParam( @ApiParam(
name = "uuid", name = "uuid",
value = "uuid of the application release.", value = "uuid of the application release.",

View File

@ -33,6 +33,8 @@ import org.wso2.carbon.device.application.mgt.common.BasicUserInfo;
import org.wso2.carbon.device.application.mgt.common.BasicUserInfoList; import org.wso2.carbon.device.application.mgt.common.BasicUserInfoList;
import org.wso2.carbon.device.application.mgt.common.RoleList; import org.wso2.carbon.device.application.mgt.common.RoleList;
import org.wso2.carbon.device.application.mgt.common.DeviceGroupList; import org.wso2.carbon.device.application.mgt.common.DeviceGroupList;
import org.wso2.carbon.device.application.mgt.store.api.services.impl.util.RequestValidationUtil;
import org.wso2.carbon.device.mgt.common.PaginationRequest;
import org.wso2.carbon.device.mgt.common.PaginationResult; import org.wso2.carbon.device.mgt.common.PaginationResult;
import org.wso2.carbon.device.application.mgt.core.exception.BadRequestException; import org.wso2.carbon.device.application.mgt.core.exception.BadRequestException;
import org.wso2.carbon.device.application.mgt.core.exception.ForbiddenException; import org.wso2.carbon.device.application.mgt.core.exception.ForbiddenException;
@ -73,9 +75,9 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
@PathParam("uuid") String uuid, @PathParam("uuid") String uuid,
@PathParam("action") String action, @PathParam("action") String action,
@Valid List<DeviceIdentifier> deviceIdentifiers, @Valid List<DeviceIdentifier> deviceIdentifiers,
@QueryParam("timestamp") String timestamp) { @QueryParam("timestamp") long timestamp) {
try { try {
if (StringUtils.isEmpty(timestamp)) { if (0 == timestamp) {
SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager(); SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager();
ApplicationInstallResponse response = subscriptionManager ApplicationInstallResponse response = subscriptionManager
.performBulkAppOperation(uuid, deviceIdentifiers, SubscriptionType.DEVICE.toString(), action); .performBulkAppOperation(uuid, deviceIdentifiers, SubscriptionType.DEVICE.toString(), action);
@ -114,9 +116,9 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
@PathParam("subType") String subType, @PathParam("subType") String subType,
@PathParam("action") String action, @PathParam("action") String action,
@Valid List<String> subscribers, @Valid List<String> subscribers,
@QueryParam("timestamp") String timestamp) { @QueryParam("timestamp") long timestamp) {
try { try {
if (StringUtils.isEmpty(timestamp)) { if (0 == timestamp) {
SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager(); SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager();
ApplicationInstallResponse response = subscriptionManager ApplicationInstallResponse response = subscriptionManager
.performBulkAppOperation(uuid, subscribers, subType, action); .performBulkAppOperation(uuid, subscribers, subType, action);
@ -155,10 +157,10 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
@PathParam("uuid") String uuid, @PathParam("uuid") String uuid,
@PathParam("action") String action, @PathParam("action") String action,
@Valid List<DeviceIdentifier> deviceIdentifiers, @Valid List<DeviceIdentifier> deviceIdentifiers,
@QueryParam("timestamp") String timestamp, @QueryParam("timestamp") long timestamp,
@QueryParam("requiresUpdatingExternal") boolean requiresUpdatingExternal) { @QueryParam("requiresUpdatingExternal") boolean requiresUpdatingExternal) {
try { try {
if (StringUtils.isEmpty(timestamp)) { if (0 == timestamp) {
SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager(); SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager();
subscriptionManager subscriptionManager
.performEntAppSubscription(uuid, deviceIdentifiers, SubscriptionType.DEVICE.toString(), .performEntAppSubscription(uuid, deviceIdentifiers, SubscriptionType.DEVICE.toString(),
@ -202,10 +204,10 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
@PathParam("subType") String subType, @PathParam("subType") String subType,
@PathParam("action") String action, @PathParam("action") String action,
@Valid List<String> subscribers, @Valid List<String> subscribers,
@QueryParam("timestamp") String timestamp, @QueryParam("timestamp") long timestamp,
@QueryParam("requiresUpdatingExternal") boolean requiresUpdatingExternal) { @QueryParam("requiresUpdatingExternal") boolean requiresUpdatingExternal) {
try { try {
if (StringUtils.isEmpty(timestamp)) { if (0 == timestamp) {
SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager(); SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager();
subscriptionManager.performEntAppSubscription(uuid, subscribers, subType, action, requiresUpdatingExternal); subscriptionManager.performEntAppSubscription(uuid, subscribers, subType, action, requiresUpdatingExternal);
String msg = "Application release which has UUID " + uuid + " is installed to subscriber's valid device" String msg = "Application release which has UUID " + uuid + " is installed to subscriber's valid device"
@ -253,11 +255,11 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
* @return {@link Response} of the operation * @return {@link Response} of the operation
*/ */
private Response scheduleApplicationOperationTask(String applicationUUID, List<?> subscribers, private Response scheduleApplicationOperationTask(String applicationUUID, List<?> subscribers,
SubscriptionType subType, SubAction subAction, String timestamp) { SubscriptionType subType, SubAction subAction, long timestamp) {
try { try {
ScheduledAppSubscriptionTaskManager subscriptionTaskManager = new ScheduledAppSubscriptionTaskManager(); ScheduledAppSubscriptionTaskManager subscriptionTaskManager = new ScheduledAppSubscriptionTaskManager();
subscriptionTaskManager.scheduleAppSubscriptionTask(applicationUUID, subscribers, subType, subAction, subscriptionTaskManager.scheduleAppSubscriptionTask(applicationUUID, subscribers, subType, subAction,
LocalDateTime.parse(timestamp, DateTimeFormatter.ISO_LOCAL_DATE_TIME)); timestamp);
} catch (ApplicationOperationTaskException e) { } catch (ApplicationOperationTaskException e) {
String msg = "Error occurred while scheduling the application install operation"; String msg = "Error occurred while scheduling the application install operation";
log.error(msg, e); log.error(msg, e);
@ -273,6 +275,9 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
@Produces("application/json") @Produces("application/json")
@Path("/{uuid}/devices") @Path("/{uuid}/devices")
public Response getAppInstalledDevices( public Response getAppInstalledDevices(
@QueryParam("name") String name,
@QueryParam("user") String user,
@QueryParam("ownership") String ownership,
@PathParam("uuid") String uuid, @PathParam("uuid") String uuid,
@DefaultValue("0") @DefaultValue("0")
@QueryParam("offset") int offset, @QueryParam("offset") int offset,
@ -281,8 +286,31 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
@QueryParam("status") List<String> status) { @QueryParam("status") List<String> status) {
try { try {
SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager(); SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager();
PaginationResult subscribedDeviceDetails = subscriptionManager PaginationRequest request = new PaginationRequest(offset, limit);
.getAppInstalledDevices(offset, limit, uuid, status); if (name != null && !name.isEmpty()) {
request.setDeviceName(name);
}
if (user != null && !user.isEmpty()) {
request.setOwner(user);
}
if (ownership != null && !ownership.isEmpty()) {
RequestValidationUtil.validateOwnershipType(ownership);
request.setOwnership(ownership);
}
if (status != null && !status.isEmpty()) {
boolean isStatusEmpty = true;
for (String statusString : status) {
if (StringUtils.isNotBlank(statusString)) {
isStatusEmpty = false;
break;
}
}
if (!isStatusEmpty) {
RequestValidationUtil.validateStatus(status);
request.setStatusList(status);
}
}
PaginationResult subscribedDeviceDetails = subscriptionManager.getAppInstalledDevices(request, uuid);
DeviceList devices = new DeviceList(); DeviceList devices = new DeviceList();
devices.setList((List<Device>) subscribedDeviceDetails.getData()); devices.setList((List<Device>) subscribedDeviceDetails.getData());
devices.setCount(subscribedDeviceDetails.getRecordsTotal()); devices.setCount(subscribedDeviceDetails.getRecordsTotal());
@ -292,8 +320,7 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
log.error(msg, e); log.error(msg, e);
return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
} catch (BadRequestException e) { } catch (BadRequestException e) {
String msg = "Found invalid payload for getting application which has UUID: " + uuid String msg = "User requested details are not valid";
+ ". Hence verify the payload";
log.error(msg, e); log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
} catch (ForbiddenException e) { } catch (ForbiddenException e) {

View File

@ -18,6 +18,7 @@
package org.wso2.carbon.device.application.mgt.store.api.services.impl.admin; package org.wso2.carbon.device.application.mgt.store.api.services.impl.admin;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException; import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException;
@ -26,6 +27,8 @@ import org.wso2.carbon.device.application.mgt.core.exception.BadRequestException
import org.wso2.carbon.device.application.mgt.core.exception.NotFoundException; import org.wso2.carbon.device.application.mgt.core.exception.NotFoundException;
import org.wso2.carbon.device.application.mgt.core.util.APIUtil; import org.wso2.carbon.device.application.mgt.core.util.APIUtil;
import org.wso2.carbon.device.application.mgt.store.api.services.admin.SubscriptionManagementAdminAPI; import org.wso2.carbon.device.application.mgt.store.api.services.admin.SubscriptionManagementAdminAPI;
import org.wso2.carbon.device.application.mgt.store.api.services.impl.util.RequestValidationUtil;
import org.wso2.carbon.device.mgt.common.PaginationRequest;
import org.wso2.carbon.device.mgt.common.PaginationResult; import org.wso2.carbon.device.mgt.common.PaginationResult;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
@ -36,6 +39,7 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.Produces; import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam; import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.util.List;
/** /**
* Implementation of Subscription Management related APIs. * Implementation of Subscription Management related APIs.
@ -51,6 +55,11 @@ public class SubscriptionManagementAdminAPIImpl implements SubscriptionManagemen
@Produces("application/json") @Produces("application/json")
@Path("/{uuid}") @Path("/{uuid}")
public Response getAppInstalledDevices( public Response getAppInstalledDevices(
@QueryParam("name") String name,
@QueryParam("user") String user,
@QueryParam("action") String action,
@QueryParam("actionStatus") String actionStatus,
@QueryParam("status") List<String> status,
@PathParam("uuid") String uuid, @PathParam("uuid") String uuid,
@DefaultValue("0") @DefaultValue("0")
@QueryParam("offset") int offset, @QueryParam("offset") int offset,
@ -58,22 +67,49 @@ public class SubscriptionManagementAdminAPIImpl implements SubscriptionManagemen
@QueryParam("limit") int limit) { @QueryParam("limit") int limit) {
try { try {
PaginationRequest request = new PaginationRequest(offset, limit);
if (name != null && !name.isEmpty()) {
request.setDeviceName(name);
}
if (user != null && !user.isEmpty()) {
request.setOwner(user);
}
if (action != null && !action.isEmpty()) {
RequestValidationUtil.validateAction(action);
}
if (status != null && !status.isEmpty()) {
boolean isStatusEmpty = true;
for (String statusString : status) {
if (StringUtils.isNotBlank(statusString)) {
isStatusEmpty = false;
break;
}
}
if (!isStatusEmpty) {
RequestValidationUtil.validateStatus(status);
request.setStatusList(status);
}
}
if (actionStatus != null && !actionStatus.isEmpty()) {
if (StringUtils.isNotBlank(actionStatus)) {
RequestValidationUtil.validateStatusFiltering(actionStatus);
}
}
SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager(); SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager();
PaginationResult subscriptionData = subscriptionManager PaginationResult subscriptionData = subscriptionManager.getAppSubscriptionDetails
.getAppSubscriptionDetails(offset, limit, uuid); (request, uuid, actionStatus, action);
return Response.status(Response.Status.OK).entity(subscriptionData).build(); return Response.status(Response.Status.OK).entity(subscriptionData).build();
} catch (NotFoundException e) { } catch (NotFoundException e) {
String msg = "Application with application release UUID: " + uuid + " is not found"; String msg = "Application with application release UUID: " + uuid + " is not found";
log.error(msg, e); log.error(msg, e);
return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
} catch (BadRequestException e) { } catch (BadRequestException e) {
String msg = "Found invalid payload for getting application which has UUID: " + uuid String msg = "User requested details are not valid";
+ ". Hence verify the payload";
log.error(msg, e); log.error(msg, e);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
} catch (ApplicationManagementException e) { } catch (ApplicationManagementException e) {
String msg = "Error occurred while getting app installed devices which has application release UUID of: " String msg = "Error occurred while getting app installed devices which has application release UUID of: "
+ uuid; + uuid;
log.error(msg, e); log.error(msg, e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} }

View File

@ -0,0 +1,116 @@
/*
* Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.device.application.mgt.store.api.services.impl.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.application.mgt.core.exception.BadRequestException;
import org.wso2.carbon.device.application.mgt.store.api.util.Constants;
import java.util.List;
public class RequestValidationUtil {
private static final Log log = LogFactory.getLog(RequestValidationUtil.class);
/**
* Checks if user requested status codes are valid.
*
* @param statusList status codes upon to filter operation logs using status
*/
public static void validateStatus(List<String> statusList) throws BadRequestException {
for (String status : statusList) {
switch (status) {
case "ACTIVE":
case "INACTIVE":
case "UNCLAIMED":
case "UNREACHABLE":
case "SUSPENDED":
case "DISENROLLMENT_REQUESTED":
case "REMOVED":
case "BLOCKED":
case "CREATED":
break;
default:
String msg = "Invalid enrollment status type: " + status + ". \nValid status types " +
"are ACTIVE | INACTIVE | UNCLAIMED | UNREACHABLE | SUSPENDED | " +
"DISENROLLMENT_REQUESTED | REMOVED | BLOCKED | CREATED";
log.error(msg);
throw new BadRequestException(msg);
}
}
}
/**
* Checks if user requested action is valid.
*
* @param action action upon to filter devices using action
*/
public static void validateAction(String action) throws BadRequestException {
if (action.equals("SUBSCRIBED") || action.equals("UNSUBSCRIBED")) {
} else {
String msg = "Invalid action type received.Valid action types are SUBSCRIBED | UNSUBSCRIBED";
log.error(msg);
throw new BadRequestException(msg);
}
}
/**
* Checks if user requested ownerships are valid.
*
* @param ownership ownerships upon to filter devices using ownership
*/
public static void validateOwnershipType(String ownership) throws BadRequestException {
switch (ownership) {
case "BYOD":
case "COPE":
case "WORK_PROFILE":
case "GOOGLE_ENTERPRISE":
case "COSU":
case "FULLY_MANAGED":
case "DEDICATED_DEVICE":
break;
default:
String msg = "Invalid ownership type received.Valid ownership types are BYOD | COPE | WORK_PROFILE |" +
"GOOGLE_ENTERPRISE | COSU | FULLY_MANAGED | DEDICATED_DEVICE";
log.error(msg);
throw new BadRequestException(msg);
}
}
/**
* Checks if user requested Action status codes are valid.
*
* @param status status codes upon to filter operation logs using status
*/
public static void validateStatusFiltering(String status) throws BadRequestException {
if (Constants.OperationStatus.COMPLETED.toUpperCase().equals(status)
|| Constants.OperationStatus.ERROR.toUpperCase().equals(status)
|| Constants.OperationStatus.NOTNOW.toUpperCase().equals(status)
|| Constants.OperationStatus.REPEATED.toUpperCase().equals(status)
|| Constants.OperationStatus.PENDING.toUpperCase().equals(status)
|| Constants.OperationStatus.IN_PROGRESS.toUpperCase().equals(status)) {
} else {
String msg = "Invalid status type: " + status + ". \nValid status types are COMPLETED | ERROR | " +
"IN_PROGRESS | NOTNOW | PENDING | REPEATED";
log.error(msg);
throw new BadRequestException(msg);
}
}
}

View File

@ -0,0 +1,101 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
*
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.application.mgt.store.api.util;
/**
* Holds the constants used by DeviceImpl Management Admin web application.
*/
public class Constants {
public static final String USER_CLAIM_EMAIL_ADDRESS = "http://wso2.org/claims/emailaddress";
public static final String USER_CLAIM_FIRST_NAME = "http://wso2.org/claims/givenname";
public static final String USER_CLAIM_LAST_NAME = "http://wso2.org/claims/lastname";
public static final String USER_CLAIM_CREATED = "http://wso2.org/claims/created";
public static final String USER_CLAIM_MODIFIED = "http://wso2.org/claims/modified";
public static final String USER_CLAIM_DEVICES = "http://wso2.org/claims/devices";
public static final String PRIMARY_USER_STORE = "PRIMARY";
public static final String DEFAULT_STREAM_VERSION = "1.0.0";
public static final String SCOPE = "scope";
public static final String JDBC_USERSTOREMANAGER = "org.wso2.carbon.user.core.jdbc.JDBCUserStoreManager";
public static final String DEFAULT_SIMPLE_DATE_FORMAT = "EEE, d MMM yyyy HH:mm:ss Z";
public static final int DEFAULT_PAGE_LIMIT = 50;
public static final String FORWARD_SLASH = "/";
public static final String ANDROID = "android";
public static final String ANDROID_POLICY_VALIDATOR = "io.entgra.proprietary.platform.android." +
"core.polcy.AndroidPolicyPayloadValidator";
public static final String IOS = "ios";
public static final String WINDOWS = "windows";
public final class OperationStatus {
private OperationStatus () { throw new AssertionError(); }
public static final String COMPLETED = "completed";
public static final String ERROR = "error";
public static final String IN_PROGRESS = "in_progress";
public static final String PENDING = "pending";
public static final String NOTNOW = "notnow";
public static final String REPEATED = "repeated";
}
public static final String DEVICES = "devices";
public static final String ATTRIBUTE_DISPLAY_NAME = "DisplayName";
public static final String ATTRIBUTE_DESCRIPTION = "Description";
public static final String EXTERNAL_DEVICE_CLAIM_DISPLAY_NAME = "Devices";
public static final String EXTERNAL_DEVICE_CLAIM_DESCRIPTION = "Device list";
public final class ErrorMessages {
private ErrorMessages () { throw new AssertionError(); }
public static final String STATUS_BAD_REQUEST_MESSAGE_DEFAULT = "Bad Request";
}
public final class DeviceConstants {
private DeviceConstants () { throw new AssertionError(); }
public static final String APPLICATION_JSON = "application/json";
public static final String HEADER_CONTENT_TYPE = "Content-Type";
}
public final class Permission {
private Permission() { throw new AssertionError(); }
public static final String ADMIN = "/permission/admin";
public static final String LOGIN = "/permission/admin/login";
public static final String DEVICE_MGT = "/permission/admin/device-mgt";
public static final String APP_MGT = "/permission/admin/app-mgt";
}
}

View File

@ -269,6 +269,12 @@ public interface DeviceManagementService {
@QueryParam("ownership") @QueryParam("ownership")
@Size(max = 45) @Size(max = 45)
String ownership, String ownership,
@ApiParam(
name = "serialNumber",
value = "The serial number of the device.",
required = false)
@QueryParam("serialNumber")
String serialNumber,
@ApiParam( @ApiParam(
name = "status", name = "status",
value = "Provide the device status details, such as active or inactive.", value = "Provide the device status details, such as active or inactive.",

View File

@ -172,6 +172,7 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
@QueryParam("userPattern") String userPattern, @QueryParam("userPattern") String userPattern,
@QueryParam("role") String role, @QueryParam("role") String role,
@QueryParam("ownership") String ownership, @QueryParam("ownership") String ownership,
@QueryParam("serialNumber") String serialNumber,
@QueryParam("status") List<String> status, @QueryParam("status") List<String> status,
@QueryParam("groupId") int groupId, @QueryParam("groupId") int groupId,
@QueryParam("since") String since, @QueryParam("since") String since,
@ -205,6 +206,9 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
RequestValidationUtil.validateOwnershipType(ownership); RequestValidationUtil.validateOwnershipType(ownership);
request.setOwnership(ownership); request.setOwnership(ownership);
} }
if (StringUtils.isNotBlank(serialNumber)) {
request.setSerialNumber(serialNumber);
}
if (status != null && !status.isEmpty()) { if (status != null && !status.isEmpty()) {
boolean isStatusEmpty = true; boolean isStatusEmpty = true;
for (String statusString : status){ for (String statusString : status){

View File

@ -175,7 +175,8 @@ public class DeviceManagementServiceImplTest {
.toReturn(this.deviceAccessAuthorizationService); .toReturn(this.deviceAccessAuthorizationService);
Response response = this.deviceManagementService Response response = this.deviceManagementService
.getDevices(TEST_DEVICE_NAME, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, .getDevices(TEST_DEVICE_NAME, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP,
DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); null, DEFAULT_STATUS_LIST, 1, null, null, false,
10, 5);
Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode()); Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode());
} }
@ -194,19 +195,23 @@ public class DeviceManagementServiceImplTest {
Response response = this.deviceManagementService Response response = this.deviceManagementService
.getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP,
DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); null, DEFAULT_STATUS_LIST, 1, null, null, false,
10, 5);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode());
response = this.deviceManagementService response = this.deviceManagementService
.getDevices(TEST_DEVICE_NAME, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, null, DEFAULT_OWNERSHIP, .getDevices(TEST_DEVICE_NAME, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, null, DEFAULT_OWNERSHIP,
DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); null, DEFAULT_STATUS_LIST, 1, null, null, false,
10, 5);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode());
response = this.deviceManagementService response = this.deviceManagementService
.getDevices(TEST_DEVICE_NAME, TEST_DEVICE_TYPE, null, null, null, DEFAULT_OWNERSHIP, .getDevices(TEST_DEVICE_NAME, TEST_DEVICE_TYPE, null, null, null, DEFAULT_OWNERSHIP,
DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); null, DEFAULT_STATUS_LIST, 1, null, null, false,
10, 5);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode());
response = this.deviceManagementService response = this.deviceManagementService
.getDevices(TEST_DEVICE_NAME, TEST_DEVICE_TYPE, null, null, null, DEFAULT_OWNERSHIP, .getDevices(TEST_DEVICE_NAME, TEST_DEVICE_TYPE, null, null, null, DEFAULT_OWNERSHIP,
DEFAULT_STATUS_LIST, 1, null, null, true, 10, 5); null, DEFAULT_STATUS_LIST, 1, null, null, true,
10, 5);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode());
} }
@ -319,7 +324,7 @@ public class DeviceManagementServiceImplTest {
.toReturn(this.deviceManagementProviderService); .toReturn(this.deviceManagementProviderService);
Mockito.when(deviceAccessAuthorizationService.isDeviceAdminUser()).thenReturn(true); Mockito.when(deviceAccessAuthorizationService.isDeviceAdminUser()).thenReturn(true);
deviceManagementService.getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, deviceManagementService.getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null,
DEFAULT_ROLE, DEFAULT_OWNERSHIP, DEFAULT_STATUS_LIST, 1, DEFAULT_ROLE, DEFAULT_OWNERSHIP, null, DEFAULT_STATUS_LIST, 1,
null, null, false, 10, 5); null, null, false, 10, 5);
} }
@ -339,11 +344,11 @@ public class DeviceManagementServiceImplTest {
Response response = this.deviceManagementService Response response = this.deviceManagementService
.getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP
, DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); , null, DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode());
response = this.deviceManagementService response = this.deviceManagementService
.getDevices(null, TEST_DEVICE_TYPE, null, DEFAULT_USERNAME, DEFAULT_ROLE, DEFAULT_OWNERSHIP .getDevices(null, TEST_DEVICE_TYPE, null, DEFAULT_USERNAME, DEFAULT_ROLE, DEFAULT_OWNERSHIP
, DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); , null, DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode());
} }
@ -365,7 +370,8 @@ public class DeviceManagementServiceImplTest {
Response response = this.deviceManagementService Response response = this.deviceManagementService
.getDevices(null, TEST_DEVICE_TYPE, "newuser", null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, .getDevices(null, TEST_DEVICE_TYPE, "newuser", null, DEFAULT_ROLE, DEFAULT_OWNERSHIP,
DEFAULT_STATUS_LIST, 0, null, null, false, 10, 5); null, DEFAULT_STATUS_LIST, 0, null, null, false,
10, 5);
Assert.assertEquals(response.getStatus(), Response.Status.UNAUTHORIZED.getStatusCode()); Assert.assertEquals(response.getStatus(), Response.Status.UNAUTHORIZED.getStatusCode());
Mockito.reset(this.deviceAccessAuthorizationService); Mockito.reset(this.deviceAccessAuthorizationService);
} }
@ -386,15 +392,18 @@ public class DeviceManagementServiceImplTest {
Response response = this.deviceManagementService Response response = this.deviceManagementService
.getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP,
DEFAULT_STATUS_LIST, 0, null, ifModifiedSince, false, 10, 5); null, DEFAULT_STATUS_LIST, 0, null, ifModifiedSince, false,
10, 5);
Assert.assertEquals(response.getStatus(), Response.Status.NOT_MODIFIED.getStatusCode()); Assert.assertEquals(response.getStatus(), Response.Status.NOT_MODIFIED.getStatusCode());
response = this.deviceManagementService response = this.deviceManagementService
.getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP,
DEFAULT_STATUS_LIST, 0, null, ifModifiedSince, true, 10, 5); null, DEFAULT_STATUS_LIST, 0, null, ifModifiedSince, true,
10, 5);
Assert.assertEquals(response.getStatus(), Response.Status.NOT_MODIFIED.getStatusCode()); Assert.assertEquals(response.getStatus(), Response.Status.NOT_MODIFIED.getStatusCode());
response = this.deviceManagementService response = this.deviceManagementService
.getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP,
DEFAULT_STATUS_LIST, 0, null, "ErrorModifiedSince", false, 10, 5); null, DEFAULT_STATUS_LIST, 0, null, "ErrorModifiedSince",
false, 10, 5);
Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode()); Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode());
} }
@ -414,15 +423,18 @@ public class DeviceManagementServiceImplTest {
Response response = this.deviceManagementService Response response = this.deviceManagementService
.getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP,
DEFAULT_STATUS_LIST, 0, since, null, false, 10, 5); null, DEFAULT_STATUS_LIST, 0, since, null, false,
10, 5);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode());
response = this.deviceManagementService response = this.deviceManagementService
.getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP,
DEFAULT_STATUS_LIST, 0, since, null, true, 10, 5); null, DEFAULT_STATUS_LIST, 0, since, null, true,
10, 5);
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode());
response = this.deviceManagementService response = this.deviceManagementService
.getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP,
DEFAULT_STATUS_LIST, 0, "ErrorSince", null, false, 10, 5); null, DEFAULT_STATUS_LIST, 0, "ErrorSince", null, false,
10, 5);
Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode()); Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode());
} }
@ -444,7 +456,8 @@ public class DeviceManagementServiceImplTest {
Response response = this.deviceManagementService Response response = this.deviceManagementService
.getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP,
DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); null, DEFAULT_STATUS_LIST, 1, null, null, false,
10, 5);
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
Mockito.reset(this.deviceManagementProviderService); Mockito.reset(this.deviceManagementProviderService);
} }
@ -466,7 +479,8 @@ public class DeviceManagementServiceImplTest {
Response response = this.deviceManagementService Response response = this.deviceManagementService
.getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP, .getDevices(null, TEST_DEVICE_TYPE, DEFAULT_USERNAME, null, DEFAULT_ROLE, DEFAULT_OWNERSHIP,
DEFAULT_STATUS_LIST, 1, null, null, false, 10, 5); null, DEFAULT_STATUS_LIST, 1, null, null, false,
10, 5);
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
Mockito.reset(this.deviceAccessAuthorizationService); Mockito.reset(this.deviceAccessAuthorizationService);
} }

View File

@ -40,6 +40,7 @@ public class PaginationRequest {
private String ownerRole; private String ownerRole;
private Date since; private Date since;
private String filter; private String filter;
private String serialNumber;
private Map<String, Object> property = new HashMap<>(); private Map<String, Object> property = new HashMap<>();
private List<String> statusList = new ArrayList<>(); private List<String> statusList = new ArrayList<>();
private OperationLogFilters operationLogFilters = new OperationLogFilters(); private OperationLogFilters operationLogFilters = new OperationLogFilters();
@ -153,6 +154,10 @@ public class PaginationRequest {
return this.property.get(key); return this.property.get(key);
} }
public String getSerialNumber() { return serialNumber; }
public void setSerialNumber(String serialNumber) { this.serialNumber = serialNumber; }
public Map<String, Object> getProperties() { public Map<String, Object> getProperties() {
Map<String, Object> temp = new HashMap<>(); Map<String, Object> temp = new HashMap<>();
temp.putAll(property); temp.putAll(property);

View File

@ -30,7 +30,7 @@ import java.util.List;
public class ActivityStatus { public class ActivityStatus {
public enum Status { public enum Status {
IN_PROGRESS, PENDING, COMPLETED, ERROR, REPEATED, INVALID, UNAUTHORIZED IN_PROGRESS, PENDING, COMPLETED, ERROR, REPEATED, INVALID, UNAUTHORIZED, NOTNOW
} }
@ApiModelProperty( @ApiModelProperty(

View File

@ -27,6 +27,7 @@ public class Item {
private String label; private String label;
private String tooltip; private String tooltip;
private String docLink;
private String key; private String key;
private String value; private String value;
private boolean isRequired; private boolean isRequired;
@ -65,6 +66,16 @@ public class Item {
this.tooltip = tooltip; this.tooltip = tooltip;
} }
@XmlElement(name = "DocLink")
public String getDocLink() {
return docLink;
}
public void setDocLink(String docLink) {
this.docLink = docLink;
}
@XmlElement(name = "Key", required = true) @XmlElement(name = "Key", required = true)
public String getKey() { public String getKey() {
return key; return key;

View File

@ -651,16 +651,14 @@ public interface DeviceDAO {
/** /**
* This method is used to get the details of subscribed devices. * This method is used to get the details of subscribed devices.
* *
* @param deviceIds device ids of the subscribed devices. * @param deviceIds device ids of the subscribed devices.
* @param tenantId Id of the current tenant. * @param tenantId Id of the current tenant.
* @param offsetValue offset value for get paginated request. * @param request paginated request object.
* @param limitValue limit value for get paginated request.
* @param status status of the devices.
* @return devices - subscribed device details list * @return devices - subscribed device details list
* @throws DeviceManagementDAOException if connections establishment fails. * @throws DeviceManagementDAOException if connections establishment fails.
*/ */
List<Device> getSubscribedDevices(int offsetValue, int limitValue, List<Integer> deviceIds, List<Device> getSubscribedDevices(PaginationRequest request, List<Integer> deviceIds, int tenantId)
int tenantId, List<String> status) throws DeviceManagementDAOException; throws DeviceManagementDAOException;
/** /**
* @param deviceIds device ids of the subscribed devices. * @param deviceIds device ids of the subscribed devices.

View File

@ -67,6 +67,9 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl {
boolean isStatusProvided = false; boolean isStatusProvided = false;
Date since = request.getSince(); Date since = request.getSince();
boolean isSinceProvided = false; boolean isSinceProvided = false;
String serial = request.getSerialNumber();
boolean isSerialProvided = false;
try { try {
Connection conn = getConnection(); Connection conn = getConnection();
@ -87,10 +90,19 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl {
"d.DESCRIPTION, " + "d.DESCRIPTION, " +
"d.NAME, " + "d.NAME, " +
"d.DEVICE_IDENTIFICATION, " + "d.DEVICE_IDENTIFICATION, " +
"t.NAME AS DEVICE_TYPE " + "t.NAME AS DEVICE_TYPE ";
"FROM DM_DEVICE d, DM_DEVICE_TYPE t ";
sql = sql + " WHERE DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ?"; if (serial != null) {
sql = sql + "FROM DM_DEVICE d, DM_DEVICE_TYPE t, DM_DEVICE_INFO i " +
"WHERE DEVICE_TYPE_ID = t.ID " +
"AND d.ID= i.DEVICE_ID " +
"AND i.KEY_FIELD = 'serial' " +
"AND i.VALUE_FIELD = ? " +
"AND d.TENANT_ID = ? ";
isSerialProvided = true;
} else {
sql = sql + "FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ? ";
}
//Add query for last updated timestamp //Add query for last updated timestamp
if (since != null) { if (since != null) {
sql = sql + " AND d.LAST_UPDATED_TIMESTAMP > ?"; sql = sql + " AND d.LAST_UPDATED_TIMESTAMP > ?";
@ -128,6 +140,9 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl {
try (PreparedStatement stmt = conn.prepareStatement(sql)) { try (PreparedStatement stmt = conn.prepareStatement(sql)) {
int paramIdx = 1; int paramIdx = 1;
if (isSerialProvided) {
stmt.setString(paramIdx++, serial);
}
stmt.setInt(paramIdx++, tenantId); stmt.setInt(paramIdx++, tenantId);
if (isSinceProvided) { if (isSinceProvided) {
stmt.setTimestamp(paramIdx++, new Timestamp(since.getTime())); stmt.setTimestamp(paramIdx++, new Timestamp(since.getTime()));
@ -877,11 +892,15 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl {
} }
@Override @Override
public List<Device> getSubscribedDevices(int offsetValue, int limitValue, public List<Device> getSubscribedDevices(PaginationRequest request, List<Integer> deviceIds, int tenantId)
List<Integer> deviceIds, int tenantId, List<String> status)
throws DeviceManagementDAOException { throws DeviceManagementDAOException {
Connection conn; Connection conn;
int limitValue = request.getRowCount();
int offsetValue = request.getStartIndex();
List<String> status = request.getStatusList();
String name = request.getDeviceName();
String user = request.getOwner();
String ownership = request.getOwnership();
try { try {
List<Device> devices = new ArrayList<>(); List<Device> devices = new ArrayList<>();
if (deviceIds.isEmpty()) { if (deviceIds.isEmpty()) {
@ -891,6 +910,10 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl {
int index = 1; int index = 1;
boolean isStatusProvided = false; boolean isStatusProvided = false;
boolean isDeviceNameProvided = false;
boolean isOwnerProvided = false;
boolean isOwnershipProvided = false;
StringJoiner joiner = new StringJoiner(",", StringJoiner joiner = new StringJoiner(",",
"SELECT " "SELECT "
+ "DM_DEVICE.ID AS DEVICE_ID, " + "DM_DEVICE.ID AS DEVICE_ID, "
@ -918,6 +941,18 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl {
deviceIds.stream().map(ignored -> "?").forEach(joiner::add); deviceIds.stream().map(ignored -> "?").forEach(joiner::add);
String query = joiner.toString(); String query = joiner.toString();
if (name != null && !name.isEmpty()) {
query += " AND DM_DEVICE.NAME LIKE ?";
isDeviceNameProvided = true;
}
if (ownership != null && !ownership.isEmpty()) {
query += " AND e.OWNERSHIP = ?";
isOwnershipProvided = true;
}
if (user != null && !user.isEmpty()) {
query += " AND e.OWNER = ?";
isOwnerProvided = true;
}
if (status != null && !status.isEmpty()) { if (status != null && !status.isEmpty()) {
query += buildStatusQuery(status); query += buildStatusQuery(status);
isStatusProvided = true; isStatusProvided = true;
@ -930,8 +965,16 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl {
for (Integer deviceId : deviceIds) { for (Integer deviceId : deviceIds) {
ps.setObject(index++, deviceId); ps.setObject(index++, deviceId);
} }
ps.setInt(index++, tenantId); ps.setInt(index++, tenantId);
if (isDeviceNameProvided) {
ps.setString(index++, name + "%");
}
if (isOwnershipProvided) {
ps.setString(index++, ownership);
}
if (isOwnerProvided) {
ps.setString(index++, user);
}
if (isStatusProvided) { if (isStatusProvided) {
for (String deviceStatus : status) { for (String deviceStatus : status) {
ps.setString(index++, deviceStatus); ps.setString(index++, deviceStatus);

View File

@ -68,6 +68,8 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl {
boolean isStatusProvided = false; boolean isStatusProvided = false;
Date since = request.getSince(); Date since = request.getSince();
boolean isSinceProvided = false; boolean isSinceProvided = false;
String serial = request.getSerialNumber();
boolean isSerialProvided = false;
try { try {
conn = getConnection(); conn = getConnection();
@ -88,9 +90,19 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl {
"d.DESCRIPTION, " + "d.DESCRIPTION, " +
"d.NAME, " + "d.NAME, " +
"d.DEVICE_IDENTIFICATION, " + "d.DEVICE_IDENTIFICATION, " +
"t.NAME AS DEVICE_TYPE " + "t.NAME AS DEVICE_TYPE ";
"FROM DM_DEVICE d, " +
"DM_DEVICE_TYPE t WHERE DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ?"; if (serial != null) {
sql = sql + "FROM DM_DEVICE d, DM_DEVICE_TYPE t, DM_DEVICE_INFO i " +
"WHERE DEVICE_TYPE_ID = t.ID " +
"AND d.ID= i.DEVICE_ID " +
"AND i.KEY_FIELD = 'serial' " +
"AND i.VALUE_FIELD = ? " +
"AND d.TENANT_ID = ? ";
isSerialProvided = true;
} else {
sql = sql + "FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ? ";
}
//Add query for last updated timestamp //Add query for last updated timestamp
if (since != null) { if (since != null) {
sql = sql + " AND d.LAST_UPDATED_TIMESTAMP > ?"; sql = sql + " AND d.LAST_UPDATED_TIMESTAMP > ?";
@ -128,6 +140,9 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl {
try (PreparedStatement stmt = conn.prepareStatement(sql)) { try (PreparedStatement stmt = conn.prepareStatement(sql)) {
int paramIdx = 1; int paramIdx = 1;
if (isSerialProvided) {
stmt.setString(paramIdx++, serial);
}
stmt.setInt(paramIdx++, tenantId); stmt.setInt(paramIdx++, tenantId);
if (isSinceProvided) { if (isSinceProvided) {
stmt.setTimestamp(paramIdx++, new Timestamp(since.getTime())); stmt.setTimestamp(paramIdx++, new Timestamp(since.getTime()));
@ -847,11 +862,15 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl {
} }
@Override @Override
public List<Device> getSubscribedDevices(int offsetValue, int limitValue, public List<Device> getSubscribedDevices(PaginationRequest request, List<Integer> deviceIds, int tenantId)
List<Integer> deviceIds, int tenantId, List<String> status)
throws DeviceManagementDAOException { throws DeviceManagementDAOException {
Connection conn; Connection conn;
int limitValue = request.getRowCount();
int offsetValue = request.getStartIndex();
List<String> status = request.getStatusList();
String name = request.getDeviceName();
String user = request.getOwner();
String ownership = request.getOwnership();
try { try {
List<Device> devices = new ArrayList<>(); List<Device> devices = new ArrayList<>();
if (deviceIds.isEmpty()) { if (deviceIds.isEmpty()) {
@ -861,6 +880,9 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl {
int index = 1; int index = 1;
boolean isStatusProvided = false; boolean isStatusProvided = false;
boolean isDeviceNameProvided = false;
boolean isOwnerProvided = false;
boolean isOwnershipProvided = false;
StringJoiner joiner = new StringJoiner(",", StringJoiner joiner = new StringJoiner(",",
"SELECT " "SELECT "
+ "DM_DEVICE.ID AS DEVICE_ID, " + "DM_DEVICE.ID AS DEVICE_ID, "
@ -888,6 +910,18 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl {
deviceIds.stream().map(ignored -> "?").forEach(joiner::add); deviceIds.stream().map(ignored -> "?").forEach(joiner::add);
String query = joiner.toString(); String query = joiner.toString();
if (name != null && !name.isEmpty()) {
query += " AND DM_DEVICE.NAME LIKE ?";
isDeviceNameProvided = true;
}
if (ownership != null && !ownership.isEmpty()) {
query += " AND e.OWNERSHIP = ?";
isOwnershipProvided = true;
}
if (user != null && !user.isEmpty()) {
query += " AND e.OWNER = ?";
isOwnerProvided = true;
}
if (status != null && !status.isEmpty()) { if (status != null && !status.isEmpty()) {
query += buildStatusQuery(status); query += buildStatusQuery(status);
isStatusProvided = true; isStatusProvided = true;
@ -902,6 +936,15 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl {
} }
ps.setInt(index++, tenantId); ps.setInt(index++, tenantId);
if (isDeviceNameProvided) {
ps.setString(index++, name + "%");
}
if (isOwnershipProvided) {
ps.setString(index++, ownership);
}
if (isOwnerProvided) {
ps.setString(index++, user);
}
if (isStatusProvided) { if (isStatusProvided) {
for (String deviceStatus : status) { for (String deviceStatus : status) {
ps.setString(index++, deviceStatus); ps.setString(index++, deviceStatus);

View File

@ -67,6 +67,8 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl {
boolean isStatusProvided = false; boolean isStatusProvided = false;
Date since = request.getSince(); Date since = request.getSince();
boolean isSinceProvided = false; boolean isSinceProvided = false;
String serial = request.getSerialNumber();
boolean isSerialProvided = false;
try { try {
conn = getConnection(); conn = getConnection();
@ -87,11 +89,19 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl {
"d.DESCRIPTION, " + "d.DESCRIPTION, " +
"d.NAME, " + "d.NAME, " +
"d.DEVICE_IDENTIFICATION, " + "d.DEVICE_IDENTIFICATION, " +
"t.NAME AS DEVICE_TYPE " + "t.NAME AS DEVICE_TYPE ";
"FROM DM_DEVICE d, " +
"DM_DEVICE_TYPE t " + if (serial != null) {
"WHERE DEVICE_TYPE_ID = t.ID " + sql = sql + "FROM DM_DEVICE d, DM_DEVICE_TYPE t, DM_DEVICE_INFO i " +
"AND d.TENANT_ID = ?"; "WHERE DEVICE_TYPE_ID = t.ID " +
"AND d.ID= i.DEVICE_ID " +
"AND i.KEY_FIELD = 'serial' " +
"AND i.VALUE_FIELD = ? " +
"AND d.TENANT_ID = ? ";
isSerialProvided = true;
} else {
sql = sql + "FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ? ";
}
//Add the query for device-type //Add the query for device-type
if (deviceType != null && !deviceType.isEmpty()) { if (deviceType != null && !deviceType.isEmpty()) {
sql = sql + " AND t.NAME = ?"; sql = sql + " AND t.NAME = ?";
@ -124,6 +134,9 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl {
try (PreparedStatement stmt = conn.prepareStatement(sql)) { try (PreparedStatement stmt = conn.prepareStatement(sql)) {
int paramIdx = 1; int paramIdx = 1;
if (isSerialProvided) {
stmt.setString(paramIdx++, serial);
}
stmt.setInt(paramIdx++, tenantId); stmt.setInt(paramIdx++, tenantId);
if (isDeviceTypeProvided) { if (isDeviceTypeProvided) {
stmt.setString(paramIdx++, deviceType); stmt.setString(paramIdx++, deviceType);
@ -827,11 +840,15 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl {
} }
@Override @Override
public List<Device> getSubscribedDevices(int offsetValue, int limitValue, public List<Device> getSubscribedDevices(PaginationRequest request, List<Integer> deviceIds, int tenantId)
List<Integer> deviceIds, int tenantId, List<String> status)
throws DeviceManagementDAOException { throws DeviceManagementDAOException {
Connection conn; Connection conn;
int limitValue = request.getRowCount();
int offsetValue = request.getStartIndex();
List<String> status = request.getStatusList();
String name = request.getDeviceName();
String user = request.getOwner();
String ownership = request.getOwnership();
try { try {
List<Device> devices = new ArrayList<>(); List<Device> devices = new ArrayList<>();
if (deviceIds.isEmpty()) { if (deviceIds.isEmpty()) {
@ -841,6 +858,9 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl {
int index = 1; int index = 1;
boolean isStatusProvided = false; boolean isStatusProvided = false;
boolean isDeviceNameProvided = false;
boolean isOwnerProvided = false;
boolean isOwnershipProvided = false;
StringJoiner joiner = new StringJoiner(",", StringJoiner joiner = new StringJoiner(",",
"SELECT " "SELECT "
+ "DM_DEVICE.ID AS DEVICE_ID, " + "DM_DEVICE.ID AS DEVICE_ID, "
@ -868,6 +888,18 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl {
deviceIds.stream().map(ignored -> "?").forEach(joiner::add); deviceIds.stream().map(ignored -> "?").forEach(joiner::add);
String query = joiner.toString(); String query = joiner.toString();
if (name != null && !name.isEmpty()) {
query += " AND DM_DEVICE.NAME LIKE ?";
isDeviceNameProvided = true;
}
if (ownership != null && !ownership.isEmpty()) {
query += " AND e.OWNERSHIP = ?";
isOwnershipProvided = true;
}
if (user != null && !user.isEmpty()) {
query += " AND e.OWNER = ?";
isOwnerProvided = true;
}
if (status != null && !status.isEmpty()) { if (status != null && !status.isEmpty()) {
query += buildStatusQuery(status); query += buildStatusQuery(status);
isStatusProvided = true; isStatusProvided = true;
@ -882,6 +914,15 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl {
} }
ps.setInt(index++, tenantId); ps.setInt(index++, tenantId);
if (isDeviceNameProvided) {
ps.setString(index++, name + "%");
}
if (isOwnershipProvided) {
ps.setString(index++, ownership);
}
if (isOwnerProvided) {
ps.setString(index++, user);
}
if (isStatusProvided) { if (isStatusProvided) {
for (String deviceStatus : status) { for (String deviceStatus : status) {
ps.setString(index++, deviceStatus); ps.setString(index++, deviceStatus);

View File

@ -69,6 +69,8 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl {
boolean isStatusProvided = false; boolean isStatusProvided = false;
Date since = request.getSince(); Date since = request.getSince();
boolean isSinceProvided = false; boolean isSinceProvided = false;
String serial = request.getSerialNumber();
boolean isSerialProvided = false;
try { try {
conn = getConnection(); conn = getConnection();
@ -89,8 +91,19 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl {
"d.DESCRIPTION, " + "d.DESCRIPTION, " +
"d.NAME, " + "d.NAME, " +
"d.DEVICE_IDENTIFICATION, " + "d.DEVICE_IDENTIFICATION, " +
"t.NAME AS DEVICE_TYPE " + "t.NAME AS DEVICE_TYPE ";
"FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ?";
if (serial != null) {
sql = sql + "FROM DM_DEVICE d, DM_DEVICE_TYPE t, DM_DEVICE_INFO i " +
"WHERE DEVICE_TYPE_ID = t.ID " +
"AND d.ID= i.DEVICE_ID " +
"AND i.KEY_FIELD = 'serial' " +
"AND i.VALUE_FIELD = ? " +
"AND d.TENANT_ID = ? ";
isSerialProvided = true;
} else {
sql = sql + "FROM DM_DEVICE d, DM_DEVICE_TYPE t WHERE DEVICE_TYPE_ID = t.ID AND d.TENANT_ID = ? ";
}
//Add query for last updated timestamp //Add query for last updated timestamp
if (since != null) { if (since != null) {
sql = sql + " AND d.LAST_UPDATED_TIMESTAMP > ?"; sql = sql + " AND d.LAST_UPDATED_TIMESTAMP > ?";
@ -128,6 +141,9 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl {
try (PreparedStatement stmt = conn.prepareStatement(sql)) { try (PreparedStatement stmt = conn.prepareStatement(sql)) {
int paramIdx = 1; int paramIdx = 1;
if (isSerialProvided) {
stmt.setString(paramIdx++, serial);
}
stmt.setInt(paramIdx++, tenantId); stmt.setInt(paramIdx++, tenantId);
if (isSinceProvided) { if (isSinceProvided) {
stmt.setTimestamp(paramIdx++, new Timestamp(since.getTime())); stmt.setTimestamp(paramIdx++, new Timestamp(since.getTime()));
@ -693,11 +709,15 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl {
} }
@Override @Override
public List<Device> getSubscribedDevices(int offsetValue, int limitValue, public List<Device> getSubscribedDevices(PaginationRequest request, List<Integer> deviceIds, int tenantId)
List<Integer> deviceIds, int tenantId, List<String> status)
throws DeviceManagementDAOException { throws DeviceManagementDAOException {
Connection conn; Connection conn;
int limitValue = request.getRowCount();
int offsetValue = request.getStartIndex();
List<String> status = request.getStatusList();
String name = request.getDeviceName();
String user = request.getOwner();
String ownership = request.getOwnership();
try { try {
List<Device> devices = new ArrayList<>(); List<Device> devices = new ArrayList<>();
if (deviceIds.isEmpty()) { if (deviceIds.isEmpty()) {
@ -707,6 +727,9 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl {
int index = 1; int index = 1;
boolean isStatusProvided = false; boolean isStatusProvided = false;
boolean isDeviceNameProvided = false;
boolean isOwnerProvided = false;
boolean isOwnershipProvided = false;
StringJoiner joiner = new StringJoiner(",", StringJoiner joiner = new StringJoiner(",",
"SELECT " "SELECT "
+ "DM_DEVICE.ID AS DEVICE_ID, " + "DM_DEVICE.ID AS DEVICE_ID, "
@ -734,6 +757,18 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl {
deviceIds.stream().map(ignored -> "?").forEach(joiner::add); deviceIds.stream().map(ignored -> "?").forEach(joiner::add);
String query = joiner.toString(); String query = joiner.toString();
if (name != null && !name.isEmpty()) {
query += " AND DM_DEVICE.NAME LIKE ?";
isDeviceNameProvided = true;
}
if (ownership != null && !ownership.isEmpty()) {
query += " AND e.OWNERSHIP = ?";
isOwnershipProvided = true;
}
if (user != null && !user.isEmpty()) {
query += " AND e.OWNER = ?";
isOwnerProvided = true;
}
if (status != null && !status.isEmpty()) { if (status != null && !status.isEmpty()) {
query += buildStatusQuery(status); query += buildStatusQuery(status);
isStatusProvided = true; isStatusProvided = true;
@ -748,6 +783,15 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl {
} }
ps.setInt(index++, tenantId); ps.setInt(index++, tenantId);
if (isDeviceNameProvided) {
ps.setString(index++, name + "%");
}
if (isOwnershipProvided) {
ps.setString(index++, ownership);
}
if (isOwnerProvided) {
ps.setString(index++, user);
}
if (isStatusProvided) { if (isStatusProvided) {
for (String deviceStatus : status) { for (String deviceStatus : status) {
ps.setString(index++, deviceStatus); ps.setString(index++, deviceStatus);

View File

@ -22,6 +22,10 @@ public class CommandOperation extends Operation {
private boolean enabled; private boolean enabled;
public CommandOperation() {
setControl(Control.NO_REPEAT);
}
public boolean isEnabled() { public boolean isEnabled() {
return enabled; return enabled;
} }
@ -34,8 +38,4 @@ public class CommandOperation extends Operation {
return Type.COMMAND; return Type.COMMAND;
} }
public Control getControl(){
return Control.NO_REPEAT;
}
} }

View File

@ -23,10 +23,11 @@ import java.util.List;
public class ConfigOperation extends Operation { public class ConfigOperation extends Operation {
private List<Property> properties; private final List<Property> properties;
public ConfigOperation() { public ConfigOperation() {
properties = new ArrayList<Property>(); properties = new ArrayList<>();
setControl(Control.REPEAT);
} }
public List<Property> getConfigProperties() { public List<Property> getConfigProperties() {
@ -37,6 +38,10 @@ public class ConfigOperation extends Operation {
properties.add(new Property(name, value, type)); properties.add(new Property(name, value, type));
} }
public Type getType() {
return Type.CONFIG;
}
public static class Property { public static class Property {
private String name; private String name;
private Object value; private Object value;
@ -73,13 +78,4 @@ public class ConfigOperation extends Operation {
} }
} }
public Type getType() {
return Type.CONFIG;
}
public Control getControl(){
return Control.REPEAT;
}
} }

View File

@ -19,7 +19,13 @@ package org.wso2.carbon.device.mgt.core.dto.operation.mgt;
import java.util.List; import java.util.List;
public class PolicyOperation extends Operation{ public class PolicyOperation extends Operation {
private List<ProfileOperation> profileOperations;
public PolicyOperation() {
setControl(Control.REPEAT);
}
public List<ProfileOperation> getProfileOperations() { public List<ProfileOperation> getProfileOperations() {
return profileOperations; return profileOperations;
@ -29,10 +35,4 @@ public class PolicyOperation extends Operation{
this.profileOperations = profileOperations; this.profileOperations = profileOperations;
} }
private List<ProfileOperation> profileOperations;
public Control getControl(){
return Control.REPEAT;
}
} }

View File

@ -22,13 +22,12 @@ import java.io.Serializable;
public class ProfileOperation extends ConfigOperation implements Serializable { public class ProfileOperation extends ConfigOperation implements Serializable {
public ProfileOperation() {
super();
}
public Type getType() { public Type getType() {
return Type.PROFILE; return Type.PROFILE;
} }
public Control getControl(){
return Control.REPEAT;
}
} }

View File

@ -24,6 +24,10 @@ public class CommandOperation extends Operation {
private boolean enabled; private boolean enabled;
public CommandOperation() {
setControl(Control.NO_REPEAT);
}
public boolean isEnabled() { public boolean isEnabled() {
return enabled; return enabled;
} }
@ -35,8 +39,5 @@ public class CommandOperation extends Operation {
public Type getType() { public Type getType() {
return Type.COMMAND; return Type.COMMAND;
} }
public Control getControl(){
return Control.NO_REPEAT;
}
} }

View File

@ -21,8 +21,6 @@ package org.wso2.carbon.device.mgt.core.operation.mgt;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class ConfigOperation extends Operation { public class ConfigOperation extends Operation {
@ -38,6 +36,15 @@ public class ConfigOperation extends Operation {
properties.add(new Property(name, value, type)); properties.add(new Property(name, value, type));
}*/ }*/
public ConfigOperation() {
//properties = new ArrayList<>();
setControl(Control.REPEAT);
}
public Type getType() {
return Type.CONFIG;
}
public static class Property implements Serializable { public static class Property implements Serializable {
private String name; private String name;
private Object value; private Object value;
@ -74,12 +81,4 @@ public class ConfigOperation extends Operation {
} }
} }
public Type getType() {
return Type.CONFIG;
}
public Control getControl(){
return Control.REPEAT;
}
} }

View File

@ -18,6 +18,7 @@
package org.wso2.carbon.device.mgt.core.operation.mgt; package org.wso2.carbon.device.mgt.core.operation.mgt;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import java.util.List; import java.util.List;
public class PolicyOperation extends Operation { public class PolicyOperation extends Operation {
@ -25,6 +26,10 @@ public class PolicyOperation extends Operation {
public static final String POLICY_OPERATION_CODE = "POLICY_BUNDLE"; public static final String POLICY_OPERATION_CODE = "POLICY_BUNDLE";
private List<ProfileOperation> profileOperations; private List<ProfileOperation> profileOperations;
public PolicyOperation() {
setControl(Control.REPEAT);
}
public List<ProfileOperation> getProfileOperations() { public List<ProfileOperation> getProfileOperations() {
return profileOperations; return profileOperations;
} }
@ -33,8 +38,4 @@ public class PolicyOperation extends Operation {
this.profileOperations = profileOperations; this.profileOperations = profileOperations;
} }
public Control getControl(){
return Control.REPEAT;
}
} }

View File

@ -19,21 +19,21 @@
package org.wso2.carbon.device.mgt.core.operation.mgt; package org.wso2.carbon.device.mgt.core.operation.mgt;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList;
import java.util.List; import java.util.List;
public class ProfileOperation extends ConfigOperation implements Serializable { public class ProfileOperation extends ConfigOperation implements Serializable {
private static final long serialVersionUID = -3322674908775087365L; private static final long serialVersionUID = -3322674908775087365L;
private List<Integer> correctiveActionIds; private List<Integer> correctiveActionIds;
private List<Integer> reactiveActionIds; private List<Integer> reactiveActionIds;
public Type getType() { public ProfileOperation() {
return Type.PROFILE; super();
} }
public Control getControl(){ public Type getType() {
return Control.REPEAT; return Type.PROFILE;
} }
public List<Integer> getCorrectiveActionIds() { public List<Integer> getCorrectiveActionIds() {
@ -51,4 +51,5 @@ public class ProfileOperation extends ConfigOperation implements Serializable {
public void setReactiveActionIds(List<Integer> reactiveActionIds) { public void setReactiveActionIds(List<Integer> reactiveActionIds) {
this.reactiveActionIds = reactiveActionIds; this.reactiveActionIds = reactiveActionIds;
} }
} }

View File

@ -905,14 +905,12 @@ public interface DeviceManagementProviderService {
* This method retrieves a list of subscribed devices. * This method retrieves a list of subscribed devices.
* *
* @param devicesIds devices ids of the subscribed devices. * @param devicesIds devices ids of the subscribed devices.
* @param offsetValue offset value for get paginated request. * @param request paginated request object.
* @param limitValue limit value for get paginated request.
* @param status status of the devices.
* @return {@link PaginationResult} * @return {@link PaginationResult}
* @throws DeviceManagementException if any service level or DAO level error occurs. * @throws DeviceManagementException if any service level or DAO level error occurs.
*/ */
PaginationResult getAppSubscribedDevices(int offsetValue, int limitValue, PaginationResult getAppSubscribedDevices(PaginationRequest request, List<Integer> devicesIds)
List<Integer> devicesIds, List<String> status) throws DeviceManagementException; throws DeviceManagementException;
/** /**
* This method is used to get a list of applications installed in all enrolled devices * This method is used to get a list of applications installed in all enrolled devices

View File

@ -4161,9 +4161,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
} }
@Override @Override
public PaginationResult getAppSubscribedDevices(int offsetValue, int limitValue, List<Integer> devicesIds, public PaginationResult getAppSubscribedDevices(PaginationRequest request, List<Integer> devicesIds) throws DeviceManagementException {
List<String> status) throws DeviceManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true); int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Getting all devices details for device ids: " + devicesIds); log.debug("Getting all devices details for device ids: " + devicesIds);
@ -4172,15 +4170,14 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
List<Device> subscribedDeviceDetails; List<Device> subscribedDeviceDetails;
try { try {
DeviceManagementDAOFactory.openConnection(); DeviceManagementDAOFactory.openConnection();
subscribedDeviceDetails = deviceDAO subscribedDeviceDetails = deviceDAO.getSubscribedDevices(request, devicesIds, tenantId);
.getSubscribedDevices(offsetValue, limitValue, devicesIds, tenantId, status);
if (subscribedDeviceDetails.isEmpty()) { if (subscribedDeviceDetails.isEmpty()) {
paginationResult.setData(new ArrayList<>()); paginationResult.setData(new ArrayList<>());
paginationResult.setRecordsFiltered(0); paginationResult.setRecordsFiltered(0);
paginationResult.setRecordsTotal(0); paginationResult.setRecordsTotal(0);
return paginationResult; return paginationResult;
} }
int count = deviceDAO.getSubscribedDeviceCount(devicesIds, tenantId, status); int count = deviceDAO.getSubscribedDeviceCount(devicesIds, tenantId, request.getStatusList());
paginationResult.setRecordsFiltered(count); paginationResult.setRecordsFiltered(count);
paginationResult.setRecordsTotal(count); paginationResult.setRecordsTotal(count);
} catch (DeviceManagementDAOException e) { } catch (DeviceManagementDAOException e) {

View File

@ -52,6 +52,7 @@ public class DeviceStatusMonitoringTask extends DynamicPartitionedScheduleTask {
@Override @Override
public void setProperties(Map<String, String> properties) { public void setProperties(Map<String, String> properties) {
super.setProperties(properties);
deviceType = properties.get(DeviceStatusTaskManagerServiceImpl.DEVICE_TYPE); deviceType = properties.get(DeviceStatusTaskManagerServiceImpl.DEVICE_TYPE);
deviceTypeId = Integer.parseInt(properties.get(DeviceStatusTaskManagerServiceImpl.DEVICE_TYPE_ID)); deviceTypeId = Integer.parseInt(properties.get(DeviceStatusTaskManagerServiceImpl.DEVICE_TYPE_ID));
String deviceStatusTaskConfigStr = properties.get(DeviceStatusTaskManagerServiceImpl.DEVICE_STATUS_TASK_CONFIG); String deviceStatusTaskConfigStr = properties.get(DeviceStatusTaskManagerServiceImpl.DEVICE_STATUS_TASK_CONFIG);

View File

@ -39,28 +39,26 @@ import org.apache.commons.logging.Log;
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;
import org.wso2.carbon.device.mgt.common.DynamicTaskContext;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig; import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig;
import org.wso2.carbon.device.mgt.common.StartupOperationConfig; import org.wso2.carbon.device.mgt.common.StartupOperationConfig;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder; import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.core.task.DeviceMgtTaskException; import org.wso2.carbon.device.mgt.core.task.DeviceMgtTaskException;
import org.wso2.carbon.device.mgt.core.task.DeviceTaskManager; import org.wso2.carbon.device.mgt.core.task.DeviceTaskManager;
import org.wso2.carbon.ntask.core.Task;
import org.wso2.carbon.user.api.UserStoreException;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public class DeviceDetailsRetrieverTask extends DynamicPartitionedScheduleTask { public class DeviceDetailsRetrieverTask extends DynamicPartitionedScheduleTask {
private static Log log = LogFactory.getLog(DeviceDetailsRetrieverTask.class); private static final Log log = LogFactory.getLog(DeviceDetailsRetrieverTask.class);
private String deviceType; private String deviceType;
private DeviceManagementProviderService deviceManagementProviderService; private DeviceManagementProviderService deviceManagementProviderService;
@Override @Override
public void setProperties(Map<String, String> map) { public void setProperties(Map<String, String> map) {
super.setProperties(map);
deviceType = map.get("DEVICE_TYPE"); deviceType = map.get("DEVICE_TYPE");
} }
@ -122,7 +120,7 @@ public class DeviceDetailsRetrieverTask extends DynamicPartitionedScheduleTask {
//pass the configurations also from here, monitoring tasks //pass the configurations also from here, monitoring tasks
try { try {
if (deviceManagementProviderService.isDeviceMonitoringEnabled(deviceType)) { if (deviceManagementProviderService.isDeviceMonitoringEnabled(deviceType)) {
deviceTaskManager.addOperations(super.getTaskContext()); deviceTaskManager.addOperations(getTaskContext());
} }
} catch (DeviceMgtTaskException e) { } catch (DeviceMgtTaskException e) {
log.error("Error occurred while trying to add the operations to " + log.error("Error occurred while trying to add the operations to " +

View File

@ -26,12 +26,27 @@ import org.wso2.carbon.device.mgt.common.DynamicTaskContext;
import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder; import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
import org.wso2.carbon.ntask.core.Task; import org.wso2.carbon.ntask.core.Task;
import java.util.Map;
public abstract class DynamicPartitionedScheduleTask implements Task { public abstract class DynamicPartitionedScheduleTask implements Task {
private static final Log log = LogFactory.getLog(DynamicPartitionedScheduleTask.class); private static final Log log = LogFactory.getLog(DynamicPartitionedScheduleTask.class);
private static DynamicTaskContext taskContext = null; private static DynamicTaskContext taskContext = null;
private Map<String, String> properties;
@Override
public void setProperties(Map<String, String> properties) {
this.properties = properties;
}
public String getProperty(String name) {
if (properties == null) {
return null;
}
return properties.get(name);
}
@Override @Override
public final void init() { public final void init() {
@ -97,11 +112,7 @@ public abstract class DynamicPartitionedScheduleTask implements Task {
} }
public static boolean isDynamicTaskEligible(){ public static boolean isDynamicTaskEligible(){
if(taskContext != null && taskContext.isPartitioningEnabled()) { return taskContext != null && taskContext.isPartitioningEnabled();
return true;
} else {
return false;
}
} }
} }

View File

@ -61,6 +61,8 @@ public abstract class RandomlyAssignedScheduleTask implements Task {
log.error("Error refreshing Variables necessary for Randomly Assigned Scheduled Task. " + log.error("Error refreshing Variables necessary for Randomly Assigned Scheduled Task. " +
"Dynamic Tasks will not function.", e); "Dynamic Tasks will not function.", e);
} }
} else {
qualifiedToExecuteTask = true;
} }
} }

View File

@ -21,8 +21,8 @@ package org.wso2.carbon.policy.mgt.core.enforcement;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.Device; import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo; import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager; import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
import org.wso2.carbon.device.mgt.core.config.policy.PolicyConfiguration; import org.wso2.carbon.device.mgt.core.config.policy.PolicyConfiguration;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
@ -36,19 +36,13 @@ import org.wso2.carbon.policy.mgt.core.mgt.impl.PolicyManagerImpl;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
public class DelegationTask extends DynamicPartitionedScheduleTask { public class DelegationTask extends DynamicPartitionedScheduleTask {
private static final Log log = LogFactory.getLog(DelegationTask.class); private static final Log log = LogFactory.getLog(DelegationTask.class);
private PolicyConfiguration policyConfiguration = DeviceConfigurationManager.getInstance() private final PolicyConfiguration policyConfiguration = DeviceConfigurationManager.getInstance()
.getDeviceManagementConfig().getPolicyConfiguration(); .getDeviceManagementConfig().getPolicyConfiguration();
@Override
public void setProperties(Map<String, String> map) {
}
@Override @Override
public void executeDynamicTask() { public void executeDynamicTask() {
try { try {
@ -70,10 +64,10 @@ public class DelegationTask extends DynamicPartitionedScheduleTask {
try { try {
devices = new ArrayList<>(); devices = new ArrayList<>();
toBeNotified = new ArrayList<>(); toBeNotified = new ArrayList<>();
if (super.isDynamicTaskEligible()) { if (isDynamicTaskEligible()) {
devices.addAll(service.getAllocatedDevices(deviceType, devices.addAll(service.getAllocatedDevices(deviceType,
super.getTaskContext().getActiveServerCount(), getTaskContext().getActiveServerCount(),
super.getTaskContext().getServerHashIndex())); getTaskContext().getServerHashIndex()));
} else { } else {
devices.addAll(service.getAllDevices(deviceType, false)); devices.addAll(service.getAllDevices(deviceType, false));
} }
@ -81,9 +75,9 @@ public class DelegationTask extends DynamicPartitionedScheduleTask {
if (device != null && device.getEnrolmentInfo() != null if (device != null && device.getEnrolmentInfo() != null
&& device.getEnrolmentInfo().getStatus() != EnrolmentInfo.Status.REMOVED) { && device.getEnrolmentInfo().getStatus() != EnrolmentInfo.Status.REMOVED) {
toBeNotified.add(device); toBeNotified.add(device);
} if (log.isDebugEnabled()) {
if (log.isDebugEnabled()) { log.debug("Adding policy operation to device : " + device.getDeviceIdentifier());
log.debug("Adding policy operation to device : " + device.getDeviceIdentifier()); }
} }
} }
if (!toBeNotified.isEmpty()) { if (!toBeNotified.isEmpty()) {

View File

@ -24,33 +24,22 @@ import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.Device; import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo; import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager; import org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager;
import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.PolicyComplianceException; import org.wso2.carbon.device.mgt.common.policy.mgt.monitor.PolicyComplianceException;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.core.task.impl.DynamicPartitionedScheduleTask; import org.wso2.carbon.device.mgt.core.task.impl.DynamicPartitionedScheduleTask;
import org.wso2.carbon.policy.mgt.core.internal.PolicyManagementDataHolder; import org.wso2.carbon.policy.mgt.core.internal.PolicyManagementDataHolder;
import org.wso2.carbon.policy.mgt.core.mgt.MonitoringManager; import org.wso2.carbon.policy.mgt.core.mgt.MonitoringManager;
import org.wso2.carbon.policy.mgt.core.util.PolicyManagementConstants;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
public class MonitoringTask extends DynamicPartitionedScheduleTask { public class MonitoringTask extends DynamicPartitionedScheduleTask {
private static final Log log = LogFactory.getLog(MonitoringTask.class); private static final Log log = LogFactory.getLog(MonitoringTask.class);
@Override private String tenant;
public void setProperties(Map<String, String> map) {
}
@Override
public void executeDynamicTask() {
if (log.isDebugEnabled()) {
log.debug("Monitoring task started to run.");
}
this.executeforAllTenants();
}
/** /**
* Check whether Device platform (ex: android) is exist in the cdm-config.xml file before adding a * Check whether Device platform (ex: android) is exist in the cdm-config.xml file before adding a
@ -66,30 +55,27 @@ public class MonitoringTask extends DynamicPartitionedScheduleTask {
return policyMonitoringManager != null; return policyMonitoringManager != null;
} }
private void executeforAllTenants() { @Override
public void executeDynamicTask() {
tenant = getProperty(PolicyManagementConstants.TENANT_ID);
if (tenant == null) {
log.warn("Tenant id of the Monitoring Task got null");
return;
}
int tenantId = Integer.parseInt(tenant);
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Monitoring task started to run for all tenants."); log.debug("Monitoring task started to run for tenant: " + tenant);
}
if (MultitenantConstants.SUPER_TENANT_ID == tenantId) {
this.executeTask();
return;
} }
try { try {
DeviceManagementProviderService deviceManagementService = PolicyManagementDataHolder PrivilegedCarbonContext.startTenantFlow();
.getInstance().getDeviceManagementService(); PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId, true);
List<Integer> tenants = deviceManagementService.getDeviceEnrolledTenants(); this.executeTask();
for (Integer tenant : tenants) { } finally {
if (MultitenantConstants.SUPER_TENANT_ID == tenant) { PrivilegedCarbonContext.endTenantFlow();
this.executeTask();
continue;
}
try {
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenant, true);
this.executeTask();
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
}
} catch (DeviceManagementException e) {
log.error("Error occurred while trying to get the available tenants from device manager service ", e);
} }
} }
@ -105,7 +91,7 @@ public class MonitoringTask extends DynamicPartitionedScheduleTask {
} }
} }
} catch (PolicyComplianceException e) { } catch (PolicyComplianceException e) {
log.error("Error occurred while getting the device types."); log.error("TID:[" + tenant + "] Error occurred while getting the device types.");
} }
if (!deviceTypes.isEmpty()) { if (!deviceTypes.isEmpty()) {
try { try {
@ -113,42 +99,42 @@ public class MonitoringTask extends DynamicPartitionedScheduleTask {
PolicyManagementDataHolder.getInstance().getDeviceManagementService(); PolicyManagementDataHolder.getInstance().getDeviceManagementService();
for (String deviceType : configDeviceTypes) { for (String deviceType : configDeviceTypes) {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Running task for device type : " + deviceType); log.debug("TID:[" + tenant + "] Running task for device type : " + deviceType);
} }
PolicyMonitoringManager monitoringService = PolicyMonitoringManager monitoringService =
PolicyManagementDataHolder.getInstance().getDeviceManagementService() PolicyManagementDataHolder.getInstance().getDeviceManagementService()
.getPolicyMonitoringManager(deviceType); .getPolicyMonitoringManager(deviceType);
List<Device> devices; List<Device> devices;
if(super.isDynamicTaskEligible()){ if(isDynamicTaskEligible()){
devices = deviceManagementProviderService.getAllocatedDevices(deviceType, devices = deviceManagementProviderService
super.getTaskContext().getActiveServerCount(), .getAllocatedDevices(deviceType, getTaskContext().getActiveServerCount(),
super.getTaskContext().getServerHashIndex()); getTaskContext().getServerHashIndex());
} else { } else {
devices = deviceManagementProviderService.getAllDevices(deviceType, false); devices = deviceManagementProviderService.getAllDevices(deviceType, false);
} }
if (monitoringService != null && !devices.isEmpty()) { if (monitoringService != null && !devices.isEmpty()) {
List<Device> notifiableDevices = new ArrayList<>(); List<Device> notifiableDevices = new ArrayList<>();
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Removing inactive and blocked devices from the list for the device type : " + log.debug("TID:[" + tenant + "] Removing inactive and blocked devices from " +
deviceType); "the list for the device type : " + deviceType);
} }
StringBuilder sb = new StringBuilder();
for (Device device : devices) { for (Device device : devices) {
EnrolmentInfo.Status status = device.getEnrolmentInfo().getStatus(); EnrolmentInfo.Status status = device.getEnrolmentInfo().getStatus();
if (status.equals(EnrolmentInfo.Status.ACTIVE) || if (status.equals(EnrolmentInfo.Status.ACTIVE) ||
status.equals(EnrolmentInfo.Status.INACTIVE) ||
status.equals(EnrolmentInfo.Status.UNREACHABLE)) { status.equals(EnrolmentInfo.Status.UNREACHABLE)) {
notifiableDevices.add(device); notifiableDevices.add(device);
} if (log.isDebugEnabled()) {
if (log.isDebugEnabled()) { if (sb.length() > 0) {
log.debug("Adding monitoring operation to device : " + device.getDeviceIdentifier()); sb.append(", ");
}
sb.append(device.getDeviceIdentifier());
}
} }
} }
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Following '" + deviceType + "' devices selected to send the notification " + log.debug("TID:[" + tenant + "] Sending monitoring to '" + deviceType +
"for policy monitoring"); "' devices with ids [" + sb + "]");
for (Device device : notifiableDevices) {
log.debug(device.getDeviceIdentifier());
}
} }
if (!notifiableDevices.isEmpty()) { if (!notifiableDevices.isEmpty()) {
monitoringManager.addMonitoringOperation(deviceType, notifiableDevices); monitoringManager.addMonitoringOperation(deviceType, notifiableDevices);
@ -156,13 +142,14 @@ public class MonitoringTask extends DynamicPartitionedScheduleTask {
} }
} }
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Monitoring task running completed."); log.debug("TID:[" + tenant + "] Monitoring task running completed.");
} }
} catch (Exception e) { } catch (Exception e) {
log.error("Error occurred while trying to run a task.", e); log.error("TID:[" + tenant + "] Error occurred while trying to run a task.", e);
} }
} else { } else {
log.info("No device types registered currently. So did not run the monitoring task."); log.info("TID:[" + tenant + "] No device types registered currently. " +
"So did not run the monitoring task.");
} }
} }
@ -170,4 +157,5 @@ public class MonitoringTask extends DynamicPartitionedScheduleTask {
protected void setup() { protected void setup() {
} }
} }

View File

@ -39,7 +39,7 @@ import java.util.Map;
public class TaskScheduleServiceImpl implements TaskScheduleService { public class TaskScheduleServiceImpl implements TaskScheduleService {
private static final Log log = LogFactory.getLog(TaskScheduleServiceImpl.class); private static final Log log = LogFactory.getLog(TaskScheduleServiceImpl.class);
private PolicyConfiguration policyConfiguration; private final PolicyConfiguration policyConfiguration;
public TaskScheduleServiceImpl() { public TaskScheduleServiceImpl() {
@ -72,7 +72,7 @@ public class TaskScheduleServiceImpl implements TaskScheduleService {
Map<String, String> properties = new HashMap<>(); Map<String, String> properties = new HashMap<>();
properties.put(PolicyManagementConstants.TENANT_ID, String.valueOf(tenantId)); properties.put(PolicyManagementConstants.TENANT_ID, String.valueOf(tenantId));
String taskName = PolicyManagementConstants.MONITORING_TASK_NAME + "_" + String.valueOf(tenantId); String taskName = PolicyManagementConstants.MONITORING_TASK_NAME + "_" + tenantId;
if (!taskManager.isTaskScheduled(taskName)) { if (!taskManager.isTaskScheduled(taskName)) {
@ -101,7 +101,7 @@ public class TaskScheduleServiceImpl implements TaskScheduleService {
public void stopTask() throws PolicyMonitoringTaskException { public void stopTask() throws PolicyMonitoringTaskException {
int tenantId = getTenantId(); int tenantId = getTenantId();
try { try {
String taskName = PolicyManagementConstants.MONITORING_TASK_NAME + "_" + String.valueOf(tenantId); String taskName = PolicyManagementConstants.MONITORING_TASK_NAME + "_" + tenantId;
TaskService taskService = PolicyManagementDataHolder.getInstance().getTaskService(); TaskService taskService = PolicyManagementDataHolder.getInstance().getTaskService();
if (taskService.isServerInit()) { if (taskService.isServerInit()) {
TaskManager taskManager = taskService.getTaskManager(PolicyManagementConstants.MONITORING_TASK_TYPE); TaskManager taskManager = taskService.getTaskManager(PolicyManagementConstants.MONITORING_TASK_TYPE);
@ -117,7 +117,7 @@ public class TaskScheduleServiceImpl implements TaskScheduleService {
public void updateTask(int monitoringFrequency) throws PolicyMonitoringTaskException { public void updateTask(int monitoringFrequency) throws PolicyMonitoringTaskException {
int tenantId = getTenantId(); int tenantId = getTenantId();
try { try {
String taskName = PolicyManagementConstants.MONITORING_TASK_NAME + "_" + String.valueOf(tenantId); String taskName = PolicyManagementConstants.MONITORING_TASK_NAME + "_" + tenantId;
TaskService taskService = PolicyManagementDataHolder.getInstance().getTaskService(); TaskService taskService = PolicyManagementDataHolder.getInstance().getTaskService();
TaskManager taskManager = taskService.getTaskManager(PolicyManagementConstants.MONITORING_TASK_TYPE); TaskManager taskManager = taskService.getTaskManager(PolicyManagementConstants.MONITORING_TASK_TYPE);
@ -129,7 +129,7 @@ public class TaskScheduleServiceImpl implements TaskScheduleService {
triggerInfo.setRepeatCount(-1); triggerInfo.setRepeatCount(-1);
Map<String, String> properties = new HashMap<>(); Map<String, String> properties = new HashMap<>();
properties.put("tenantId", String.valueOf(tenantId)); properties.put(PolicyManagementConstants.TENANT_ID, String.valueOf(tenantId));
TaskInfo taskInfo = new TaskInfo(taskName, PolicyManagementConstants.MONITORING_TASK_CLAZZ, properties, TaskInfo taskInfo = new TaskInfo(taskName, PolicyManagementConstants.MONITORING_TASK_CLAZZ, properties,
triggerInfo); triggerInfo);
@ -150,7 +150,7 @@ public class TaskScheduleServiceImpl implements TaskScheduleService {
@Override @Override
public boolean isTaskScheduled() throws PolicyMonitoringTaskException { public boolean isTaskScheduled() throws PolicyMonitoringTaskException {
int tenantId = getTenantId(); int tenantId = getTenantId();
String taskName = PolicyManagementConstants.MONITORING_TASK_NAME + "_" + String.valueOf(tenantId); String taskName = PolicyManagementConstants.MONITORING_TASK_NAME + "_" + tenantId;
TaskService taskService = PolicyManagementDataHolder.getInstance().getTaskService(); TaskService taskService = PolicyManagementDataHolder.getInstance().getTaskService();
TaskManager taskManager; TaskManager taskManager;
try { try {

View File

@ -132,7 +132,7 @@ public class DefaultTokenHandler extends HttpServlet {
URIBuilder ub = new URIBuilder(); URIBuilder ub = new URIBuilder();
ub.setScheme(HandlerConstants.WSS_PROTOCOL); ub.setScheme(HandlerConstants.WSS_PROTOCOL);
ub.setHost(System.getProperty(HandlerConstants.IOT_CORE_HOST_ENV_VAR)); ub.setHost(System.getProperty(HandlerConstants.IOT_CORE_HOST_ENV_VAR));
ub.setPort(Integer.parseInt(System.getProperty(HandlerConstants.IOT_CORE_PORT_ENV_VAR))); ub.setPort(Integer.parseInt(System.getProperty(HandlerConstants.IOT_CORE_HTTPS_PORT_ENV_VAR)));
ub.setPath(HandlerConstants.REMOTE_SESSION_CONTEXT); ub.setPath(HandlerConstants.REMOTE_SESSION_CONTEXT);
JsonObject responseJsonObj = new JsonObject(); JsonObject responseJsonObj = new JsonObject();

View File

@ -48,6 +48,7 @@ import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.InputStreamBody; import org.apache.http.entity.mime.content.InputStreamBody;
import io.entgra.ui.request.interceptor.beans.ProxyResponse; import io.entgra.ui.request.interceptor.beans.ProxyResponse;
import org.wso2.carbon.context.CarbonContext;
import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet; import javax.servlet.annotation.WebServlet;
@ -111,6 +112,11 @@ public class InvokerHandler extends HttpServlet {
HttpGet getRequest = new HttpGet(generateBackendRequestURL(req)); HttpGet getRequest = new HttpGet(generateBackendRequestURL(req));
copyRequestHeaders(req, getRequest, false); copyRequestHeaders(req, getRequest, false);
getRequest.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BEARER + authData.getAccessToken()); getRequest.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BEARER + authData.getAccessToken());
if (apiEndpoint.equals(System.getProperty("iot.reporting.webapp.host"))) {
getRequest.setHeader("Tenant-Id", String.valueOf(
CarbonContext.getThreadLocalCarbonContext().getTenantId()
));
}
ProxyResponse proxyResponse = HandlerUtil.execute(getRequest); ProxyResponse proxyResponse = HandlerUtil.execute(getRequest);
if (HandlerConstants.TOKEN_IS_EXPIRED.equals(proxyResponse.getExecutorResponse())) { if (HandlerConstants.TOKEN_IS_EXPIRED.equals(proxyResponse.getExecutorResponse())) {
proxyResponse = retryRequestWithRefreshedToken(req, resp, getRequest); proxyResponse = retryRequestWithRefreshedToken(req, resp, getRequest);

View File

@ -24,6 +24,9 @@ import com.google.gson.JsonObject;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException; import com.google.gson.JsonSyntaxException;
import io.entgra.ui.request.interceptor.beans.AuthData; import io.entgra.ui.request.interceptor.beans.AuthData;
import io.entgra.ui.request.interceptor.cache.LoginCacheManager;
import io.entgra.ui.request.interceptor.cache.OAuthApp;
import io.entgra.ui.request.interceptor.cache.OAuthAppCacheKey;
import io.entgra.ui.request.interceptor.exceptions.LoginException; import io.entgra.ui.request.interceptor.exceptions.LoginException;
import io.entgra.ui.request.interceptor.util.HandlerConstants; import io.entgra.ui.request.interceptor.util.HandlerConstants;
import io.entgra.ui.request.interceptor.util.HandlerUtil; import io.entgra.ui.request.interceptor.util.HandlerUtil;
@ -56,7 +59,7 @@ public class LoginHandler extends HttpServlet {
private static String password; private static String password;
private static String gatewayUrl; private static String gatewayUrl;
private static String uiConfigUrl; private static String uiConfigUrl;
private static String keyManagerUrl; private static String iotsCoreUrl;
@Override @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) { protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
@ -70,33 +73,66 @@ public class LoginHandler extends HttpServlet {
//setting session to expiry in 5 minutes //setting session to expiry in 5 minutes
httpSession.setMaxInactiveInterval(Math.toIntExact(HandlerConstants.TIMEOUT)); httpSession.setMaxInactiveInterval(Math.toIntExact(HandlerConstants.TIMEOUT));
JsonObject uiConfigJsonObject = HandlerUtil.getUIConfigAndPersistInSession( JsonObject uiConfigJsonObject = HandlerUtil.getUIConfigAndPersistInSession(uiConfigUrl, gatewayUrl, httpSession, resp);
uiConfigUrl, gatewayUrl, httpSession, resp);
JsonArray tags = uiConfigJsonObject.get("appRegistration").getAsJsonObject().get("tags").getAsJsonArray(); JsonArray tags = uiConfigJsonObject.get("appRegistration").getAsJsonObject().get("tags").getAsJsonArray();
JsonArray scopes = uiConfigJsonObject.get("scopes").getAsJsonArray(); JsonArray scopes = uiConfigJsonObject.get("scopes").getAsJsonArray();
HttpPost apiRegEndpoint = new HttpPost(gatewayUrl + HandlerConstants.APP_REG_ENDPOINT); // Check if OAuth app cache exists. If not create a new application.
apiRegEndpoint.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC + Base64.getEncoder() LoginCacheManager loginCacheManager = new LoginCacheManager();
.encodeToString((username + HandlerConstants.COLON + password).getBytes())); loginCacheManager.initializeCacheManager();
apiRegEndpoint.setHeader(HTTP.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString()); OAuthAppCacheKey oAuthAppCacheKey = new OAuthAppCacheKey(HandlerConstants.PUBLISHER_APPLICATION_NAME, username);
apiRegEndpoint.setEntity(HandlerUtil.constructAppRegPayload( OAuthApp oAuthApp = loginCacheManager.getOAuthAppCache(oAuthAppCacheKey);
tags, HandlerConstants.PUBLISHER_APPLICATION_NAME, username, password));
ProxyResponse clientAppResponse = HandlerUtil.execute(apiRegEndpoint); if (oAuthApp == null) {
HttpPost apiRegEndpoint = new HttpPost(gatewayUrl + HandlerConstants.APP_REG_ENDPOINT);
apiRegEndpoint.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC + Base64.getEncoder()
.encodeToString((username + HandlerConstants.COLON + password).getBytes()));
apiRegEndpoint.setHeader(HTTP.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString());
apiRegEndpoint.setEntity(HandlerUtil.constructAppRegPayload(tags, HandlerConstants.PUBLISHER_APPLICATION_NAME, username, password));
if (clientAppResponse.getCode() == HttpStatus.SC_UNAUTHORIZED) { ProxyResponse clientAppResponse = HandlerUtil.execute(apiRegEndpoint);
HandlerUtil.handleError(resp, clientAppResponse);
return; if (clientAppResponse.getCode() == HttpStatus.SC_UNAUTHORIZED) {
HandlerUtil.handleError(resp, clientAppResponse);
return;
}
if (clientAppResponse.getCode() == HttpStatus.SC_CREATED) {
JsonParser jsonParser = new JsonParser();
JsonElement jClientAppResult = jsonParser.parse(clientAppResponse.getData());
String clientId = null;
String clientSecret = null;
String encodedClientApp = null;
if (jClientAppResult.isJsonObject()) {
JsonObject jClientAppResultAsJsonObject = jClientAppResult.getAsJsonObject();
clientId = jClientAppResultAsJsonObject.get("client_id").getAsString();
clientSecret = jClientAppResultAsJsonObject.get("client_secret").getAsString();
encodedClientApp = Base64.getEncoder()
.encodeToString((clientId + HandlerConstants.COLON + clientSecret).getBytes());
oAuthAppCacheKey = new OAuthAppCacheKey(HandlerConstants.PUBLISHER_APPLICATION_NAME, username);
oAuthApp = new OAuthApp(
HandlerConstants.PUBLISHER_APPLICATION_NAME,
username,
clientId,
clientSecret,
encodedClientApp
);
loginCacheManager.addOAuthAppToCache(oAuthAppCacheKey, oAuthApp);
}
if (getTokenAndPersistInSession(req, resp, clientId, clientSecret, encodedClientApp, scopes)) {
ProxyResponse proxyResponse = new ProxyResponse();
proxyResponse.setCode(HttpStatus.SC_OK);
HandlerUtil.handleSuccess(resp, proxyResponse);
return;
}
}
HandlerUtil.handleError(resp, null);
} else {
getTokenAndPersistInSession(req, resp, oAuthApp.getClientId(), oAuthApp.getClientSecret(), oAuthApp.getEncodedClientApp(), scopes);
} }
if (clientAppResponse.getCode() == HttpStatus.SC_CREATED && getTokenAndPersistInSession(req, resp,
clientAppResponse.getData(), scopes)) {
ProxyResponse proxyResponse = new ProxyResponse();
proxyResponse.setCode(HttpStatus.SC_OK);
HandlerUtil.handleSuccess(resp, proxyResponse);
return;
}
HandlerUtil.handleError(resp, null);
} catch (IOException e) { } catch (IOException e) {
log.error("Error occurred while sending the response into the socket. ", e); log.error("Error occurred while sending the response into the socket. ", e);
} catch (JsonSyntaxException e) { } catch (JsonSyntaxException e) {
@ -106,57 +142,54 @@ public class LoginHandler extends HttpServlet {
} }
} }
/*** /**
* Generates token from token endpoint and persists them inside the session * Generates token from token endpoint and persists them inside the session
* *
* @param req - {@link HttpServletRequest} * @param req - {@link HttpServletRequest}
* @param clientAppResult - clientAppResult * @param resp - {@link HttpServletResponse}
* @param scopes - scopes defied in the application-mgt.xml * @param clientId - clientId of the OAuth app
* @throws LoginException - login exception throws when getting token result * @param clientSecret - clientSecret of the OAuth app
* @param encodedClientApp - Base64 encoded clientId:clientSecret.
* @param scopes - User scopes JSON Array
* @return boolean response
* @throws LoginException - Throws if any error occurs while getting login response
*/ */
private boolean getTokenAndPersistInSession(HttpServletRequest req, HttpServletResponse resp, private boolean getTokenAndPersistInSession(HttpServletRequest req, HttpServletResponse resp,
String clientAppResult, JsonArray scopes) throws LoginException { String clientId, String clientSecret, String encodedClientApp,
JsonArray scopes) throws LoginException {
JsonParser jsonParser = new JsonParser(); JsonParser jsonParser = new JsonParser();
try { try {
JsonElement jClientAppResult = jsonParser.parse(clientAppResult);
if (jClientAppResult.isJsonObject()) {
JsonObject jClientAppResultAsJsonObject = jClientAppResult.getAsJsonObject();
String clientId = jClientAppResultAsJsonObject.get("client_id").getAsString();
String clientSecret = jClientAppResultAsJsonObject.get("client_secret").getAsString();
String encodedClientApp = Base64.getEncoder()
.encodeToString((clientId + HandlerConstants.COLON + clientSecret).getBytes());
ProxyResponse tokenResultResponse = getTokenResult(encodedClientApp, scopes); ProxyResponse tokenResultResponse = getTokenResult(encodedClientApp, scopes);
if (tokenResultResponse.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) { if (tokenResultResponse.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) {
log.error("Error occurred while invoking the API to get token data."); log.error("Error occurred while invoking the API to get token data.");
HandlerUtil.handleError(resp, tokenResultResponse); HandlerUtil.handleError(resp, tokenResultResponse);
return false;
}
String tokenResult = tokenResultResponse.getData();
if (tokenResult == null) {
log.error("Invalid token response is received.");
HandlerUtil.handleError(resp, tokenResultResponse);
return false;
}
JsonElement jTokenResult = jsonParser.parse(tokenResult);
if (jTokenResult.isJsonObject()) {
JsonObject jTokenResultAsJsonObject = jTokenResult.getAsJsonObject();
HttpSession session = req.getSession(false);
if (session == null) {
return false; return false;
} }
String tokenResult = tokenResultResponse.getData(); AuthData authData = new AuthData();
if (tokenResult == null) { authData.setClientId(clientId);
log.error("Invalid token response is received."); authData.setClientSecret(clientSecret);
HandlerUtil.handleError(resp, tokenResultResponse); authData.setEncodedClientApp(encodedClientApp);
return false; authData.setAccessToken(jTokenResultAsJsonObject.get("access_token").getAsString());
} authData.setRefreshToken(jTokenResultAsJsonObject.get("refresh_token").getAsString());
authData.setScope(jTokenResultAsJsonObject.get("scope").getAsString());
JsonElement jTokenResult = jsonParser.parse(tokenResult); session.setAttribute(HandlerConstants.SESSION_AUTH_DATA_KEY, authData);
if (jTokenResult.isJsonObject()) { return true;
JsonObject jTokenResultAsJsonObject = jTokenResult.getAsJsonObject();
HttpSession session = req.getSession(false);
if (session == null) {
return false;
}
AuthData authData = new AuthData();
authData.setClientId(clientId);
authData.setClientSecret(clientSecret);
authData.setEncodedClientApp(encodedClientApp);
authData.setAccessToken(jTokenResultAsJsonObject.get("access_token").getAsString());
authData.setRefreshToken(jTokenResultAsJsonObject.get("refresh_token").getAsString());
authData.setScope(jTokenResultAsJsonObject.get("scope").getAsString());
session.setAttribute(HandlerConstants.SESSION_AUTH_DATA_KEY, authData);
return true;
}
} }
return false; return false;
} catch (IOException e) { } catch (IOException e) {
@ -170,19 +203,18 @@ public class LoginHandler extends HttpServlet {
* Define username and password static parameters. * Define username and password static parameters.
*/ */
private static void validateLoginRequest(HttpServletRequest req) throws LoginException { private static void validateLoginRequest(HttpServletRequest req) throws LoginException {
String iotsCorePort = System.getProperty("iot.core.https.port"); String iotsCorePort = System.getProperty(HandlerConstants.IOT_CORE_HTTPS_PORT_ENV_VAR);
if (HandlerConstants.HTTP_PROTOCOL.equals(req.getScheme())) { if (HandlerConstants.HTTP_PROTOCOL.equals(req.getScheme())) {
iotsCorePort = System.getProperty("iot.core.http.port"); iotsCorePort = System.getProperty(HandlerConstants.IOT_CORE_HTTP_PORT_ENV_VAR);
} }
username = req.getParameter("username"); username = req.getParameter("username");
password = req.getParameter("password"); password = req.getParameter("password");
gatewayUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty("iot.gateway.host") gatewayUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty(HandlerConstants.IOT_GW_HOST_ENV_VAR)
+ HandlerConstants.COLON + HandlerUtil.getGatewayPort(req.getScheme()); + HandlerConstants.COLON + HandlerUtil.getGatewayPort(req.getScheme());
uiConfigUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty("iot.core.host") uiConfigUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty(HandlerConstants.IOT_CORE_HOST_ENV_VAR)
+ HandlerConstants.COLON + iotsCorePort + HandlerConstants.UI_CONFIG_ENDPOINT; + HandlerConstants.COLON + iotsCorePort + HandlerConstants.UI_CONFIG_ENDPOINT;
keyManagerUrl = HandlerConstants.HTTPS_PROTOCOL + HandlerConstants.SCHEME_SEPARATOR + iotsCoreUrl = HandlerConstants.HTTPS_PROTOCOL + HandlerConstants.SCHEME_SEPARATOR +
System.getProperty("iot.keymanager.host") + HandlerConstants.COLON System.getProperty(HandlerConstants.IOT_CORE_HOST_ENV_VAR) + HandlerConstants.COLON + iotsCorePort;
+ System.getProperty("iot.keymanager.https.port");
if (username == null || password == null) { if (username == null || password == null) {
String msg = "Invalid login request. Username or Password is not received for login request."; String msg = "Invalid login request. Username or Password is not received for login request.";
log.error(msg); log.error(msg);
@ -199,7 +231,7 @@ public class LoginHandler extends HttpServlet {
* @throws IOException IO exception throws if an error occurred when invoking token endpoint * @throws IOException IO exception throws if an error occurred when invoking token endpoint
*/ */
private ProxyResponse getTokenResult(String encodedClientApp, JsonArray scopes) throws IOException { private ProxyResponse getTokenResult(String encodedClientApp, JsonArray scopes) throws IOException {
HttpPost tokenEndpoint = new HttpPost(keyManagerUrl + HandlerConstants.TOKEN_ENDPOINT); HttpPost tokenEndpoint = new HttpPost(iotsCoreUrl+ HandlerConstants.TOKEN_ENDPOINT);
tokenEndpoint.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC + encodedClientApp); tokenEndpoint.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC + encodedClientApp);
tokenEndpoint.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED.toString()); tokenEndpoint.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED.toString());
String scopeString = HandlerUtil.getScopeString(scopes); String scopeString = HandlerUtil.getScopeString(scopes);

View File

@ -241,7 +241,7 @@ public class OTPInvokerHandler extends HttpServlet {
private static boolean validateRequest(HttpServletRequest req, HttpServletResponse resp) private static boolean validateRequest(HttpServletRequest req, HttpServletResponse resp)
throws IOException { throws IOException {
String schema = req.getScheme(); String schema = req.getScheme();
apiEndpoint = schema + HandlerConstants.SCHEME_SEPARATOR + System.getProperty("iot.core.host") apiEndpoint = schema + HandlerConstants.SCHEME_SEPARATOR + System.getProperty(HandlerConstants.IOT_CORE_HOST_ENV_VAR)
+ HandlerConstants.COLON + HandlerUtil.getCorePort(schema); + HandlerConstants.COLON + HandlerUtil.getCorePort(schema);
if (StringUtils.isBlank(req.getHeader(HandlerConstants.OTP_HEADER))) { if (StringUtils.isBlank(req.getHeader(HandlerConstants.OTP_HEADER))) {

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.ui.request.interceptor;
import io.entgra.ui.request.interceptor.beans.AuthData;
import io.entgra.ui.request.interceptor.beans.ProxyResponse;
import io.entgra.ui.request.interceptor.util.HandlerConstants;
import io.entgra.ui.request.interceptor.util.HandlerUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.json.JSONObject;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@MultipartConfig
@WebServlet("/login-user/scopes")
public class PermissionScopeHandler extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession httpSession = req.getSession(false);
if (httpSession == null) {
HandlerUtil.sendUnAuthorizeResponse(resp);
return;
}
AuthData authData = (AuthData) httpSession.getAttribute(HandlerConstants.SESSION_AUTH_DATA_KEY);
if (authData == null) {
HandlerUtil.sendUnAuthorizeResponse(resp);
return;
}
if (!StringUtils.isEmpty(authData.getScope())) {
ProxyResponse proxyResponse = new ProxyResponse();
JSONObject jsonObject = new JSONObject();
jsonObject.put(HandlerConstants.USER_SCOPES, authData.getScope());
proxyResponse.setCode(HttpStatus.SC_OK);
proxyResponse.setData(jsonObject.toString());
HandlerUtil.handleSuccess(resp, proxyResponse);
}
HandlerUtil.handleError(resp, null);
}
}

View File

@ -27,6 +27,7 @@ import io.entgra.ui.request.interceptor.util.HandlerUtil;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpHeaders; import org.apache.http.HttpHeaders;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType; import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity; import org.apache.http.entity.StringEntity;
@ -50,21 +51,18 @@ public class SsoLoginCallbackHandler extends HttpServlet {
String code = req.getParameter("code"); String code = req.getParameter("code");
HttpSession session = req.getSession(false); HttpSession session = req.getSession(false);
String scope = session.getAttribute("scope").toString(); String scope = session.getAttribute("scope").toString();
String iotsCorePort = System.getProperty("iot.core.https.port"); String iotsCorePort = System.getProperty(HandlerConstants.IOT_CORE_HTTPS_PORT_ENV_VAR);
if (HandlerConstants.HTTP_PROTOCOL.equals(req.getScheme())) { if (HandlerConstants.HTTP_PROTOCOL.equals(req.getScheme())) {
iotsCorePort = System.getProperty("iot.core.http.port"); iotsCorePort = System.getProperty(HandlerConstants.IOT_CORE_HTTP_PORT_ENV_VAR);
} }
String gatewayUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty("iot.gateway.host") String gatewayUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty(HandlerConstants.IOT_GW_HOST_ENV_VAR)
+ HandlerConstants.COLON + HandlerUtil.getGatewayPort(req.getScheme()); + HandlerConstants.COLON + HandlerUtil.getGatewayPort(req.getScheme());
String iotsCoreUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty("iot.core.host") String iotsCoreUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty(HandlerConstants.IOT_CORE_HOST_ENV_VAR)
+ HandlerConstants.COLON + iotsCorePort; + HandlerConstants.COLON + iotsCorePort;
String keyManagerUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR
+ System.getProperty("iot.keymanager.host") + HandlerConstants.COLON
+ System.getProperty("iot.keymanager.https.port");
HttpPost tokenEndpoint = new HttpPost(keyManagerUrl + HandlerConstants.TOKEN_ENDPOINT); HttpPost tokenEndpoint = new HttpPost(iotsCoreUrl + HandlerConstants.TOKEN_ENDPOINT);
tokenEndpoint.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC + session.getAttribute("encodedClientApp")); tokenEndpoint.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC + session.getAttribute("encodedClientApp"));
tokenEndpoint.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED.toString()); tokenEndpoint.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED.toString());

View File

@ -23,6 +23,9 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException; import com.google.gson.JsonSyntaxException;
import io.entgra.ui.request.interceptor.cache.LoginCacheManager;
import io.entgra.ui.request.interceptor.cache.OAuthApp;
import io.entgra.ui.request.interceptor.cache.OAuthAppCacheKey;
import io.entgra.ui.request.interceptor.util.HandlerConstants; import io.entgra.ui.request.interceptor.util.HandlerConstants;
import io.entgra.ui.request.interceptor.util.HandlerUtil; import io.entgra.ui.request.interceptor.util.HandlerUtil;
import org.apache.commons.lang.text.StrSubstitutor; import org.apache.commons.lang.text.StrSubstitutor;
@ -69,28 +72,65 @@ public class SsoLoginHandler extends HttpServlet {
private static String adminPassword; private static String adminPassword;
private static String gatewayUrl; private static String gatewayUrl;
private static String iotsCoreUrl; private static String iotsCoreUrl;
private static String keyManagerUrl;
private static String encodedAdminCredentials; private static String encodedAdminCredentials;
private static String encodedClientApp; private static String encodedClientApp;
private static String applicationId; private static String applicationId;
private static String applicationName;
private static String baseContextPath; private static String baseContextPath;
private JsonObject uiConfigJsonObject; private JsonObject uiConfigJsonObject;
private HttpSession httpSession; private HttpSession httpSession;
private LoginCacheManager loginCacheManager;
private OAuthApp oAuthApp;
@Override @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
dynamicClientRegistration(req, resp); try {
String clientId = httpSession.getAttribute("clientId").toString(); httpSession = req.getSession(false);
JsonArray scopesSsoJson = uiConfigJsonObject.get("scopes").getAsJsonArray();
String scopesSsoString = HandlerUtil.getScopeString(scopesSsoJson); if (httpSession != null) {
String loginCallbackUrl = iotsCoreUrl + baseContextPath + HandlerConstants.SSO_LOGIN_CALLBACK; httpSession.invalidate();
resp.sendRedirect(iotsCoreUrl + HandlerConstants.AUTHORIZATION_ENDPOINT + }
"?response_type=code" +
"&client_id=" + clientId + httpSession = req.getSession(true);
"&state=" + initializeAdminCredentials();
"&scope=openid " + scopesSsoString + baseContextPath = req.getContextPath();
"&redirect_uri=" + loginCallbackUrl); applicationName = baseContextPath.substring(1, baseContextPath.indexOf("-ui-request-handler"));
// Check if oauth app cache is available
loginCacheManager = new LoginCacheManager();
loginCacheManager.initializeCacheManager();
oAuthApp = loginCacheManager.getOAuthAppCache(
new OAuthAppCacheKey(applicationName, adminUsername)
);
if (oAuthApp == null) {
dynamicClientRegistration(req, resp);
}
String clientId = oAuthApp.getClientId();
JsonArray scopesSsoJson = uiConfigJsonObject.get("scopes").getAsJsonArray();
String scopesSsoString = HandlerUtil.getScopeString(scopesSsoJson);
String loginCallbackUrl = iotsCoreUrl + baseContextPath + HandlerConstants.SSO_LOGIN_CALLBACK;
persistAuthSessionData(req, oAuthApp.getClientId(), oAuthApp.getClientSecret(),
oAuthApp.getEncodedClientApp(), scopesSsoString);
resp.sendRedirect(iotsCoreUrl + HandlerConstants.AUTHORIZATION_ENDPOINT +
"?response_type=code" +
"&client_id=" + clientId +
"&state=" +
"&scope=openid " + scopesSsoString +
"&redirect_uri=" + loginCallbackUrl);
} catch (IOException e) {
log.error("Error occurred while sending the response into the socket. ", e);
} catch (JsonSyntaxException e) {
log.error("Error occurred while parsing the response. ", e);
} catch (ParserConfigurationException e) {
log.error("Error while creating the document builder.");
} catch (SAXException e) {
log.error("Error while parsing xml file.", e);
}
} }
/*** /***
@ -102,40 +142,19 @@ public class SsoLoginHandler extends HttpServlet {
*/ */
private void dynamicClientRegistration(HttpServletRequest req, HttpServletResponse resp) { private void dynamicClientRegistration(HttpServletRequest req, HttpServletResponse resp) {
try { try {
File userMgtConf = new File("repository/conf/user-mgt.xml"); String iotsCorePort = System.getProperty(HandlerConstants.IOT_CORE_HTTPS_PORT_ENV_VAR);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(userMgtConf);
adminUsername = doc.getElementsByTagName("UserName").item(0).getTextContent();
adminPassword = doc.getElementsByTagName("Password").item(0).getTextContent();
baseContextPath = req.getContextPath();
String applicationName = baseContextPath.substring(1, baseContextPath.indexOf("-ui-request-handler"));
String iotsCorePort = System.getProperty("iot.core.https.port");
if (HandlerConstants.HTTP_PROTOCOL.equals(req.getScheme())) { if (HandlerConstants.HTTP_PROTOCOL.equals(req.getScheme())) {
iotsCorePort = System.getProperty("iot.core.http.port"); iotsCorePort = System.getProperty(HandlerConstants.IOT_CORE_HTTP_PORT_ENV_VAR);
} }
gatewayUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty("iot.gateway.host") gatewayUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty(HandlerConstants.IOT_GW_HOST_ENV_VAR)
+ HandlerConstants.COLON + HandlerUtil.getGatewayPort(req.getScheme()); + HandlerConstants.COLON + HandlerUtil.getGatewayPort(req.getScheme());
iotsCoreUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty("iot.core.host") iotsCoreUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty(HandlerConstants.IOT_CORE_HOST_ENV_VAR)
+ HandlerConstants.COLON + iotsCorePort; + HandlerConstants.COLON + iotsCorePort;
String uiConfigUrl = iotsCoreUrl + HandlerConstants.UI_CONFIG_ENDPOINT; String uiConfigUrl = iotsCoreUrl + HandlerConstants.UI_CONFIG_ENDPOINT;
keyManagerUrl = HandlerConstants.HTTPS_PROTOCOL + HandlerConstants.SCHEME_SEPARATOR +
System.getProperty("iot.keymanager.host") + HandlerConstants.COLON
+ System.getProperty("iot.keymanager.https.port");
httpSession = req.getSession(false);
if (httpSession != null) {
httpSession.invalidate();
}
httpSession = req.getSession(true);
uiConfigJsonObject = HandlerUtil.getUIConfigAndPersistInSession(uiConfigUrl, gatewayUrl, httpSession, resp); uiConfigJsonObject = HandlerUtil.getUIConfigAndPersistInSession(uiConfigUrl, gatewayUrl, httpSession, resp);
JsonArray tags = uiConfigJsonObject.get("appRegistration").getAsJsonObject().get("tags").getAsJsonArray(); JsonArray tags = uiConfigJsonObject.get("appRegistration").getAsJsonObject().get("tags").getAsJsonArray();
JsonArray scopes = uiConfigJsonObject.get("scopes").getAsJsonArray(); JsonArray scopes = uiConfigJsonObject.get("scopes").getAsJsonArray();
@ -157,19 +176,22 @@ public class SsoLoginHandler extends HttpServlet {
if (clientAppResponse.getCode() == HttpStatus.SC_CREATED) { if (clientAppResponse.getCode() == HttpStatus.SC_CREATED) {
JsonParser jsonParser = new JsonParser(); JsonParser jsonParser = new JsonParser();
JsonElement jClientAppResult = jsonParser.parse(clientAppResponse.getData()); JsonElement jClientAppResult = jsonParser.parse(clientAppResponse.getData());
String clientId = null;
String clientSecret = null;
if (jClientAppResult.isJsonObject()) { if (jClientAppResult.isJsonObject()) {
JsonObject jClientAppResultAsJsonObject = jClientAppResult.getAsJsonObject(); JsonObject jClientAppResultAsJsonObject = jClientAppResult.getAsJsonObject();
String clientId = jClientAppResultAsJsonObject.get("client_id").getAsString(); clientId = jClientAppResultAsJsonObject.get("client_id").getAsString();
String clientSecret = jClientAppResultAsJsonObject.get("client_secret").getAsString(); clientSecret = jClientAppResultAsJsonObject.get("client_secret").getAsString();
encodedClientApp = Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes()); encodedClientApp = Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes());
String redirectUrl = req.getParameter("redirect"); String scopesString = HandlerUtil.getScopeString(scopes);
httpSession = req.getSession(false); persistAuthSessionData(req, clientId, clientSecret, encodedClientApp, scopesString);
httpSession.setAttribute("clientId", clientId);
httpSession.setAttribute("clientSecret", clientSecret);
httpSession.setAttribute("encodedClientApp", encodedClientApp);
httpSession.setAttribute("scope", HandlerUtil.getScopeString(scopes));
httpSession.setAttribute("redirectUrl", redirectUrl);
} }
// cache the oauth app credentials
OAuthAppCacheKey oAuthAppCacheKey = new OAuthAppCacheKey(applicationName, adminUsername);
oAuthApp = new OAuthApp(applicationName, adminUsername, clientId, clientSecret, encodedClientApp);
loginCacheManager.addOAuthAppToCache(oAuthAppCacheKey, oAuthApp);
} }
// Get the details of the registered application // Get the details of the registered application
@ -225,7 +247,6 @@ public class SsoLoginHandler extends HttpServlet {
if (updateApplicationGrantTypesEndpointResponse.getCode() == HttpStatus.SC_OK) { if (updateApplicationGrantTypesEndpointResponse.getCode() == HttpStatus.SC_OK) {
return; return;
} }
HandlerUtil.handleError(resp, null); HandlerUtil.handleError(resp, null);
} catch (IOException e) { } catch (IOException e) {
log.error("Error occurred while sending the response into the socket. ", e); log.error("Error occurred while sending the response into the socket. ", e);
@ -233,11 +254,48 @@ public class SsoLoginHandler extends HttpServlet {
log.error("Error occurred while parsing the response. ", e); log.error("Error occurred while parsing the response. ", e);
} catch (ParserConfigurationException e) { } catch (ParserConfigurationException e) {
log.error("Error while creating the document builder."); log.error("Error while creating the document builder.");
} catch ( SAXException e) { } catch (SAXException e) {
log.error("Error while parsing xml file.", e); log.error("Error while parsing xml file.", e);
} }
} }
/**
* Initialize the admin credential variables
*
* @throws ParserConfigurationException - Throws when error occur during initializing the document builder
* @throws IOException - Throws when error occur during document parsing
* @throws SAXException - Throws when error occur during document parsing
*/
private void initializeAdminCredentials() throws ParserConfigurationException, IOException, SAXException {
File userMgtConf = new File("repository/conf/user-mgt.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(userMgtConf);
adminUsername = doc.getElementsByTagName("UserName").item(0).getTextContent();
adminPassword = doc.getElementsByTagName("Password").item(0).getTextContent();
}
/**
* Persist the Auth data inside the session
*
* @param req - Http Servlet request
* @param clientId - Client ID of the SP
* @param clientSecret - Client secret of the SP
* @param encodedClientApp - Base64 encoded clientId:clientSecret.
* @param scopes - User scopes
*/
private void persistAuthSessionData(HttpServletRequest req, String clientId, String clientSecret,
String encodedClientApp, String scopes) {
httpSession = req.getSession(false);
httpSession.setAttribute("clientId", clientId);
httpSession.setAttribute("clientSecret", clientSecret);
httpSession.setAttribute("encodedClientApp", encodedClientApp);
httpSession.setAttribute("scope", scopes);
httpSession.setAttribute("redirectUrl", req.getParameter("redirect"));
}
/*** /***
* Generates payload for application grant_type update payload * Generates payload for application grant_type update payload
* *
@ -266,7 +324,7 @@ public class SsoLoginHandler extends HttpServlet {
* @throws IOException IO exception throws if an error occurred when invoking token endpoint * @throws IOException IO exception throws if an error occurred when invoking token endpoint
*/ */
private ProxyResponse getTokenResult(String encodedClientApp) throws IOException { private ProxyResponse getTokenResult(String encodedClientApp) throws IOException {
HttpPost tokenEndpoint = new HttpPost(keyManagerUrl + HandlerConstants.TOKEN_ENDPOINT); HttpPost tokenEndpoint = new HttpPost(iotsCoreUrl + HandlerConstants.TOKEN_ENDPOINT);
tokenEndpoint.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC + encodedClientApp); tokenEndpoint.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC + encodedClientApp);
tokenEndpoint.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED.toString()); tokenEndpoint.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED.toString());
@ -315,7 +373,7 @@ public class SsoLoginHandler extends HttpServlet {
*/ */
private void updateSaasApp(String appName) throws ParserConfigurationException, IOException, SAXException { private void updateSaasApp(String appName) throws ParserConfigurationException, IOException, SAXException {
File getAppRequestXmlFile = new File(HandlerConstants.PAYLOADS_DIR + "/get-app-request.xml"); File getAppRequestXmlFile = new File(HandlerConstants.PAYLOADS_DIR + "/get-app-request.xml");
String identityAppMgtUrl = iotsCoreUrl + HandlerConstants.IDENTITY_APP_MGT_ENDPOINT;; String identityAppMgtUrl = iotsCoreUrl + HandlerConstants.IDENTITY_APP_MGT_ENDPOINT;
HttpPost getApplicationEndpoint = new HttpPost(identityAppMgtUrl); HttpPost getApplicationEndpoint = new HttpPost(identityAppMgtUrl);
getApplicationEndpoint.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC + getApplicationEndpoint.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC +

View File

@ -55,7 +55,8 @@ public class UserHandler extends HttpServlet {
protected void doPost(HttpServletRequest req, HttpServletResponse resp) { protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
try { try {
String serverUrl = String serverUrl =
req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty("iot.core.host") req.getScheme() + HandlerConstants.SCHEME_SEPARATOR +
System.getProperty(HandlerConstants.IOT_CORE_HOST_ENV_VAR)
+ HandlerConstants.COLON + HandlerUtil.getCorePort(req.getScheme()); + HandlerConstants.COLON + HandlerUtil.getCorePort(req.getScheme());
HttpSession httpSession = req.getSession(false); HttpSession httpSession = req.getSession(false);
if (httpSession == null) { if (httpSession == null) {
@ -71,32 +72,31 @@ public class UserHandler extends HttpServlet {
String accessToken = authData.getAccessToken(); String accessToken = authData.getAccessToken();
HttpPost introspectionEndpoint = new HttpPost(serverUrl + HandlerConstants.INTROSPECT_ENDPOINT); HttpPost tokenEndpoint = new HttpPost(serverUrl + HandlerConstants.INTROSPECT_ENDPOINT);
introspectionEndpoint.setHeader(HttpHeaders.CONTENT_TYPE, tokenEndpoint.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED.toString());
ContentType.APPLICATION_FORM_URLENCODED.toString());
DeviceManagementConfig dmc = DeviceConfigurationManager.getInstance().getDeviceManagementConfig(); DeviceManagementConfig dmc = DeviceConfigurationManager.getInstance().getDeviceManagementConfig();
String username = dmc.getKeyManagerConfigurations().getAdminUsername(); String adminUsername = dmc.getKeyManagerConfigurations().getAdminUsername();
String password = dmc.getKeyManagerConfigurations().getAdminPassword(); String adminPassword = dmc.getKeyManagerConfigurations().getAdminPassword();
introspectionEndpoint.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC + Base64.getEncoder() tokenEndpoint.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC + Base64.getEncoder()
.encodeToString((username + HandlerConstants.COLON + password).getBytes())); .encodeToString((adminUsername + HandlerConstants.COLON + adminPassword).getBytes()));
StringEntity introspectionPayload = new StringEntity("token=" + accessToken, StringEntity tokenEPPayload = new StringEntity("token=" + accessToken,
ContentType.APPLICATION_FORM_URLENCODED); ContentType.APPLICATION_FORM_URLENCODED);
introspectionEndpoint.setEntity(introspectionPayload); tokenEndpoint.setEntity(tokenEPPayload);
ProxyResponse introspectionStatus = HandlerUtil.execute(introspectionEndpoint); ProxyResponse tokenStatus = HandlerUtil.execute(tokenEndpoint);
if (introspectionStatus.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) { if (tokenStatus.getExecutorResponse().contains(HandlerConstants.EXECUTOR_EXCEPTION_PREFIX)) {
log.error("Error occurred while invoking the API to get token status."); log.error("Error occurred while invoking the API to get token status.");
HandlerUtil.handleError(resp, introspectionStatus); HandlerUtil.handleError(resp, tokenStatus);
return; return;
} }
String introspectionData = introspectionStatus.getData(); String tokenData = tokenStatus.getData();
if (introspectionData == null) { if (tokenData == null) {
log.error("Invalid token data is received."); log.error("Invalid token data is received.");
HandlerUtil.handleError(resp, introspectionStatus); HandlerUtil.handleError(resp, tokenStatus);
return; return;
} }
JsonParser jsonParser = new JsonParser(); JsonParser jsonParser = new JsonParser();
JsonElement jTokenResult = jsonParser.parse(introspectionData); JsonElement jTokenResult = jsonParser.parse(tokenData);
if (jTokenResult.isJsonObject()) { if (jTokenResult.isJsonObject()) {
JsonObject jTokenResultAsJsonObject = jTokenResult.getAsJsonObject(); JsonObject jTokenResultAsJsonObject = jTokenResult.getAsJsonObject();
if (!jTokenResultAsJsonObject.get("active").getAsBoolean()) { if (!jTokenResultAsJsonObject.get("active").getAsBoolean()) {

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2021, 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.ui.request.interceptor.cache;
import io.entgra.ui.request.interceptor.util.HandlerConstants;
import javax.cache.Cache;
import javax.cache.CacheManager;
import javax.cache.Caching;
/**
* Contains necessary functions to manage oAuth app cache during login handling
*/
public class LoginCacheManager {
private CacheManager cacheManager = null;
private Cache<OAuthAppCacheKey, OAuthApp> cache = null;
/**
* Initialize the cache manager if it is not already initialized
*/
public void initializeCacheManager() {
cacheManager = Caching.getCacheManagerFactory().getCacheManager(HandlerConstants.LOGIN_CACHE);
}
/**
* Persists OAuth app cache if it is not already persisted
*
* @param oAuthAppCacheKey - The identifier key of the cache
* @param oAuthApp - The value of the cache which contains OAuth app data
*/
public void addOAuthAppToCache(OAuthAppCacheKey oAuthAppCacheKey, OAuthApp oAuthApp) {
cache = cacheManager.getCache(HandlerConstants.LOGIN_CACHE);
cache.put(oAuthAppCacheKey, oAuthApp);
}
/**
* Retrieves the OAuth app cache
*
* @param oAuthAppCacheKey - The key to identify the cache
* @return - Returns OAuthApp object
*/
public OAuthApp getOAuthAppCache(OAuthAppCacheKey oAuthAppCacheKey) {
cache = cacheManager.getCache(HandlerConstants.LOGIN_CACHE);
return cache.get(oAuthAppCacheKey);
}
}

View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 2021, 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.ui.request.interceptor.cache;
/**
* The data object used for Login Cache
*/
public class OAuthApp {
private String appName;
private String appOwner;
private String clientId;
private String clientSecret;
private String encodedClientApp;
public OAuthApp(String appName, String appOwner, String clientId, String clientSecret, String encodedClientApp) {
this.appName = appName;
this.appOwner = appOwner;
this.clientId = clientId;
this.clientSecret = clientSecret;
this.encodedClientApp = encodedClientApp;
}
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public String getAppOwner() {
return appOwner;
}
public void setAppOwner(String appOwner) {
this.appOwner = appOwner;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientSecret() {
return clientSecret;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public String getEncodedClientApp() {
return encodedClientApp;
}
public void setEncodedClientApp(String encodedClientApp) {
this.encodedClientApp = encodedClientApp;
}
}

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2021, 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.ui.request.interceptor.cache;
import java.util.Objects;
/**
* The key object used for Login Cache
*/
public class OAuthAppCacheKey {
private String appName;
private String appOwner;
private volatile int hashCode;
public OAuthAppCacheKey(String appName, String appOwner) {
this.appName = appName;
this.appOwner = appOwner;
}
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public String getAppOwner() {
return appOwner;
}
public void setAppOwner(String appOwner) {
this.appOwner = appOwner;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj instanceof OAuthAppCacheKey) {
final OAuthAppCacheKey other = (OAuthAppCacheKey) obj;
String thisId = this.appName + "-" + this.appOwner;
String otherId = other.appName + "-" + other.appOwner;
return thisId.equals(otherId);
}
return false;
}
@Override
public int hashCode() {
if (hashCode == 0) {
hashCode = Objects.hash(appName, appOwner);
}
return hashCode;
}
}

View File

@ -55,6 +55,7 @@ public class HandlerConstants {
public static final String PASSWORD_GRANT_TYPE = "password"; public static final String PASSWORD_GRANT_TYPE = "password";
public static final String JWT_BEARER_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer"; public static final String JWT_BEARER_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer";
public static final String PRODUCTION_KEY = "PRODUCTION"; public static final String PRODUCTION_KEY = "PRODUCTION";
public static final String LOGIN_CACHE = "LOGIN_CACHE";
public static final String SCHEME_SEPARATOR = "://"; public static final String SCHEME_SEPARATOR = "://";
public static final String COLON = ":"; public static final String COLON = ":";
@ -75,6 +76,10 @@ public class HandlerConstants {
public static final String REMOTE_SESSION_CONTEXT = "/remote/session/clients"; public static final String REMOTE_SESSION_CONTEXT = "/remote/session/clients";
public static final String IOT_CORE_HOST_ENV_VAR = "iot.core.host"; public static final String IOT_CORE_HOST_ENV_VAR = "iot.core.host";
public static final String IOT_CORE_PORT_ENV_VAR = "iot.core.https.port"; public static final String IOT_CORE_HTTP_PORT_ENV_VAR = "iot.core.http.port";
public static final String IOT_CORE_HTTPS_PORT_ENV_VAR = "iot.core.https.port";
public static final String IOT_GW_HOST_ENV_VAR = "iot.gateway.host";
public static final String IOT_GW_HTTP_PORT_ENV_VAR = "iot.gateway.http.port";
public static final String IOT_GW_HTTPS_PORT_ENV_VAR = "iot.gateway.https.port";
public static final String USER_SCOPES = "user-scopes";
} }

View File

@ -226,9 +226,9 @@ public class HandlerUtil {
* @return {@link String} gateway port * @return {@link String} gateway port
*/ */
public static String getGatewayPort(String scheme) { public static String getGatewayPort(String scheme) {
String gatewayPort = System.getProperty("iot.gateway.https.port"); String gatewayPort = System.getProperty(HandlerConstants.IOT_GW_HTTPS_PORT_ENV_VAR);
if (HandlerConstants.HTTP_PROTOCOL.equals(scheme)) { if (HandlerConstants.HTTP_PROTOCOL.equals(scheme)) {
gatewayPort = System.getProperty("iot.gateway.http.port"); gatewayPort = System.getProperty(HandlerConstants.IOT_GW_HTTP_PORT_ENV_VAR);
} }
return gatewayPort; return gatewayPort;
} }
@ -240,9 +240,9 @@ public class HandlerUtil {
* @return {@link String} gateway port * @return {@link String} gateway port
*/ */
public static String getCorePort(String scheme) { public static String getCorePort(String scheme) {
String productCorePort = System.getProperty("iot.core.https.port"); String productCorePort = System.getProperty(HandlerConstants.IOT_CORE_HTTPS_PORT_ENV_VAR);
if (HandlerConstants.HTTP_PROTOCOL.equals(scheme)) { if (HandlerConstants.HTTP_PROTOCOL.equals(scheme)) {
productCorePort = System.getProperty("iot.core.https.por"); productCorePort = System.getProperty(HandlerConstants.IOT_CORE_HTTP_PORT_ENV_VAR);
} }
return productCorePort; return productCorePort;
} }

View File

@ -269,7 +269,7 @@ CREATE TABLE IF NOT EXISTS AP_SCHEDULED_SUBSCRIPTION(
APPLICATION_UUID VARCHAR(36) NOT NULL, APPLICATION_UUID VARCHAR(36) NOT NULL,
SUBSCRIBER_LIST LONGVARCHAR NOT NULL, SUBSCRIBER_LIST LONGVARCHAR NOT NULL,
STATUS VARCHAR(15) NOT NULL, STATUS VARCHAR(15) NOT NULL,
SCHEDULED_AT TIMESTAMP NOT NULL, SCHEDULED_AT BIGINT NOT NULL,
SCHEDULED_BY VARCHAR(100) NOT NULL, SCHEDULED_BY VARCHAR(100) NOT NULL,
SCHEDULED_TIMESTAMP TIMESTAMP NOT NULL, SCHEDULED_TIMESTAMP TIMESTAMP NOT NULL,
DELETED BOOLEAN, DELETED BOOLEAN,

View File

@ -270,7 +270,7 @@ CREATE TABLE AP_SCHEDULED_SUBSCRIPTION(
APPLICATION_UUID VARCHAR(200) NOT NULL, APPLICATION_UUID VARCHAR(200) NOT NULL,
SUBSCRIBER_LIST VARCHAR(MAX) NOT NULL, SUBSCRIBER_LIST VARCHAR(MAX) NOT NULL,
STATUS VARCHAR(15) NOT NULL, STATUS VARCHAR(15) NOT NULL,
SCHEDULED_AT DATETIME2(0) NOT NULL, SCHEDULED_AT BIGINT NOT NULL,
SCHEDULED_BY VARCHAR(100) NOT NULL, SCHEDULED_BY VARCHAR(100) NOT NULL,
SCHEDULED_TIMESTAMP DATETIME2(0) NOT NULL, SCHEDULED_TIMESTAMP DATETIME2(0) NOT NULL,
DELETED BIT, DELETED BIT,

View File

@ -269,7 +269,7 @@ CREATE TABLE IF NOT EXISTS AP_SCHEDULED_SUBSCRIPTION(
APPLICATION_UUID VARCHAR(36) NOT NULL, APPLICATION_UUID VARCHAR(36) NOT NULL,
SUBSCRIBER_LIST TEXT NOT NULL, SUBSCRIBER_LIST TEXT NOT NULL,
STATUS VARCHAR(15) NOT NULL, STATUS VARCHAR(15) NOT NULL,
SCHEDULED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, SCHEDULED_AT BIGINT NOT NULL,
SCHEDULED_BY VARCHAR(100) NOT NULL, SCHEDULED_BY VARCHAR(100) NOT NULL,
SCHEDULED_TIMESTAMP TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, SCHEDULED_TIMESTAMP TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
DELETED BOOLEAN, DELETED BOOLEAN,

View File

@ -372,7 +372,7 @@ CREATE TABLE AP_SCHEDULED_SUBSCRIPTION (
APPLICATION_UUID VARCHAR(36) NOT NULL, APPLICATION_UUID VARCHAR(36) NOT NULL,
SUBSCRIBER_LIST VARCHAR(4000) NOT NULL, SUBSCRIBER_LIST VARCHAR(4000) NOT NULL,
STATUS VARCHAR(15) NOT NULL, STATUS VARCHAR(15) NOT NULL,
SCHEDULED_AT TIMESTAMP NOT NULL, SCHEDULED_AT NUMBER(19) NOT NULL,
SCHEDULED_BY VARCHAR(100) NOT NULL, SCHEDULED_BY VARCHAR(100) NOT NULL,
SCHEDULED_TIMESTAMP TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, SCHEDULED_TIMESTAMP TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
DELETED NUMBER(1) NOT_NULL DEFAULT 0, DELETED NUMBER(1) NOT_NULL DEFAULT 0,

View File

@ -299,7 +299,7 @@ CREATE TABLE IF NOT EXISTS AP_SCHEDULED_SUBSCRIPTION(
APPLICATION_UUID VARCHAR(36) NOT NULL, APPLICATION_UUID VARCHAR(36) NOT NULL,
SUBSCRIBER_LIST TEXT NOT NULL, SUBSCRIBER_LIST TEXT NOT NULL,
STATUS VARCHAR(15) NOT NULL, STATUS VARCHAR(15) NOT NULL,
SCHEDULED_AT TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP NOT NULL, SCHEDULED_AT BIGINT NOT NULL,
SCHEDULED_BY VARCHAR(100) NOT NULL, SCHEDULED_BY VARCHAR(100) NOT NULL,
SCHEDULED_TIMESTAMP TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP NOT NULL, SCHEDULED_TIMESTAMP TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP NOT NULL,
DELETED BOOLEAN, DELETED BOOLEAN,

View File

@ -2258,6 +2258,8 @@
<imp.package.version.osgi.framework>[1.6.0, 2.0.0)</imp.package.version.osgi.framework> <imp.package.version.osgi.framework>[1.6.0, 2.0.0)</imp.package.version.osgi.framework>
<imp.package.version.osgi.service>[1.2.0,1.3.0)</imp.package.version.osgi.service> <imp.package.version.osgi.service>[1.2.0,1.3.0)</imp.package.version.osgi.service>
<maven.test.skip>true</maven.test.skip>
</properties> </properties>
<distributionManagement> <distributionManagement>