mirror of
https://repository.entgra.net/community/device-mgt-core.git
synced 2025-10-06 02:01:45 +00:00
Fix merge conflicts
This commit is contained in:
commit
298c58e8b8
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.common;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
public class BasePaginatedResult {
|
||||
|
||||
@ApiModelProperty(
|
||||
value = "Number of total resources.",
|
||||
example = "1")
|
||||
@JsonProperty("count")
|
||||
private long count;
|
||||
|
||||
public long getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(long count) {
|
||||
this.count = count;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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.common;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
@ApiModel(value = "BasicUserInfo", description = "Basic user information and the roles of the user.")
|
||||
public class BasicUserInfo {
|
||||
|
||||
@ApiModelProperty(name = "username", value = "The login name of the user.", required = true )
|
||||
private String username;
|
||||
@ApiModelProperty(name = "firstname", value = "The first name of the user.", required = true )
|
||||
private String firstname;
|
||||
@ApiModelProperty(name = "lastname", value = "The last name of the user.", required = true )
|
||||
private String lastname;
|
||||
@ApiModelProperty(name = "emailAddress", value = "The email address of the user.", required = true )
|
||||
private String emailAddress;
|
||||
@ApiModelProperty(name = "createdDate", value = "User creation date." )
|
||||
private String createdDate;
|
||||
@ApiModelProperty(name = "modifiedDate", value = "User modifiedDate date." )
|
||||
private String modifiedDate;
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getFirstname() {
|
||||
return firstname;
|
||||
}
|
||||
|
||||
public void setFirstname(String firstname) {
|
||||
this.firstname = firstname;
|
||||
}
|
||||
|
||||
public String getLastname() {
|
||||
return lastname;
|
||||
}
|
||||
|
||||
public void setLastname(String lastname) {
|
||||
this.lastname = lastname;
|
||||
}
|
||||
|
||||
public String getEmailAddress() {
|
||||
return emailAddress;
|
||||
}
|
||||
|
||||
public void setEmailAddress(String emailAddress) {
|
||||
this.emailAddress = emailAddress;
|
||||
}
|
||||
|
||||
public String getCreatedDate() {
|
||||
return createdDate;
|
||||
}
|
||||
|
||||
public void setCreatedDate(String createdDate) {
|
||||
this.createdDate = createdDate;
|
||||
}
|
||||
|
||||
public String getModifiedDate() {
|
||||
return modifiedDate;
|
||||
}
|
||||
|
||||
public void setModifiedDate(String modifiedDate) {
|
||||
this.modifiedDate = modifiedDate;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.common;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ApiModel(value = "BasicUserInfoList", description = "This contains basic details of a set of users that matches " +
|
||||
"a given criteria as a collection")
|
||||
public class BasicUserInfoList extends BasePaginatedResult {
|
||||
|
||||
private List<BasicUserInfo> users = new ArrayList<>();
|
||||
|
||||
@ApiModelProperty(value = "List of devices returned")
|
||||
@JsonProperty("users")
|
||||
public List<BasicUserInfo> getList() {
|
||||
return users;
|
||||
}
|
||||
|
||||
public void setList(List<BasicUserInfo> users) {
|
||||
this.users = users;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("{\n");
|
||||
|
||||
sb.append(" count: ").append(getCount()).append(",\n");
|
||||
sb.append(" users: [").append(users).append("\n");
|
||||
sb.append("]}\n");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.common;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class DeviceGroupList extends BasePaginatedResult {
|
||||
|
||||
@ApiModelProperty(value = "List of device groups returned")
|
||||
@JsonProperty("groups")
|
||||
private List<?> deviceGroups = new ArrayList<>();
|
||||
|
||||
public List<?> getList() {
|
||||
return deviceGroups;
|
||||
}
|
||||
|
||||
public void setList(List<?> deviceGroups) {
|
||||
this.deviceGroups = deviceGroups;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("{\n");
|
||||
sb.append(" count: ").append(getCount()).append(",\n");
|
||||
sb.append(" groups: [").append(deviceGroups).append("\n");
|
||||
sb.append("]}\n");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.common;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import org.wso2.carbon.device.mgt.common.Device;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class DeviceList extends BasePaginatedResult {
|
||||
|
||||
private List<Device> devices = new ArrayList<>();
|
||||
|
||||
@ApiModelProperty(value = "List of devices returned")
|
||||
@JsonProperty("devices")
|
||||
public List<Device> getList() {
|
||||
return devices;
|
||||
}
|
||||
|
||||
public void setList(List<Device> devices) {
|
||||
this.devices = devices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("{\n");
|
||||
|
||||
sb.append(" count: ").append(getCount()).append(",\n");
|
||||
sb.append(" devices: [").append(devices).append("\n");
|
||||
sb.append("]}\n");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.common;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ApiModel(value = "Role List")
|
||||
public class RoleList extends BasePaginatedResult {
|
||||
|
||||
private List<?> roles;
|
||||
|
||||
@ApiModelProperty(value = "Returns the list of roles that match the offset and limit parameter values "
|
||||
+ "that were specified.")
|
||||
@JsonProperty("roles")
|
||||
|
||||
public List<?> getList() {
|
||||
return roles;
|
||||
}
|
||||
|
||||
public void setList(List<?> roles) {
|
||||
this.roles = roles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("{\n");
|
||||
sb.append(" count: ").append(getCount()).append(",\n");
|
||||
sb.append(" roles: [").append(roles).append("\n");
|
||||
sb.append("]}\n");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -23,6 +23,7 @@ import org.wso2.carbon.device.application.mgt.common.ExecutionStatus;
|
||||
import org.wso2.carbon.device.application.mgt.common.dto.ScheduledSubscriptionDTO;
|
||||
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.mgt.common.PaginationResult;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -83,4 +84,30 @@ public interface SubscriptionManager {
|
||||
* @throws SubscriptionManagementException if error occurred while updating the status of the subscription
|
||||
*/
|
||||
void updateScheduledSubscriptionStatus(int id, ExecutionStatus status) throws SubscriptionManagementException;
|
||||
|
||||
/***
|
||||
* 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 offsetValue offset value for get paginated request.
|
||||
* @param limitValue limit value for get paginated request.
|
||||
* @param status status of the devices.
|
||||
* @return deviceDetails - device details for given application release.
|
||||
* @throws {@link ApplicationManagementException} Exception of the application management
|
||||
*/
|
||||
PaginationResult getAppInstalledDevices(int offsetValue, int limitValue, String appUUID,
|
||||
String status) throws ApplicationManagementException;
|
||||
|
||||
/***
|
||||
* This method used to get category details.
|
||||
*
|
||||
* @param appUUID UUID of the application release.
|
||||
* @param subType subscription type of the application.
|
||||
* @param offsetValue offset value for get paginated request.
|
||||
* @param limitValue limit value for get paginated request.
|
||||
* @return {@link PaginationResult} pagination result of the category details.
|
||||
* @throws {@link ApplicationManagementException} Exception of the application management
|
||||
*/
|
||||
PaginationResult getAppInstalledCategories(int offsetValue, int limitValue, String appUUID,
|
||||
String subType) throws ApplicationManagementException;
|
||||
}
|
||||
|
||||
@ -168,6 +168,46 @@ public interface SubscriptionDAO {
|
||||
* @return {@link ScheduledSubscriptionDTO}
|
||||
* @throws ApplicationManagementDAOException if error occurred while retrieving the subscription
|
||||
*/
|
||||
ScheduledSubscriptionDTO getPendingScheduledSubscriptionByTaskName(String taskName)
|
||||
ScheduledSubscriptionDTO getPendingScheduledSubscriptionByTaskName(String taskName) throws ApplicationManagementDAOException;
|
||||
|
||||
/**
|
||||
* This method is used to get the details of users
|
||||
*
|
||||
* @param tenantId id of the current tenant
|
||||
* @param offsetValue offset value for get paginated result
|
||||
* @param limitValue limit value for get paginated result
|
||||
* @param appReleaseId id of the application release.
|
||||
* @return subscribedUsers - list of app subscribed users.
|
||||
* @throws {@link ApplicationManagementDAOException} if connections establishment fails.
|
||||
*/
|
||||
List<String> getAppSubscribedUsers(int offsetValue, int limitValue, int appReleaseId,
|
||||
int tenantId)
|
||||
throws ApplicationManagementDAOException;
|
||||
|
||||
/**
|
||||
* This method is used to get the details of roles
|
||||
*
|
||||
* @param tenantId id of the current tenant
|
||||
* @param offsetValue offset value for get paginated request.
|
||||
* @param limitValue limit value for get paginated request.
|
||||
* @param appReleaseId id of the application release.
|
||||
* @return subscribedRoles - list of app subscribed roles.
|
||||
* @throws {@link ApplicationManagementDAOException} if connections establishment fails.
|
||||
*/
|
||||
List<String> getAppSubscribedRoles(int offsetValue, int limitValue, int appReleaseId,
|
||||
int tenantId)
|
||||
throws ApplicationManagementDAOException;
|
||||
|
||||
/**
|
||||
* This method is used to get the details of subscribed groups
|
||||
*
|
||||
* @param tenantId id of the current tenant
|
||||
* @param offsetValue offset value for get paginated request.
|
||||
* @param limitValue limit value for get paginated request.
|
||||
* @param appReleaseId id of the application release.
|
||||
* @return subscribedGroups - list of app subscribed groups.
|
||||
* @throws {@link ApplicationManagementDAOException} if connections establishment fails.
|
||||
*/
|
||||
List<String> getAppSubscribedGroups(int offsetValue, int limitValue, int appReleaseId, int tenantId)
|
||||
throws ApplicationManagementDAOException;
|
||||
}
|
||||
|
||||
@ -356,6 +356,7 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
|
||||
+ "DS.UNSUBSCRIBED_BY AS UNSUBSCRIBED_BY, "
|
||||
+ "DS.UNSUBSCRIBED_TIMESTAMP AS UNSUBSCRIBED_AT, "
|
||||
+ "DS.ACTION_TRIGGERED_FROM AS ACTION_TRIGGERED_FROM, "
|
||||
+ "DS.STATUS AS STATUS,"
|
||||
+ "DS.DM_DEVICE_ID AS DEVICE_ID "
|
||||
+ "FROM AP_DEVICE_SUBSCRIPTION DS "
|
||||
+ "WHERE DS.AP_APP_RELEASE_ID = ? AND DS.TENANT_ID=?";
|
||||
@ -849,6 +850,45 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getAppSubscribedUsers(int offsetValue, int limitValue, int appReleaseId,
|
||||
int tenantId)
|
||||
throws ApplicationManagementDAOException {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Request received in DAO Layer to get already subscribed users for " +
|
||||
"given app release id.");
|
||||
}
|
||||
try {
|
||||
Connection conn = this.getDBConnection();
|
||||
List<String> subscribedUsers = new ArrayList<>();
|
||||
String sql = "SELECT "
|
||||
+ "US.USER_NAME AS USER "
|
||||
+ "FROM AP_USER_SUBSCRIPTION US "
|
||||
+ "WHERE "
|
||||
+ "AP_APP_RELEASE_ID = ? AND TENANT_ID = ? LIMIT ?,?";
|
||||
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||
stmt.setInt(1, appReleaseId);
|
||||
stmt.setInt(2, tenantId);
|
||||
stmt.setInt(3, offsetValue);
|
||||
stmt.setInt(4, limitValue);
|
||||
try (ResultSet rs = stmt.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
subscribedUsers.add(rs.getString("USER"));
|
||||
}
|
||||
}
|
||||
return subscribedUsers;
|
||||
}
|
||||
} catch (DBConnectionException e) {
|
||||
String msg = "Error occurred while obtaining the DB connection to get already " +
|
||||
"subscribed users for given app release id.";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementDAOException(msg, e);
|
||||
} catch (SQLException e) {
|
||||
String msg = "SQL Error occurred while getting subscribed users for given app release id.";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementDAOException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ScheduledSubscriptionDTO> getScheduledSubscriptionByStatus(ExecutionStatus status, boolean deleted)
|
||||
throws ApplicationManagementDAOException {
|
||||
@ -918,6 +958,45 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getAppSubscribedRoles(int offsetValue, int limitValue, int appReleaseId,
|
||||
int tenantId)
|
||||
throws ApplicationManagementDAOException {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Request received in DAO Layer to get already subscribed roles for " +
|
||||
"given app release id.");
|
||||
}
|
||||
try {
|
||||
Connection conn = this.getDBConnection();
|
||||
List<String> subscribedRoles = new ArrayList<>();
|
||||
String sql = "SELECT "
|
||||
+ "US.ROLE_NAME AS ROLE "
|
||||
+ "FROM AP_ROLE_SUBSCRIPTION US "
|
||||
+ "WHERE "
|
||||
+ "AP_APP_RELEASE_ID = ? AND TENANT_ID = ? LIMIT ?,?";
|
||||
try (PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||
ps.setInt(1, appReleaseId);
|
||||
ps.setInt(2, tenantId);
|
||||
ps.setInt(3, offsetValue);
|
||||
ps.setInt(4, limitValue);
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
subscribedRoles.add(rs.getString("ROLE"));
|
||||
}
|
||||
}
|
||||
return subscribedRoles;
|
||||
}
|
||||
} catch (DBConnectionException e) {
|
||||
String msg = "Error occurred while obtaining the DB connection to get already " +
|
||||
"subscribed roles for given app release id.";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementDAOException(msg, e);
|
||||
} catch (SQLException e) {
|
||||
String msg = "SQL Error occurred while getting subscribed roles for given app release id.";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementDAOException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScheduledSubscriptionDTO getPendingScheduledSubscriptionByTaskName(String taskName)
|
||||
throws ApplicationManagementDAOException {
|
||||
@ -957,4 +1036,45 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
|
||||
throw new ApplicationManagementDAOException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAppSubscribedGroups(int offsetValue, int limitValue, int appReleaseId,
|
||||
int tenantId)
|
||||
throws ApplicationManagementDAOException {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Request received in DAO Layer to get already subscribed groups for " +
|
||||
"given app release id.");
|
||||
}
|
||||
try {
|
||||
Connection conn = this.getDBConnection();
|
||||
List<String> subscribedGroups = new ArrayList<>();
|
||||
String sql = "SELECT "
|
||||
+ "GS.GROUP_NAME AS GROUPS "
|
||||
+ "FROM AP_GROUP_SUBSCRIPTION GS "
|
||||
+ "WHERE "
|
||||
+ "AP_APP_RELEASE_ID = ? AND TENANT_ID = ? LIMIT ?,?";
|
||||
try (PreparedStatement ps = conn.prepareStatement(sql)) {
|
||||
ps.setInt(1, appReleaseId);
|
||||
ps.setInt(2, tenantId);
|
||||
ps.setInt(3, offsetValue);
|
||||
ps.setInt(4, limitValue);
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
subscribedGroups.add(rs.getString("GROUPS"));
|
||||
}
|
||||
}
|
||||
return subscribedGroups;
|
||||
}
|
||||
} catch (DBConnectionException e) {
|
||||
String msg = "Error occurred while obtaining the DB connection to get already " +
|
||||
"subscribed groups for given app release id.";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementDAOException(msg, e);
|
||||
} catch (SQLException e) {
|
||||
String msg = "SQL Error occurred while getting subscribed groups for given " +
|
||||
"app release id.";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementDAOException(msg, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,6 +82,7 @@ import org.wso2.carbon.device.mgt.core.util.MDMAndroidOperationUtil;
|
||||
import org.wso2.carbon.device.mgt.core.util.MDMIOSOperationUtil;
|
||||
import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo;
|
||||
import org.wso2.carbon.user.api.UserStoreException;
|
||||
import org.wso2.carbon.device.mgt.common.PaginationResult;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import java.io.IOException;
|
||||
@ -684,6 +685,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
|
||||
app.setLocation(application.getApplicationReleases().get(0).getInstallerPath());
|
||||
return MDMAndroidOperationUtil.createInstallAppOperation(app);
|
||||
} else if (SubAction.UNINSTALL.toString().equalsIgnoreCase(action)) {
|
||||
app.setType(mobileAppType);
|
||||
return MDMAndroidOperationUtil.createAppUninstallOperation(app);
|
||||
} else {
|
||||
String msg = "Invalid Action is found. Action: " + action;
|
||||
@ -793,10 +795,117 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementException(msg, e);
|
||||
} catch (IOException e) {
|
||||
String msg = "Error while installing the enrollment with id: " + applicationPolicyDTO.getApplicationDTO()
|
||||
.getId() + " on device";
|
||||
String msg = "Error while installing the enrollment with id: " + applicationPolicyDTO.getApplicationDTO().getId()
|
||||
+ " on device";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaginationResult getAppInstalledDevices(int offsetValue, int limitValue, String appUUID,
|
||||
String status)
|
||||
throws ApplicationManagementException {
|
||||
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
|
||||
DeviceManagementProviderService deviceManagementProviderService = HelperUtil
|
||||
.getDeviceManagementProviderService();
|
||||
|
||||
try {
|
||||
ConnectionManagerUtil.openDBConnection();
|
||||
ApplicationDTO applicationDTO = this.applicationDAO.getAppWithRelatedRelease(appUUID, tenantId);
|
||||
int applicationReleaseId = applicationDTO.getApplicationReleaseDTOs().get(0).getId();
|
||||
|
||||
List<DeviceSubscriptionDTO> deviceSubscriptionDTOS = subscriptionDAO
|
||||
.getDeviceSubscriptions(applicationReleaseId, tenantId);
|
||||
if (deviceSubscriptionDTOS.isEmpty()) {
|
||||
String msg = "Couldn't found an subscribed devices for application release id: "
|
||||
+ applicationReleaseId;
|
||||
log.info(msg);
|
||||
}
|
||||
List<Integer> deviceIdList = new ArrayList<>();
|
||||
for (DeviceSubscriptionDTO deviceIds : deviceSubscriptionDTOS) {
|
||||
deviceIdList.add(deviceIds.getDeviceId());
|
||||
}
|
||||
//pass the device id list to device manager service method
|
||||
try {
|
||||
PaginationResult deviceDetails = deviceManagementProviderService
|
||||
.getAppSubscribedDevices(offsetValue ,limitValue, deviceIdList, status);
|
||||
|
||||
if (deviceDetails == null) {
|
||||
String msg = "Couldn't found an subscribed devices details for device ids: "
|
||||
+ deviceIdList;
|
||||
log.error(msg);
|
||||
throw new NotFoundException(msg);
|
||||
}
|
||||
return deviceDetails;
|
||||
|
||||
} catch (DeviceManagementException e) {
|
||||
String msg = "service error occurred while getting data from the service";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementException(msg, e);
|
||||
}
|
||||
} catch (ApplicationManagementDAOException e) {
|
||||
ConnectionManagerUtil.rollbackDBTransaction();
|
||||
String msg = "Error occurred when get application release data for application" +
|
||||
" release UUID: " + appUUID;
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementException(msg, e);
|
||||
} catch (DBConnectionException e) {
|
||||
String msg = "DB Connection error occurred while getting device details that " +
|
||||
"given application id";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementException(msg, e);
|
||||
} finally {
|
||||
ConnectionManagerUtil.closeDBConnection();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaginationResult getAppInstalledCategories(int offsetValue, int limitValue,
|
||||
String appUUID, String subType)
|
||||
throws ApplicationManagementException {
|
||||
|
||||
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
|
||||
PaginationResult paginationResult = new PaginationResult();
|
||||
try {
|
||||
ConnectionManagerUtil.openDBConnection();
|
||||
ApplicationDTO applicationDTO = this.applicationDAO
|
||||
.getAppWithRelatedRelease(appUUID, tenantId);
|
||||
int applicationReleaseId = applicationDTO.getApplicationReleaseDTOs().get(0).getId();
|
||||
|
||||
int count = 0;
|
||||
List<String> SubscriptionList = new ArrayList<>();
|
||||
|
||||
if (SubscriptionType.USER.toString().equalsIgnoreCase(subType)) {
|
||||
SubscriptionList = subscriptionDAO
|
||||
.getAppSubscribedUsers(offsetValue, limitValue, applicationReleaseId, tenantId);
|
||||
} else if (SubscriptionType.ROLE.toString().equalsIgnoreCase(subType)) {
|
||||
SubscriptionList = subscriptionDAO
|
||||
.getAppSubscribedRoles(offsetValue, limitValue, applicationReleaseId, tenantId);
|
||||
} else if (SubscriptionType.GROUP.toString().equalsIgnoreCase(subType)) {
|
||||
SubscriptionList = subscriptionDAO
|
||||
.getAppSubscribedGroups(offsetValue, limitValue, applicationReleaseId, tenantId);
|
||||
}
|
||||
count = SubscriptionList.size();
|
||||
paginationResult.setData(SubscriptionList);
|
||||
paginationResult.setRecordsFiltered(count);
|
||||
paginationResult.setRecordsTotal(count);
|
||||
|
||||
return paginationResult;
|
||||
|
||||
} catch (ApplicationManagementDAOException e) {
|
||||
ConnectionManagerUtil.rollbackDBTransaction();
|
||||
String msg = "Error occurred when get application release data for application" +
|
||||
" release UUID: " + appUUID;
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementException(msg, e);
|
||||
} catch (DBConnectionException e) {
|
||||
String msg = "DB Connection error occurred while getting category details that " +
|
||||
"given application id";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementException(msg, e);
|
||||
} finally {
|
||||
ConnectionManagerUtil.closeDBConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@
|
||||
}
|
||||
|
||||
.mobile-menu-button{
|
||||
margin-top: 4%;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
Header{
|
||||
@ -68,7 +68,7 @@
|
||||
}
|
||||
|
||||
.dashboard-body{
|
||||
margin-top: 14%;
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
.logo-image {
|
||||
@ -80,7 +80,7 @@
|
||||
@media screen and (max-height: 350px) {
|
||||
|
||||
.mobile-menu-button{
|
||||
margin-top: 2%;
|
||||
margin-top: 15px;
|
||||
}
|
||||
.dashboard-body{
|
||||
margin-top: 9%;
|
||||
|
||||
@ -40,14 +40,14 @@ class Dashboard extends React.Component {
|
||||
this.Logo = this.config.theme.logo;
|
||||
}
|
||||
|
||||
showDrawer = () => {
|
||||
showMobileNavigationBar = () => {
|
||||
this.setState({
|
||||
visible: true,
|
||||
collapsed: !this.state.collapsed
|
||||
});
|
||||
};
|
||||
|
||||
onClose = () => {
|
||||
onCloseMobileNavigationBar = () => {
|
||||
this.setState({
|
||||
visible: false,
|
||||
});
|
||||
@ -131,7 +131,7 @@ class Dashboard extends React.Component {
|
||||
|
||||
<Layout className="mobile-layout">
|
||||
<div className="mobile-menu-button">
|
||||
<Button type="link" onClick={this.showDrawer}>
|
||||
<Button type="link" onClick={this.showMobileNavigationBar}>
|
||||
<Icon type={this.state.collapsed ? 'menu-fold' : 'menu-unfold'} className="bar-icon"/>
|
||||
</Button>
|
||||
</div>
|
||||
@ -146,7 +146,7 @@ class Dashboard extends React.Component {
|
||||
}
|
||||
placement="left"
|
||||
closable={false}
|
||||
onClose={this.onClose}
|
||||
onClose={this.onCloseMobileNavigationBar}
|
||||
visible={this.state.visible}
|
||||
getContainer={false}
|
||||
style={{position: 'absolute'}}>
|
||||
@ -214,6 +214,6 @@ class Dashboard extends React.Component {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default withConfigContext(Dashboard);
|
||||
@ -20,6 +20,7 @@ package org.wso2.carbon.device.application.mgt.store.api.services;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import io.swagger.annotations.ApiResponse;
|
||||
import io.swagger.annotations.ApiResponses;
|
||||
import io.swagger.annotations.Extension;
|
||||
import io.swagger.annotations.ExtensionProperty;
|
||||
@ -27,15 +28,17 @@ import io.swagger.annotations.Info;
|
||||
import io.swagger.annotations.SwaggerDefinition;
|
||||
import io.swagger.annotations.Tag;
|
||||
import org.wso2.carbon.apimgt.annotations.api.Scopes;
|
||||
import org.wso2.carbon.device.application.mgt.common.ErrorResponse;
|
||||
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.util.List;
|
||||
@ -181,4 +184,133 @@ public interface SubscriptionManagementAPI {
|
||||
)
|
||||
@QueryParam("timestamp") String timestamp
|
||||
);
|
||||
|
||||
@GET
|
||||
@Path("/{uuid}/devices")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@ApiOperation(
|
||||
consumes = MediaType.APPLICATION_JSON,
|
||||
produces = MediaType.APPLICATION_JSON,
|
||||
httpMethod = "GET",
|
||||
value = "Get device details that have a given application install",
|
||||
notes = "This will get the device details that have a given application install, if exists",
|
||||
tags = "Subscription Management",
|
||||
extensions = {
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name = SCOPE, value = "perm:app:subscription:uninstall")
|
||||
})
|
||||
}
|
||||
)
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(
|
||||
code = 200,
|
||||
message = "OK. \n Successfully retrieved device details.",
|
||||
response = List.class,
|
||||
responseContainer = "List"),
|
||||
@ApiResponse(
|
||||
code = 404,
|
||||
message = "Not Found. \n No Application found which has application release of UUID.",
|
||||
response = ErrorResponse.class),
|
||||
@ApiResponse(
|
||||
code = 400,
|
||||
message = "Bad Request. \n Found invalid payload with the request.",
|
||||
response = List.class),
|
||||
@ApiResponse(
|
||||
code = 403,
|
||||
message = "Forbidden. \n Don't have permission to get the details.",
|
||||
response = List.class),
|
||||
@ApiResponse(
|
||||
code = 500,
|
||||
message = "Internal Server Error. \n Error occurred while getting data",
|
||||
response = ErrorResponse.class)
|
||||
})
|
||||
Response getAppInstalledDevices(
|
||||
@ApiParam(
|
||||
name="uuid",
|
||||
value="uuid of the application release.",
|
||||
required = true)
|
||||
@PathParam("uuid") String uuid,
|
||||
@ApiParam(
|
||||
name = "offset",
|
||||
value = "The starting pagination index for the complete list of qualified items.",
|
||||
defaultValue = "0")
|
||||
@QueryParam("offset") int offset,
|
||||
@ApiParam(
|
||||
name = "limit",
|
||||
value = "Provide how many device details you require from the starting pagination index/offset.",
|
||||
defaultValue = "5")
|
||||
@QueryParam("limit") int limit,
|
||||
@ApiParam(
|
||||
name = "status",
|
||||
value = "Provide the device status details, such as active or inactive.")
|
||||
@QueryParam("status") String status
|
||||
);
|
||||
|
||||
@GET
|
||||
@Path("/{uuid}/{subType}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@ApiOperation(
|
||||
consumes = MediaType.APPLICATION_JSON,
|
||||
produces = MediaType.APPLICATION_JSON,
|
||||
httpMethod = "GET",
|
||||
value = "Get category details that have a given application install",
|
||||
notes = "This will get the category details that have a given application install, if exists",
|
||||
tags = "Subscription Management",
|
||||
extensions = {
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name = SCOPE, value = "perm:app:subscription:uninstall")
|
||||
})
|
||||
}
|
||||
)
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(
|
||||
code = 200,
|
||||
message = "OK. \n Successfully retrieved categories details.",
|
||||
response = List.class,
|
||||
responseContainer = "List"),
|
||||
@ApiResponse(
|
||||
code = 404,
|
||||
message = "Not Found. \n No Application found which has application " +
|
||||
"release of UUID.",
|
||||
response = ErrorResponse.class),
|
||||
@ApiResponse(
|
||||
code = 400,
|
||||
message = "Bad Request. \n Found invalid payload with the request.",
|
||||
response = List.class),
|
||||
@ApiResponse(
|
||||
code = 403,
|
||||
message = "Forbidden. \n Don't have permission to get the details.",
|
||||
response = List.class),
|
||||
@ApiResponse(
|
||||
code = 500,
|
||||
message = "Internal Server Error. \n Error occurred while getting data",
|
||||
response = ErrorResponse.class)
|
||||
})
|
||||
Response getAppInstalledCategories(
|
||||
@ApiParam(
|
||||
name="uuid",
|
||||
value="uuid of the application release.",
|
||||
required = true)
|
||||
@PathParam("uuid") String uuid,
|
||||
@ApiParam(
|
||||
name="subType",
|
||||
value="Subscription type of the application release.",
|
||||
required = true)
|
||||
@PathParam("subType") String subType,
|
||||
@ApiParam(
|
||||
name = "offset",
|
||||
value = "The starting pagination index for the complete list of qualified items.",
|
||||
defaultValue = "0")
|
||||
@QueryParam("offset") int offset,
|
||||
@ApiParam(
|
||||
name = "limit",
|
||||
value = "Provide how many device details you require from the starting " +
|
||||
"pagination index/offset.",
|
||||
defaultValue = "5")
|
||||
@QueryParam("limit") int limit
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,21 +1,3 @@
|
||||
/*
|
||||
* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||
* Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
|
||||
*
|
||||
@ -46,20 +28,31 @@ import org.wso2.carbon.device.application.mgt.common.SubscriptionType;
|
||||
import org.wso2.carbon.device.application.mgt.common.exception.ApplicationManagementException;
|
||||
import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager;
|
||||
import org.wso2.carbon.device.application.mgt.core.exception.ApplicationOperationTaskException;
|
||||
import org.wso2.carbon.device.application.mgt.common.DeviceList;
|
||||
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.RoleList;
|
||||
import org.wso2.carbon.device.application.mgt.common.DeviceGroupList;
|
||||
import org.wso2.carbon.device.mgt.common.PaginationResult;
|
||||
import org.wso2.carbon.device.application.mgt.common.SubsciptionType;
|
||||
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.NotFoundException;
|
||||
import org.wso2.carbon.device.application.mgt.core.task.ScheduledAppSubscriptionTaskManager;
|
||||
import org.wso2.carbon.device.application.mgt.core.util.APIUtil;
|
||||
import org.wso2.carbon.device.application.mgt.store.api.services.SubscriptionManagementAPI;
|
||||
import org.wso2.carbon.device.mgt.common.Device;
|
||||
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.DefaultValue;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
@ -114,6 +107,7 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@POST
|
||||
@Path("/{uuid}/{subType}/{action}")
|
||||
@ -185,4 +179,114 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
|
||||
}
|
||||
return Response.status(Response.Status.CREATED).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Consumes("application/json")
|
||||
@Produces("application/json")
|
||||
@Path("/{uuid}/devices")
|
||||
public Response getAppInstalledDevices(@PathParam("uuid") String uuid,
|
||||
@DefaultValue("0")
|
||||
@QueryParam("offset") int offset,
|
||||
@DefaultValue("5")
|
||||
@QueryParam("limit") int limit,
|
||||
@QueryParam("status") String status) {
|
||||
|
||||
try {
|
||||
SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager();
|
||||
|
||||
PaginationResult subscribedDeviceDetails = subscriptionManager
|
||||
.getAppInstalledDevices(offset, limit, uuid, status);
|
||||
|
||||
DeviceList devices = new DeviceList();
|
||||
|
||||
devices.setList((List<Device>) subscribedDeviceDetails.getData());
|
||||
devices.setCount(subscribedDeviceDetails.getRecordsTotal());
|
||||
|
||||
return Response.status(Response.Status.OK).entity(devices).build();
|
||||
} catch (NotFoundException e) {
|
||||
String msg = "Application with application release UUID: " + uuid + " is not found";
|
||||
log.error(msg, e);
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
|
||||
} catch (BadRequestException e) {
|
||||
String msg = "Found invalid payload for getting application which has UUID: " + uuid
|
||||
+ ". Hence verify the payload";
|
||||
log.error(msg, e);
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
|
||||
} catch (ForbiddenException e) {
|
||||
String msg = "Application release is not in the installable state."
|
||||
+ "Hence you are not permitted to get the devices details.";
|
||||
log.error(msg, e);
|
||||
return Response.status(Response.Status.FORBIDDEN).entity(msg).build();
|
||||
} catch (ApplicationManagementException e) {
|
||||
String msg = "Error occurred while getting application with the application release uuid: "
|
||||
+ uuid;
|
||||
log.error(msg, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Consumes("application/json")
|
||||
@Produces("application/json")
|
||||
@Path("/{uuid}/{subType}")
|
||||
public Response getAppInstalledCategories(@PathParam("uuid") String uuid,
|
||||
@PathParam("subType") String subType,
|
||||
@DefaultValue("0")
|
||||
@QueryParam("offset") int offset,
|
||||
@DefaultValue("5")
|
||||
@QueryParam("limit") int limit) {
|
||||
|
||||
try {
|
||||
SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager();
|
||||
|
||||
PaginationResult subscribedCategoryDetails = subscriptionManager
|
||||
.getAppInstalledCategories(offset, limit, uuid, subType);
|
||||
|
||||
if (SubsciptionType.USER.toString().equalsIgnoreCase(subType)) {
|
||||
BasicUserInfoList users = new BasicUserInfoList();
|
||||
|
||||
users.setList((List<BasicUserInfo>) subscribedCategoryDetails.getData());
|
||||
users.setCount(subscribedCategoryDetails.getRecordsTotal());
|
||||
|
||||
return Response.status(Response.Status.OK).entity(users).build();
|
||||
} else if (SubsciptionType.ROLE.toString().equalsIgnoreCase(subType)) {
|
||||
RoleList roles = new RoleList();
|
||||
|
||||
roles.setList(subscribedCategoryDetails.getData());
|
||||
roles.setCount(subscribedCategoryDetails.getRecordsTotal());
|
||||
|
||||
return Response.status(Response.Status.OK).entity(roles).build();
|
||||
} else if (SubsciptionType.GROUP.toString().equalsIgnoreCase(subType)) {
|
||||
DeviceGroupList groups = new DeviceGroupList();
|
||||
|
||||
groups.setList(subscribedCategoryDetails.getData());
|
||||
groups.setCount(subscribedCategoryDetails.getRecordsTotal());
|
||||
|
||||
return Response.status(Response.Status.OK).entity(groups).build();
|
||||
} else {
|
||||
String msg = "Found invalid sub type ";
|
||||
log.error(msg);
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
|
||||
}
|
||||
} catch (NotFoundException e) {
|
||||
String msg = "Application with application release UUID: " + uuid + " is not found";
|
||||
log.error(msg, e);
|
||||
return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
|
||||
} catch (BadRequestException e) {
|
||||
String msg = "Found invalid payload for getting application which has UUID: " + uuid
|
||||
+ ". Hence verify the payload";
|
||||
log.error(msg, e);
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
|
||||
} catch (ForbiddenException e) {
|
||||
String msg = "Application release is not in the installable state."
|
||||
+ "Hence you are not permitted to get the devices details.";
|
||||
log.error(msg, e);
|
||||
return Response.status(Response.Status.FORBIDDEN).entity(msg).build();
|
||||
} catch (ApplicationManagementException e) {
|
||||
String msg = "Error occurred while getting application with the application " +
|
||||
"release uuid: " + uuid;
|
||||
log.error(msg, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@ import DetailedRating from "./DetailedRating";
|
||||
import Reviews from "./review/Reviews";
|
||||
import axios from "axios";
|
||||
import AppInstallModal from "./install/AppInstallModal";
|
||||
import AppUninstallModal from "./install/AppUninstallModal";
|
||||
import CurrentUsersReview from "./review/CurrentUsersReview";
|
||||
import {withConfigContext} from "../../../context/ConfigContext";
|
||||
import {handleApiError} from "../../../js/Utils";
|
||||
@ -36,11 +37,12 @@ class ReleaseView extends React.Component {
|
||||
super(props);
|
||||
this.state = {
|
||||
loading: false,
|
||||
appInstallModalVisible: false
|
||||
appInstallModalVisible: false,
|
||||
appUninstallModalVisible: false
|
||||
}
|
||||
}
|
||||
|
||||
installApp = (type, payload) => {
|
||||
appOperation = (type, payload, operation) => {
|
||||
const config = this.props.context;
|
||||
const release = this.props.app.applicationReleases[0];
|
||||
const {uuid} = release;
|
||||
@ -48,7 +50,7 @@ class ReleaseView extends React.Component {
|
||||
this.setState({
|
||||
loading: true,
|
||||
});
|
||||
const url = window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.store + "/subscription/" + uuid + "/" + type + "/install";
|
||||
const url = window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.store + "/subscription/" + uuid + "/" + type + "/" + operation;
|
||||
axios.post(
|
||||
url,
|
||||
payload,
|
||||
@ -64,7 +66,7 @@ class ReleaseView extends React.Component {
|
||||
notification["success"]({
|
||||
message: 'Done!',
|
||||
description:
|
||||
'App installed triggered.',
|
||||
'App '+operation+'ed triggered.',
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
@ -74,24 +76,31 @@ class ReleaseView extends React.Component {
|
||||
message: "There was a problem",
|
||||
duration: 0,
|
||||
description:
|
||||
"Error occurred while installing app",
|
||||
"Error occurred while "+operation+"ing app",
|
||||
});
|
||||
}
|
||||
|
||||
}).catch((error) => {
|
||||
handleApiError(error,"Error occurred while installing the app.");
|
||||
handleApiError(error,"Error occurred while "+operation+"ing the app.");
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
showAppInstallModal = () => {
|
||||
this.setState({
|
||||
appInstallModalVisible: true
|
||||
});
|
||||
};
|
||||
|
||||
closeAppInstallModal = () => {
|
||||
closeAppOperationModal = () => {
|
||||
this.setState({
|
||||
appInstallModalVisible: false
|
||||
appInstallModalVisible: false,
|
||||
appUninstallModalVisible: false
|
||||
});
|
||||
};
|
||||
|
||||
showAppUninstallModal = () => {
|
||||
this.setState({
|
||||
appUninstallModalVisible: true
|
||||
});
|
||||
};
|
||||
|
||||
@ -112,8 +121,14 @@ class ReleaseView extends React.Component {
|
||||
uuid={release.uuid}
|
||||
visible={this.state.appInstallModalVisible}
|
||||
deviceType = {deviceType}
|
||||
onClose={this.closeAppInstallModal}
|
||||
onInstall={this.installApp}/>
|
||||
onClose={this.closeAppOperationModal}
|
||||
onInstall={this.appOperation}/>
|
||||
<AppUninstallModal
|
||||
uuid={release.uuid}
|
||||
visible={this.state.appUninstallModalVisible}
|
||||
deviceType = {deviceType}
|
||||
onClose={this.closeAppOperationModal}
|
||||
onUninstall={this.appOperation}/>
|
||||
<div className="release">
|
||||
<Row>
|
||||
<Col xl={4} sm={6} xs={8} className="release-icon">
|
||||
@ -138,6 +153,12 @@ class ReleaseView extends React.Component {
|
||||
htmlType="button" type="primary" icon="download">Install</Button>
|
||||
</Button.Group>
|
||||
</div>
|
||||
<div>
|
||||
<Button.Group style={{float: "right",marginRight:'3%'}}>
|
||||
<Button onClick={this.showAppUninstallModal} loading={this.state.loading}
|
||||
htmlType="button" type="primary" icon="delete">UnInstall</Button>
|
||||
</Button.Group>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
<Divider/>
|
||||
@ -179,4 +200,4 @@ class ReleaseView extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default withConfigContext(ReleaseView);
|
||||
export default withConfigContext(ReleaseView);
|
||||
|
||||
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
import React from "react";
|
||||
import {Modal, Tabs} from "antd";
|
||||
import DeviceUninstall from "./DeviceUninstall";
|
||||
import UserUninstall from "./UserUninstall";
|
||||
import RoleUninstall from "./RoleUninstall";
|
||||
import GroupUninstall from "./GroupUninstall";
|
||||
|
||||
const { TabPane } = Tabs;
|
||||
|
||||
class AppUninstallModal extends React.Component{
|
||||
state={
|
||||
data:[]
|
||||
};
|
||||
render() {
|
||||
const {deviceType} = this.props;
|
||||
return (
|
||||
<div>
|
||||
<Modal
|
||||
title="Uninstall App"
|
||||
visible={this.props.visible}
|
||||
onCancel={this.props.onClose}
|
||||
footer={null}
|
||||
>
|
||||
<Tabs defaultActiveKey="device">
|
||||
<TabPane tab="Device" key="device">
|
||||
<DeviceUninstall deviceType={deviceType} onUninstall={this.props.onUninstall} uuid={this.props.uuid}/>
|
||||
</TabPane>
|
||||
<TabPane tab="User" key="user">
|
||||
<UserUninstall onUninstall={this.props.onUninstall} uuid={this.props.uuid}/>
|
||||
</TabPane>
|
||||
<TabPane tab="Role" key="role">
|
||||
<RoleUninstall onUninstall={this.props.onUninstall} uuid={this.props.uuid}/>
|
||||
</TabPane>
|
||||
<TabPane tab="Group" key="group">
|
||||
<GroupUninstall onUninstall={this.props.onUninstall} uuid={this.props.uuid}/>
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default AppUninstallModal;
|
||||
@ -196,7 +196,7 @@ class DeviceInstall extends React.Component {
|
||||
type: device.type
|
||||
});
|
||||
});
|
||||
this.props.onInstall("devices", payload);
|
||||
this.props.onInstall("devices", payload, "install");
|
||||
};
|
||||
|
||||
render() {
|
||||
|
||||
@ -0,0 +1,232 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import axios from "axios";
|
||||
import {Button,Table, Typography} from "antd";
|
||||
import TimeAgo from 'javascript-time-ago'
|
||||
|
||||
// Load locale-specific relative date/time formatting rules.
|
||||
import en from 'javascript-time-ago/locale/en'
|
||||
import {withConfigContext} from "../../../../context/ConfigContext";
|
||||
import {handleApiError} from "../../../../js/Utils";
|
||||
|
||||
const {Text} = Typography;
|
||||
const columns = [
|
||||
{
|
||||
title: 'Device',
|
||||
dataIndex: 'name',
|
||||
fixed: 'left',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: 'Modal',
|
||||
dataIndex: 'deviceInfo',
|
||||
key: 'modal',
|
||||
render: deviceInfo => `${deviceInfo.vendor} ${deviceInfo.deviceModel}`
|
||||
// todo add filtering options
|
||||
},
|
||||
{
|
||||
title: 'Owner',
|
||||
dataIndex: 'enrolmentInfo',
|
||||
key: 'owner',
|
||||
render: enrolmentInfo => enrolmentInfo.owner
|
||||
// todo add filtering options
|
||||
},
|
||||
{
|
||||
title: 'Last Updated',
|
||||
dataIndex: 'enrolmentInfo',
|
||||
key: 'dateOfLastUpdate',
|
||||
render: (data) => {
|
||||
return (getTimeAgo(data.dateOfLastUpdate));
|
||||
}
|
||||
// todo add filtering options
|
||||
},
|
||||
{
|
||||
title: 'Status',
|
||||
dataIndex: 'enrolmentInfo',
|
||||
key: 'status',
|
||||
render: enrolmentInfo => enrolmentInfo.status
|
||||
// todo add filtering options
|
||||
},
|
||||
{
|
||||
title: 'Ownership',
|
||||
dataIndex: 'enrolmentInfo',
|
||||
key: 'ownership',
|
||||
render: enrolmentInfo => enrolmentInfo.ownership
|
||||
// todo add filtering options
|
||||
},
|
||||
{
|
||||
title: 'OS Version',
|
||||
dataIndex: 'deviceInfo',
|
||||
key: 'osVersion',
|
||||
render: deviceInfo => deviceInfo.osVersion
|
||||
// todo add filtering options
|
||||
},
|
||||
{
|
||||
title: 'IMEI',
|
||||
dataIndex: 'properties',
|
||||
key: 'imei',
|
||||
render: properties => {
|
||||
let imei = "not-found";
|
||||
for (let i = 0; i < properties.length; i++) {
|
||||
if (properties[i].name === "IMEI") {
|
||||
imei = properties[i].value;
|
||||
}
|
||||
}
|
||||
return imei;
|
||||
}
|
||||
// todo add filtering options
|
||||
},
|
||||
];
|
||||
|
||||
const getTimeAgo = (time) => {
|
||||
const timeAgo = new TimeAgo('en-US');
|
||||
return timeAgo.format(time);
|
||||
};
|
||||
|
||||
class DeviceUninstall extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
TimeAgo.addLocale(en);
|
||||
this.state = {
|
||||
data: [],
|
||||
pagination: {},
|
||||
loading: false,
|
||||
selectedRows: []
|
||||
};
|
||||
}
|
||||
|
||||
rowSelection = {
|
||||
onChange: (selectedRowKeys, selectedRows) => {
|
||||
this.setState({
|
||||
selectedRows: selectedRows
|
||||
})
|
||||
},
|
||||
getCheckboxProps: record => ({
|
||||
disabled: record.name === 'Disabled User', // Column configuration not to be checked
|
||||
name: record.name,
|
||||
}),
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.fetch();
|
||||
}
|
||||
|
||||
//fetch data from api
|
||||
fetch = (params = {}) => {
|
||||
const config = this.props.context;
|
||||
this.setState({loading: true});
|
||||
const {deviceType} = this.props;
|
||||
// get current page
|
||||
const currentPage = (params.hasOwnProperty("page")) ? params.page : 1;
|
||||
|
||||
const extraParams = {
|
||||
offset: 10 * (currentPage - 1), //calculate the offset
|
||||
limit: 10,
|
||||
status: "ACTIVE",
|
||||
};
|
||||
|
||||
if (deviceType !== 'ANY') {
|
||||
extraParams.type = deviceType;
|
||||
}
|
||||
|
||||
// note: encode with '%26' not '&'
|
||||
const encodedExtraParams = Object.keys(extraParams).map(key => key + '=' + extraParams[key]).join('&');
|
||||
|
||||
const uuid = this.props.uuid;
|
||||
axios.get(
|
||||
window.location.origin + config.serverConfig.invoker.uri + config.serverConfig.invoker.store + "/subscription/" + uuid + "/"+
|
||||
"/devices?" + encodedExtraParams,
|
||||
).then(res => {
|
||||
if (res.status === 200) {
|
||||
const pagination = {...this.state.pagination};
|
||||
this.setState({
|
||||
loading: false,
|
||||
data: res.data.data.devices,
|
||||
pagination,
|
||||
});
|
||||
}
|
||||
}).catch((error) => {
|
||||
handleApiError(error,"Error occurred while trying to load devices.");
|
||||
this.setState({loading: false});
|
||||
});
|
||||
};
|
||||
|
||||
handleTableChange = (pagination, filters, sorter) => {
|
||||
const pager = {...this.state.pagination};
|
||||
pager.current = pagination.current;
|
||||
this.setState({
|
||||
pagination: pager,
|
||||
});
|
||||
this.fetch({
|
||||
results: pagination.pageSize,
|
||||
page: pagination.current,
|
||||
sortField: sorter.field,
|
||||
sortOrder: sorter.order,
|
||||
...filters,
|
||||
});
|
||||
};
|
||||
|
||||
uninstall = () => {
|
||||
const {selectedRows} = this.state;
|
||||
const payload = [];
|
||||
selectedRows.map(device => {
|
||||
payload.push({
|
||||
id: device.deviceIdentifier,
|
||||
type: device.type
|
||||
});
|
||||
});
|
||||
this.props.onUninstall("devices", payload, "uninstall");
|
||||
};
|
||||
|
||||
render() {
|
||||
const {data, pagination, loading, selectedRows} = this.state;
|
||||
return (
|
||||
<div>
|
||||
<Text>
|
||||
Start uninstalling the application for devices by selecting the corresponding devices.
|
||||
Select uninstall to automatically start uninstalling the application for the respective devices.
|
||||
</Text>
|
||||
<Table
|
||||
style={{paddingTop: 20}}
|
||||
columns={columns}
|
||||
rowKey={record => record.deviceIdentifier}
|
||||
dataSource={data}
|
||||
pagination={{
|
||||
...pagination,
|
||||
size: "small",
|
||||
showTotal: (total, range) => `showing ${range[0]}-${range[1]} of ${total} devices`
|
||||
}}
|
||||
loading={loading}
|
||||
onChange={this.handleTableChange}
|
||||
rowSelection={this.rowSelection}
|
||||
scroll={{x: 1000}}
|
||||
/>
|
||||
<div style={{paddingTop: 10, textAlign: "right"}}>
|
||||
<Button disabled={selectedRows.length === 0} htmlType="button" type="primary"
|
||||
onClick={this.uninstall}>
|
||||
Uninstall
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withConfigContext(DeviceUninstall);
|
||||
@ -47,7 +47,7 @@ class GroupInstall extends React.Component {
|
||||
const config = this.props.context;
|
||||
this.setState({data: [], fetching: true});
|
||||
|
||||
axios.post(
|
||||
axios.get(
|
||||
window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.deviceMgt+"/groups?name=" + value,
|
||||
|
||||
).then(res => {
|
||||
@ -85,7 +85,7 @@ class GroupInstall extends React.Component {
|
||||
value.map(val=>{
|
||||
data.push(val.key);
|
||||
});
|
||||
this.props.onInstall("group",data);
|
||||
this.props.onInstall("group", data, "install");
|
||||
};
|
||||
|
||||
render() {
|
||||
|
||||
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import {Typography, Select, Spin, message, notification, Button} from "antd";
|
||||
import debounce from 'lodash.debounce';
|
||||
import axios from "axios";
|
||||
import {withConfigContext} from "../../../../context/ConfigContext";
|
||||
import {handleApiError} from "../../../../js/Utils";
|
||||
|
||||
const {Text} = Typography;
|
||||
const {Option} = Select;
|
||||
|
||||
class GroupUninstall extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.lastFetchId = 0;
|
||||
this.fetchUser = debounce(this.fetchUser, 800);
|
||||
}
|
||||
|
||||
state = {
|
||||
data: [],
|
||||
value: [],
|
||||
fetching: false,
|
||||
};
|
||||
|
||||
fetchUser = value => {
|
||||
this.lastFetchId += 1;
|
||||
const fetchId = this.lastFetchId;
|
||||
const config = this.props.context;
|
||||
this.setState({data: [], fetching: true});
|
||||
|
||||
const uuid = this.props.uuid;
|
||||
|
||||
axios.get(
|
||||
window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.store+ "/subscription/" + uuid + "/"+
|
||||
"/GROUP?",
|
||||
|
||||
).then(res => {
|
||||
if (res.status === 200) {
|
||||
if (fetchId !== this.lastFetchId) {
|
||||
// for fetch callback order
|
||||
return;
|
||||
}
|
||||
|
||||
const data = res.data.data.deviceGroups.map(group => ({
|
||||
text: group,
|
||||
value: group,
|
||||
}));
|
||||
|
||||
this.setState({data, fetching: false});
|
||||
}
|
||||
|
||||
}).catch((error) => {
|
||||
handleApiError(error,"Error occurred while trying to load groups.");
|
||||
this.setState({fetching: false});
|
||||
});
|
||||
};
|
||||
|
||||
handleChange = value => {
|
||||
this.setState({
|
||||
value,
|
||||
data: [],
|
||||
fetching: false,
|
||||
});
|
||||
};
|
||||
|
||||
install = () =>{
|
||||
const {value} = this.state;
|
||||
const data = [];
|
||||
value.map(val=>{
|
||||
data.push(val.key);
|
||||
});
|
||||
this.props.onInstall("group", data, "uninstall");
|
||||
};
|
||||
|
||||
render() {
|
||||
|
||||
const {fetching, data, value} = this.state;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Text>Start uninstalling the application for one or more groups by entering the corresponding group name. Select uninstall to automatically start uninstalling the application for the respective device group/ groups.</Text>
|
||||
<br/>
|
||||
<br/>
|
||||
<Select
|
||||
mode="multiple"
|
||||
labelInValue
|
||||
value={value}
|
||||
placeholder="Search groups"
|
||||
notFoundContent={fetching ? <Spin size="small"/> : null}
|
||||
filterOption={false}
|
||||
onSearch={this.fetchUser}
|
||||
onChange={this.handleChange}
|
||||
style={{width: '100%'}}
|
||||
>
|
||||
{data.map(d => (
|
||||
<Option key={d.value}>{d.text}</Option>
|
||||
))}
|
||||
</Select>
|
||||
<div style={{paddingTop:10, textAlign:"right"}}>
|
||||
<Button disabled={value.length===0} htmlType="button" type="primary" onClick={this.install}>Install</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withConfigContext(GroupUninstall);
|
||||
@ -85,7 +85,7 @@ class RoleInstall extends React.Component {
|
||||
value.map(val=>{
|
||||
data.push(val.key);
|
||||
});
|
||||
this.props.onInstall("role",data);
|
||||
this.props.onInstall("role", data, "install");
|
||||
};
|
||||
|
||||
render() {
|
||||
|
||||
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import {Typography, Select, Spin, message, notification, Button} from "antd";
|
||||
import debounce from 'lodash.debounce';
|
||||
import axios from "axios";
|
||||
import {withConfigContext} from "../../../../context/ConfigContext";
|
||||
import {handleApiError} from "../../../../js/Utils";
|
||||
|
||||
const {Text} = Typography;
|
||||
const {Option} = Select;
|
||||
|
||||
class RoleUninstall extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.lastFetchId = 0;
|
||||
this.fetchUser = debounce(this.fetchUser, 800);
|
||||
}
|
||||
|
||||
state = {
|
||||
data: [],
|
||||
value: [],
|
||||
fetching: false,
|
||||
};
|
||||
|
||||
fetchUser = value => {
|
||||
const config = this.props.context;
|
||||
this.lastFetchId += 1;
|
||||
const fetchId = this.lastFetchId;
|
||||
this.setState({data: [], fetching: true});
|
||||
|
||||
const uuid = this.props.uuid;
|
||||
|
||||
axios.get(
|
||||
window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.store+ "/subscription/" + uuid + "/"+
|
||||
"/ROLE?",
|
||||
).then(res => {
|
||||
if (res.status === 200) {
|
||||
if (fetchId !== this.lastFetchId) {
|
||||
// for fetch callback order
|
||||
return;
|
||||
}
|
||||
|
||||
const data = res.data.data.roles.map(role => ({
|
||||
text: role,
|
||||
value: role,
|
||||
}));
|
||||
|
||||
this.setState({data, fetching: false});
|
||||
}
|
||||
|
||||
}).catch((error) => {
|
||||
handleApiError(error,"Error occurred while trying to load roles.");
|
||||
this.setState({fetching: false});
|
||||
});
|
||||
};
|
||||
|
||||
handleChange = value => {
|
||||
this.setState({
|
||||
value,
|
||||
data: [],
|
||||
fetching: false,
|
||||
});
|
||||
};
|
||||
|
||||
install = () =>{
|
||||
const {value} = this.state;
|
||||
const data = [];
|
||||
value.map(val=>{
|
||||
data.push(val.key);
|
||||
});
|
||||
this.props.onInstall("role", data, "uninstall");
|
||||
};
|
||||
|
||||
render() {
|
||||
|
||||
const {fetching, data, value} = this.state;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Text>Start uninstalling the application for one or more roles by entering the corresponding role name. Select uninstall to automatically start uninstalling the application for the respective user role/roles.</Text>
|
||||
<br/>
|
||||
<br/>
|
||||
<Select
|
||||
mode="multiple"
|
||||
labelInValue
|
||||
value={value}
|
||||
placeholder="Search roles"
|
||||
notFoundContent={fetching ? <Spin size="small"/> : null}
|
||||
filterOption={false}
|
||||
onSearch={this.fetchUser}
|
||||
onChange={this.handleChange}
|
||||
style={{width: '100%'}}
|
||||
>
|
||||
{data.map(d => (
|
||||
<Option key={d.value}>{d.text}</Option>
|
||||
))}
|
||||
</Select>
|
||||
<div style={{paddingTop:10, textAlign:"right"}}>
|
||||
<Button disabled={value.length===0} htmlType="button" type="primary" onClick={this.install}>Install</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withConfigContext(RoleUninstall);
|
||||
@ -87,7 +87,7 @@ class UserInstall extends React.Component {
|
||||
value.map(val => {
|
||||
data.push(val.key);
|
||||
});
|
||||
this.props.onInstall("user", data);
|
||||
this.props.onInstall("user", data, "install");
|
||||
};
|
||||
|
||||
render() {
|
||||
|
||||
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import {Typography, Select, Spin, message, notification, Button} from "antd";
|
||||
import debounce from 'lodash.debounce';
|
||||
import axios from "axios";
|
||||
import {withConfigContext} from "../../../../context/ConfigContext";
|
||||
import {handleApiError} from "../../../../js/Utils";
|
||||
|
||||
const {Text} = Typography;
|
||||
const {Option} = Select;
|
||||
|
||||
class UserUninstall extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.lastFetchId = 0;
|
||||
this.fetchUser = debounce(this.fetchUser, 800);
|
||||
}
|
||||
|
||||
state = {
|
||||
data: [],
|
||||
value: [],
|
||||
fetching: false,
|
||||
};
|
||||
|
||||
fetchUser = (value) => {
|
||||
const config = this.props.context;
|
||||
this.lastFetchId += 1;
|
||||
const fetchId = this.lastFetchId;
|
||||
this.setState({data: [], fetching: true});
|
||||
|
||||
const uuid = this.props.uuid;
|
||||
|
||||
axios.get(
|
||||
window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.store+ "/subscription/" + uuid + "/"+
|
||||
"/USER?",
|
||||
|
||||
).then(res => {
|
||||
if (res.status === 200) {
|
||||
if (fetchId !== this.lastFetchId) {
|
||||
// for fetch callback order
|
||||
return;
|
||||
}
|
||||
const data = res.data.data.users.map(user => ({
|
||||
text: user,
|
||||
value: user,
|
||||
}));
|
||||
|
||||
this.setState({data, fetching: false});
|
||||
}
|
||||
|
||||
}).catch((error) => {
|
||||
handleApiError(error,"Error occurred while trying to load users.");
|
||||
this.setState({fetching: false});
|
||||
});
|
||||
};
|
||||
|
||||
handleChange = value => {
|
||||
this.setState({
|
||||
value,
|
||||
data: [],
|
||||
fetching: false,
|
||||
});
|
||||
};
|
||||
|
||||
uninstall = () => {
|
||||
const {value} = this.state;
|
||||
const data = [];
|
||||
value.map(val => {
|
||||
data.push(val.key);
|
||||
});
|
||||
this.props.onUninstall("user", data, "uninstall");
|
||||
};
|
||||
|
||||
render() {
|
||||
const {fetching, data, value} = this.state;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Text>Start uninstalling the application for one or more users by entering the corresponding user name. Select uninstall to automatically start uninstalling the application for the respective user/users. </Text>
|
||||
<p>Select users</p>
|
||||
<Select
|
||||
mode="multiple"
|
||||
labelInValue
|
||||
value={value}
|
||||
placeholder="Enter the username"
|
||||
notFoundContent={fetching ? <Spin size="small"/> : null}
|
||||
filterOption={false}
|
||||
onSearch={this.fetchUser}
|
||||
onChange={this.handleChange}
|
||||
style={{width: '100%'}}
|
||||
>
|
||||
{data.map(d => (
|
||||
<Option key={d.value}>{d.text}</Option>
|
||||
))}
|
||||
</Select>
|
||||
<div style={{paddingTop: 10, textAlign: "right"}}>
|
||||
<Button disabled={value.length===0} htmlType="button" type="primary" onClick={this.uninstall}>Uninstall</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withConfigContext(UserUninstall);
|
||||
@ -58,7 +58,7 @@
|
||||
}
|
||||
|
||||
.mobile-menu-button {
|
||||
margin-top: 4%;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
Header{
|
||||
@ -68,7 +68,7 @@
|
||||
}
|
||||
|
||||
.dashboard-body{
|
||||
margin-top: 15%;
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
.logo-image {
|
||||
@ -80,7 +80,7 @@
|
||||
@media only screen and (max-height: 350px) {
|
||||
|
||||
.mobile-menu-button{
|
||||
margin-top: 2%;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.dashboard-body{
|
||||
|
||||
@ -36,7 +36,9 @@ class Dashboard extends React.Component {
|
||||
this.state = {
|
||||
routes: props.routes,
|
||||
selectedKeys: [],
|
||||
deviceTypes: []
|
||||
deviceTypes: [],
|
||||
visible: false,
|
||||
collapsed: false
|
||||
};
|
||||
this.logo = this.props.context.theme.logo;
|
||||
}
|
||||
@ -72,20 +74,14 @@ class Dashboard extends React.Component {
|
||||
})
|
||||
};
|
||||
|
||||
//functions for show the drawer
|
||||
state = {
|
||||
visible: false,
|
||||
collapsed: false
|
||||
};
|
||||
|
||||
showDrawer = () => {
|
||||
showMobileNavigationBar = () => {
|
||||
this.setState({
|
||||
visible: true,
|
||||
collapsed: !this.state.collapsed,
|
||||
});
|
||||
};
|
||||
|
||||
onClose = () => {
|
||||
onCloseMobileNavigationBar = () => {
|
||||
this.setState({
|
||||
visible: false,
|
||||
});
|
||||
@ -153,7 +149,7 @@ class Dashboard extends React.Component {
|
||||
<Layout className="mobile-layout">
|
||||
|
||||
<div className="mobile-menu-button">
|
||||
<Button type="link" onClick={this.showDrawer}>
|
||||
<Button type="link" onClick={this.showMobileNavigationBar}>
|
||||
<Icon type={this.state.collapsed ? 'menu-fold' : 'menu-unfold'} className="bar-icon"/>
|
||||
</Button>
|
||||
</div>
|
||||
@ -163,7 +159,7 @@ class Dashboard extends React.Component {
|
||||
</Link>}
|
||||
placement="left"
|
||||
closable={false}
|
||||
onClose={this.onClose}
|
||||
onClose={this.onCloseMobileNavigationBar}
|
||||
visible={this.state.visible}
|
||||
getContainer={false}
|
||||
style={{position: 'absolute'}}
|
||||
|
||||
@ -29,8 +29,8 @@
|
||||
<artifactId>io.entgra.device.mgt.ui</artifactId>
|
||||
<version>3.2.9-SNAPSHOT</version>
|
||||
<packaging>war</packaging>
|
||||
<name>WSO2 Carbon - Device Management UI Component</name>
|
||||
<url>http://wso2.org</url>
|
||||
<name>Entgra - Device Management UI Component</name>
|
||||
<url>https://entgra.io</url>
|
||||
<description>This Component contains Device Management UI</description>
|
||||
<dependencies>
|
||||
</dependencies>
|
||||
|
||||
@ -562,4 +562,18 @@ public interface DeviceDAO {
|
||||
*/
|
||||
List<DeviceLocationHistory> getDeviceLocationInfo(DeviceIdentifier deviceIdentifier, long from, long to)
|
||||
throws DeviceManagementDAOException;
|
||||
|
||||
/**
|
||||
* This method is used to get the details of subscribed devices.
|
||||
*
|
||||
* @param deviceIds device ids of the subscribed devices.
|
||||
* @param tenantId Id of the current tenant.
|
||||
* @param offsetValue offset value for get paginated request.
|
||||
* @param limitValue limit value for get paginated request.
|
||||
* @param status status of the devices.
|
||||
* @return devices - subscribed device details list
|
||||
* @throws {@link DeviceManagementDAOException} if connections establishment fails.
|
||||
*/
|
||||
List<Device> getSubscribedDevices(int offsetValue, int limitValue, List<Integer> deviceIds,
|
||||
int tenantId, String status) throws DeviceManagementDAOException;
|
||||
}
|
||||
|
||||
@ -65,7 +65,6 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
|
||||
|
||||
|
||||
@ -34,6 +34,7 @@ import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
/**
|
||||
* This class holds the generic implementation of DeviceDAO which can be used to support ANSI db syntax.
|
||||
@ -583,7 +584,68 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl {
|
||||
return devices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Device> getSubscribedDevices(int offsetValue, int limitValue,
|
||||
List<Integer> deviceIds, int tenantId, String status)
|
||||
throws DeviceManagementDAOException {
|
||||
Connection conn;
|
||||
|
||||
try {
|
||||
conn = this.getConnection();
|
||||
int index = 1;
|
||||
|
||||
boolean isStatusProvided = false;
|
||||
StringJoiner joiner = new StringJoiner(",",
|
||||
"SELECT " +
|
||||
"f.ID AS DEVICE_ID, f.NAME AS DEVICE_NAME, f.DESCRIPTION AS DESCRIPTION, " +
|
||||
"f.DEVICE_TYPE_ID, f.DEVICE_IDENTIFICATION AS DEVICE_IDENTIFICATION, " +
|
||||
"e.ID AS ENROLMENT_ID, e.OWNER, e.OWNERSHIP, e.DATE_OF_ENROLMENT, " +
|
||||
"e.DATE_OF_LAST_UPDATE, e.STATUS, t.NAME AS DEVICE_TYPE " +
|
||||
"FROM DM_ENROLMENT AS e,DM_DEVICE AS f, DM_DEVICE_TYPE t "+
|
||||
"WHERE " +
|
||||
"e.DEVICE_ID=f.ID AND " +
|
||||
"e.DEVICE_ID IN (", ") AND e.TENANT_ID=?");
|
||||
|
||||
deviceIds.stream().map(ignored -> "?").forEach(joiner::add);
|
||||
String query = joiner.toString();
|
||||
|
||||
if (status != null && !status.isEmpty()) {
|
||||
query = query + " AND e.STATUS=?";
|
||||
isStatusProvided = true;
|
||||
}
|
||||
|
||||
query = query + " LIMIT ?,?";
|
||||
|
||||
try (PreparedStatement ps = conn.prepareStatement(query)) {
|
||||
|
||||
for (Integer deviceId : deviceIds) {
|
||||
ps.setObject(index++, deviceId);
|
||||
}
|
||||
|
||||
ps.setInt(index++, tenantId);
|
||||
if (isStatusProvided) {
|
||||
ps.setString(index++, status);
|
||||
}
|
||||
ps.setInt(index++, offsetValue);
|
||||
ps.setInt(index, limitValue);
|
||||
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
List<Device> devices = new ArrayList<>();
|
||||
while (rs.next()) {
|
||||
devices.add(DeviceManagementDAOUtil.loadDevice(rs));
|
||||
}
|
||||
return devices;
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
String msg = "Error occurred while retrieving information of all registered devices " +
|
||||
"according to device ids and the limit area.";
|
||||
log.error(msg, e);
|
||||
throw new DeviceManagementDAOException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
private Connection getConnection() throws SQLException {
|
||||
return DeviceManagementDAOFactory.getConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,6 +37,7 @@ import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
/**
|
||||
* This class holds the generic implementation of DeviceDAO which can be used to support ANSI db syntax.
|
||||
@ -588,6 +589,67 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl {
|
||||
return devices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Device> getSubscribedDevices(int offsetValue, int limitValue,
|
||||
List<Integer> deviceIds, int tenantId, String status)
|
||||
throws DeviceManagementDAOException {
|
||||
Connection conn;
|
||||
|
||||
try {
|
||||
conn = this.getConnection();
|
||||
int index = 1;
|
||||
|
||||
boolean isStatusProvided = false;
|
||||
StringJoiner joiner = new StringJoiner(",",
|
||||
"SELECT " +
|
||||
"f.ID AS DEVICE_ID, f.NAME AS DEVICE_NAME, f.DESCRIPTION AS DESCRIPTION, " +
|
||||
"f.DEVICE_TYPE_ID, f.DEVICE_IDENTIFICATION AS DEVICE_IDENTIFICATION, " +
|
||||
"e.ID AS ENROLMENT_ID, e.OWNER, e.OWNERSHIP, e.DATE_OF_ENROLMENT, " +
|
||||
"e.DATE_OF_LAST_UPDATE, e.STATUS, t.NAME AS DEVICE_TYPE " +
|
||||
"FROM DM_ENROLMENT AS e,DM_DEVICE AS f, DM_DEVICE_TYPE t " +
|
||||
"WHERE " +
|
||||
"e.DEVICE_ID=f.ID AND " +
|
||||
"e.DEVICE_ID IN (", ") AND e.TENANT_ID=?");
|
||||
|
||||
deviceIds.stream().map(ignored -> "?").forEach(joiner::add);
|
||||
String query = joiner.toString();
|
||||
|
||||
if (status != null && !status.isEmpty()) {
|
||||
query = query + " AND e.STATUS=?";
|
||||
isStatusProvided = true;
|
||||
}
|
||||
|
||||
query = query + " ORDER BY ENROLMENT_ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
|
||||
|
||||
try (PreparedStatement ps = conn.prepareStatement(query)) {
|
||||
|
||||
for (Integer deviceId : deviceIds) {
|
||||
ps.setObject(index++, deviceId);
|
||||
}
|
||||
|
||||
ps.setInt(index++, tenantId);
|
||||
if (isStatusProvided) {
|
||||
ps.setString(index++, status);
|
||||
}
|
||||
ps.setInt(index++, offsetValue);
|
||||
ps.setInt(index, limitValue);
|
||||
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
List<Device> devices = new ArrayList<>();
|
||||
while (rs.next()) {
|
||||
devices.add(DeviceManagementDAOUtil.loadDevice(rs));
|
||||
}
|
||||
return devices;
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
String msg = "Error occurred while retrieving information of all registered devices " +
|
||||
"according to device ids and the limit area.";
|
||||
log.error(msg, e);
|
||||
throw new DeviceManagementDAOException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
private Connection getConnection() throws SQLException {
|
||||
return DeviceManagementDAOFactory.getConnection();
|
||||
}
|
||||
|
||||
@ -34,6 +34,7 @@ import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
/**
|
||||
* This class holds the generic implementation of DeviceDAO which can be used to support ANSI db syntax.
|
||||
@ -565,6 +566,67 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl {
|
||||
}
|
||||
return devices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Device> getSubscribedDevices(int offsetValue, int limitValue,
|
||||
List<Integer> deviceIds, int tenantId, String status)
|
||||
throws DeviceManagementDAOException {
|
||||
Connection conn;
|
||||
|
||||
try {
|
||||
conn = this.getConnection();
|
||||
int index = 1;
|
||||
|
||||
boolean isStatusProvided = false;
|
||||
StringJoiner joiner = new StringJoiner(",",
|
||||
"SELECT " +
|
||||
"f.ID AS DEVICE_ID, f.NAME AS DEVICE_NAME, f.DESCRIPTION AS DESCRIPTION, " +
|
||||
"f.DEVICE_TYPE_ID, f.DEVICE_IDENTIFICATION AS DEVICE_IDENTIFICATION, " +
|
||||
"e.ID AS ENROLMENT_ID, e.OWNER, e.OWNERSHIP, e.DATE_OF_ENROLMENT, " +
|
||||
"e.DATE_OF_LAST_UPDATE, e.STATUS, t.NAME AS DEVICE_TYPE " +
|
||||
"FROM DM_ENROLMENT AS e,DM_DEVICE AS f, DM_DEVICE_TYPE t "+
|
||||
"WHERE " +
|
||||
"e.DEVICE_ID=f.ID AND " +
|
||||
"e.DEVICE_ID IN (", ") AND e.TENANT_ID=?");
|
||||
|
||||
deviceIds.stream().map(ignored -> "?").forEach(joiner::add);
|
||||
String query = joiner.toString();
|
||||
|
||||
if (status != null && !status.isEmpty()) {
|
||||
query = query + " AND e.STATUS=?";
|
||||
isStatusProvided = true;
|
||||
}
|
||||
|
||||
query = query + " LIMIT ? OFFSET ?";
|
||||
|
||||
try (PreparedStatement ps = conn.prepareStatement(query)) {
|
||||
|
||||
for (Integer deviceId : deviceIds) {
|
||||
ps.setObject(index++, deviceId);
|
||||
}
|
||||
|
||||
ps.setInt(index++, tenantId);
|
||||
if (isStatusProvided) {
|
||||
ps.setString(index++, status);
|
||||
}
|
||||
ps.setInt(index++, offsetValue);
|
||||
ps.setInt(index, limitValue);
|
||||
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
List<Device> devices = new ArrayList<>();
|
||||
while (rs.next()) {
|
||||
devices.add(DeviceManagementDAOUtil.loadDevice(rs));
|
||||
}
|
||||
return devices;
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
String msg = "Error occurred while retrieving information of all registered devices " +
|
||||
"according to device ids and the limit area.";
|
||||
log.error(msg, e);
|
||||
throw new DeviceManagementDAOException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
private Connection getConnection() throws SQLException {
|
||||
return DeviceManagementDAOFactory.getConnection();
|
||||
|
||||
@ -34,6 +34,7 @@ import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
/**
|
||||
* This class holds the generic implementation of DeviceDAO which can be used to support ANSI db syntax.
|
||||
@ -521,6 +522,67 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl {
|
||||
return devices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Device> getSubscribedDevices(int offsetValue, int limitValue,
|
||||
List<Integer> deviceIds, int tenantId, String status)
|
||||
throws DeviceManagementDAOException {
|
||||
Connection conn;
|
||||
|
||||
try {
|
||||
conn = this.getConnection();
|
||||
int index = 1;
|
||||
|
||||
boolean isStatusProvided = false;
|
||||
StringJoiner joiner = new StringJoiner(",",
|
||||
"SELECT " +
|
||||
"f.ID AS DEVICE_ID, f.NAME AS DEVICE_NAME, f.DESCRIPTION AS DESCRIPTION, " +
|
||||
"f.DEVICE_TYPE_ID, f.DEVICE_IDENTIFICATION AS DEVICE_IDENTIFICATION, " +
|
||||
"e.ID AS ENROLMENT_ID, e.OWNER, e.OWNERSHIP, e.DATE_OF_ENROLMENT, " +
|
||||
"e.DATE_OF_LAST_UPDATE, e.STATUS, t.NAME AS DEVICE_TYPE " +
|
||||
"FROM DM_ENROLMENT AS e,DM_DEVICE AS f, DM_DEVICE_TYPE t "+
|
||||
"WHERE " +
|
||||
"e.DEVICE_ID=f.ID AND " +
|
||||
"e.DEVICE_ID IN (", ") AND e.TENANT_ID=?");
|
||||
|
||||
deviceIds.stream().map(ignored -> "?").forEach(joiner::add);
|
||||
String query = joiner.toString();
|
||||
|
||||
if (status != null && !status.isEmpty()) {
|
||||
query = query + " AND e.STATUS=?";
|
||||
isStatusProvided = true;
|
||||
}
|
||||
|
||||
query = query + " LIMIT ?,?";
|
||||
|
||||
try (PreparedStatement ps = conn.prepareStatement(query)) {
|
||||
|
||||
for (Integer deviceId : deviceIds) {
|
||||
ps.setObject(index++, deviceId);
|
||||
}
|
||||
|
||||
ps.setInt(index++, tenantId);
|
||||
if (isStatusProvided) {
|
||||
ps.setString(index++, status);
|
||||
}
|
||||
ps.setInt(index++, offsetValue);
|
||||
ps.setInt(index, limitValue);
|
||||
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
List<Device> devices = new ArrayList<>();
|
||||
while (rs.next()) {
|
||||
devices.add(DeviceManagementDAOUtil.loadDevice(rs));
|
||||
}
|
||||
return devices;
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
String msg = "Error occurred while retrieving information of all registered devices " +
|
||||
"according to device ids and the limit area.";
|
||||
log.error(msg, e);
|
||||
throw new DeviceManagementDAOException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
private Connection getConnection() throws SQLException {
|
||||
return DeviceManagementDAOFactory.getConnection();
|
||||
}
|
||||
|
||||
@ -759,7 +759,6 @@ public interface DeviceManagementProviderService {
|
||||
|
||||
DeviceTypeVersion getDeviceTypeVersion(String deviceTypeName, String version) throws
|
||||
DeviceManagementException;
|
||||
|
||||
/**
|
||||
* Retrieves a list of configurations of a specific device
|
||||
* using the device's properties
|
||||
@ -782,4 +781,18 @@ public interface DeviceManagementProviderService {
|
||||
* @return tru if device transferee, otherwise false
|
||||
*/
|
||||
List<String> transferDeviceToTenant(DeviceTransferRequest deviceTransferRequest) throws DeviceManagementException, DeviceNotFoundException;
|
||||
|
||||
/**
|
||||
* This method retrieves a list of subscribed devices.
|
||||
*
|
||||
* @param devicesIds devices ids of the subscribed devices.
|
||||
* @param offsetValue offset value for get paginated request.
|
||||
* @param limitValue limit value for get paginated request.
|
||||
* @param status status of the devices.
|
||||
* @return {@link PaginationResult}
|
||||
* @throws {@link DeviceManagementException} if any service level or DAO level error occurs.
|
||||
*/
|
||||
PaginationResult getAppSubscribedDevices(int offsetValue, int limitValue,
|
||||
List<Integer> devicesIds, String status)
|
||||
throws DeviceManagementException;
|
||||
}
|
||||
|
||||
@ -3665,4 +3665,39 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
|
||||
deviceConfiguration.setDeviceOwner(deviceOwner);
|
||||
return deviceConfiguration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaginationResult getAppSubscribedDevices(int offsetValue, int limitValue,
|
||||
List<Integer> devicesIds, String status)
|
||||
throws DeviceManagementException {
|
||||
|
||||
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Getting all devices details for device ids: " + devicesIds);
|
||||
}
|
||||
PaginationResult paginationResult = new PaginationResult();
|
||||
int count;
|
||||
List<Device> SubscribedDeviceDetails;
|
||||
try {
|
||||
DeviceManagementDAOFactory.openConnection();
|
||||
SubscribedDeviceDetails = deviceDAO
|
||||
.getSubscribedDevices(offsetValue, limitValue, devicesIds, tenantId, status);
|
||||
count = SubscribedDeviceDetails.size();
|
||||
|
||||
} catch (DeviceManagementDAOException e) {
|
||||
String msg = "Error occurred while retrieving device list for device ids " + devicesIds;
|
||||
log.error(msg, e);
|
||||
throw new DeviceManagementException(msg, e);
|
||||
} catch (SQLException e) {
|
||||
String msg = "Error occurred while opening a connection to the data source";
|
||||
log.error(msg, e);
|
||||
throw new DeviceManagementException(msg, e);
|
||||
} finally {
|
||||
DeviceManagementDAOFactory.closeConnection();
|
||||
}
|
||||
paginationResult.setData(getAllDeviceInfo(SubscribedDeviceDetails));
|
||||
paginationResult.setRecordsFiltered(count);
|
||||
paginationResult.setRecordsTotal(count);
|
||||
return paginationResult;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user