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.dto.ScheduledSubscriptionDTO;
|
||||||
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.PaginationResult;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -83,4 +84,30 @@ public interface SubscriptionManager {
|
|||||||
* @throws SubscriptionManagementException if error occurred while updating the status of the subscription
|
* @throws SubscriptionManagementException if error occurred while updating the status of the subscription
|
||||||
*/
|
*/
|
||||||
void updateScheduledSubscriptionStatus(int id, ExecutionStatus status) throws SubscriptionManagementException;
|
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}
|
* @return {@link ScheduledSubscriptionDTO}
|
||||||
* @throws ApplicationManagementDAOException if error occurred while retrieving the subscription
|
* @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;
|
throws ApplicationManagementDAOException;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -356,6 +356,7 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
|
|||||||
+ "DS.UNSUBSCRIBED_BY AS UNSUBSCRIBED_BY, "
|
+ "DS.UNSUBSCRIBED_BY AS UNSUBSCRIBED_BY, "
|
||||||
+ "DS.UNSUBSCRIBED_TIMESTAMP AS UNSUBSCRIBED_AT, "
|
+ "DS.UNSUBSCRIBED_TIMESTAMP AS UNSUBSCRIBED_AT, "
|
||||||
+ "DS.ACTION_TRIGGERED_FROM AS ACTION_TRIGGERED_FROM, "
|
+ "DS.ACTION_TRIGGERED_FROM AS ACTION_TRIGGERED_FROM, "
|
||||||
|
+ "DS.STATUS AS STATUS,"
|
||||||
+ "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=?";
|
||||||
@ -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
|
@Override
|
||||||
public List<ScheduledSubscriptionDTO> getScheduledSubscriptionByStatus(ExecutionStatus status, boolean deleted)
|
public List<ScheduledSubscriptionDTO> getScheduledSubscriptionByStatus(ExecutionStatus status, boolean deleted)
|
||||||
throws ApplicationManagementDAOException {
|
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
|
@Override
|
||||||
public ScheduledSubscriptionDTO getPendingScheduledSubscriptionByTaskName(String taskName)
|
public ScheduledSubscriptionDTO getPendingScheduledSubscriptionByTaskName(String taskName)
|
||||||
throws ApplicationManagementDAOException {
|
throws ApplicationManagementDAOException {
|
||||||
@ -957,4 +1036,45 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
|
|||||||
throw new ApplicationManagementDAOException(msg, e);
|
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.device.mgt.core.util.MDMIOSOperationUtil;
|
||||||
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.IOException;
|
import java.io.IOException;
|
||||||
@ -684,6 +685,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
|
|||||||
app.setLocation(application.getApplicationReleases().get(0).getInstallerPath());
|
app.setLocation(application.getApplicationReleases().get(0).getInstallerPath());
|
||||||
return MDMAndroidOperationUtil.createInstallAppOperation(app);
|
return MDMAndroidOperationUtil.createInstallAppOperation(app);
|
||||||
} else if (SubAction.UNINSTALL.toString().equalsIgnoreCase(action)) {
|
} else if (SubAction.UNINSTALL.toString().equalsIgnoreCase(action)) {
|
||||||
|
app.setType(mobileAppType);
|
||||||
return MDMAndroidOperationUtil.createAppUninstallOperation(app);
|
return MDMAndroidOperationUtil.createAppUninstallOperation(app);
|
||||||
} else {
|
} else {
|
||||||
String msg = "Invalid Action is found. Action: " + action;
|
String msg = "Invalid Action is found. Action: " + action;
|
||||||
@ -793,10 +795,117 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
|
|||||||
log.error(msg, e);
|
log.error(msg, e);
|
||||||
throw new ApplicationManagementException(msg, e);
|
throw new ApplicationManagementException(msg, e);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
String msg = "Error while installing the enrollment with id: " + applicationPolicyDTO.getApplicationDTO()
|
String msg = "Error while installing the enrollment with id: " + applicationPolicyDTO.getApplicationDTO().getId()
|
||||||
.getId() + " on device";
|
+ " on device";
|
||||||
log.error(msg, e);
|
log.error(msg, e);
|
||||||
throw new ApplicationManagementException(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{
|
.mobile-menu-button{
|
||||||
margin-top: 4%;
|
margin-top: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
Header{
|
Header{
|
||||||
@ -68,7 +68,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.dashboard-body{
|
.dashboard-body{
|
||||||
margin-top: 14%;
|
margin-top: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo-image {
|
.logo-image {
|
||||||
@ -80,7 +80,7 @@
|
|||||||
@media screen and (max-height: 350px) {
|
@media screen and (max-height: 350px) {
|
||||||
|
|
||||||
.mobile-menu-button{
|
.mobile-menu-button{
|
||||||
margin-top: 2%;
|
margin-top: 15px;
|
||||||
}
|
}
|
||||||
.dashboard-body{
|
.dashboard-body{
|
||||||
margin-top: 9%;
|
margin-top: 9%;
|
||||||
|
|||||||
@ -40,14 +40,14 @@ class Dashboard extends React.Component {
|
|||||||
this.Logo = this.config.theme.logo;
|
this.Logo = this.config.theme.logo;
|
||||||
}
|
}
|
||||||
|
|
||||||
showDrawer = () => {
|
showMobileNavigationBar = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
visible: true,
|
visible: true,
|
||||||
collapsed: !this.state.collapsed
|
collapsed: !this.state.collapsed
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
onClose = () => {
|
onCloseMobileNavigationBar = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
visible: false,
|
visible: false,
|
||||||
});
|
});
|
||||||
@ -131,7 +131,7 @@ class Dashboard extends React.Component {
|
|||||||
|
|
||||||
<Layout className="mobile-layout">
|
<Layout className="mobile-layout">
|
||||||
<div className="mobile-menu-button">
|
<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"/>
|
<Icon type={this.state.collapsed ? 'menu-fold' : 'menu-unfold'} className="bar-icon"/>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@ -146,7 +146,7 @@ class Dashboard extends React.Component {
|
|||||||
}
|
}
|
||||||
placement="left"
|
placement="left"
|
||||||
closable={false}
|
closable={false}
|
||||||
onClose={this.onClose}
|
onClose={this.onCloseMobileNavigationBar}
|
||||||
visible={this.state.visible}
|
visible={this.state.visible}
|
||||||
getContainer={false}
|
getContainer={false}
|
||||||
style={{position: 'absolute'}}>
|
style={{position: 'absolute'}}>
|
||||||
@ -214,6 +214,6 @@ class Dashboard extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
export default withConfigContext(Dashboard);
|
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.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
import io.swagger.annotations.ApiParam;
|
import io.swagger.annotations.ApiParam;
|
||||||
|
import io.swagger.annotations.ApiResponse;
|
||||||
import io.swagger.annotations.ApiResponses;
|
import io.swagger.annotations.ApiResponses;
|
||||||
import io.swagger.annotations.Extension;
|
import io.swagger.annotations.Extension;
|
||||||
import io.swagger.annotations.ExtensionProperty;
|
import io.swagger.annotations.ExtensionProperty;
|
||||||
@ -27,15 +28,17 @@ import io.swagger.annotations.Info;
|
|||||||
import io.swagger.annotations.SwaggerDefinition;
|
import io.swagger.annotations.SwaggerDefinition;
|
||||||
import io.swagger.annotations.Tag;
|
import io.swagger.annotations.Tag;
|
||||||
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.mgt.common.DeviceIdentifier;
|
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
import javax.ws.rs.Consumes;
|
|
||||||
import javax.ws.rs.POST;
|
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
import javax.ws.rs.QueryParam;
|
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.MediaType;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -181,4 +184,133 @@ public interface SubscriptionManagementAPI {
|
|||||||
)
|
)
|
||||||
@QueryParam("timestamp") String timestamp
|
@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.
|
* 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.exception.ApplicationManagementException;
|
||||||
import org.wso2.carbon.device.application.mgt.common.services.SubscriptionManager;
|
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.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.BadRequestException;
|
||||||
import org.wso2.carbon.device.application.mgt.core.exception.ForbiddenException;
|
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.exception.NotFoundException;
|
||||||
import org.wso2.carbon.device.application.mgt.core.task.ScheduledAppSubscriptionTaskManager;
|
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.core.util.APIUtil;
|
||||||
import org.wso2.carbon.device.application.mgt.store.api.services.SubscriptionManagementAPI;
|
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 org.wso2.carbon.device.mgt.common.DeviceIdentifier;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
import javax.ws.rs.POST;
|
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
import javax.ws.rs.QueryParam;
|
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 javax.ws.rs.core.Response;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
@ -114,6 +107,7 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@POST
|
@POST
|
||||||
@Path("/{uuid}/{subType}/{action}")
|
@Path("/{uuid}/{subType}/{action}")
|
||||||
@ -185,4 +179,114 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
|
|||||||
}
|
}
|
||||||
return Response.status(Response.Status.CREATED).build();
|
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 Reviews from "./review/Reviews";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import AppInstallModal from "./install/AppInstallModal";
|
import AppInstallModal from "./install/AppInstallModal";
|
||||||
|
import AppUninstallModal from "./install/AppUninstallModal";
|
||||||
import CurrentUsersReview from "./review/CurrentUsersReview";
|
import CurrentUsersReview from "./review/CurrentUsersReview";
|
||||||
import {withConfigContext} from "../../../context/ConfigContext";
|
import {withConfigContext} from "../../../context/ConfigContext";
|
||||||
import {handleApiError} from "../../../js/Utils";
|
import {handleApiError} from "../../../js/Utils";
|
||||||
@ -36,11 +37,12 @@ class ReleaseView extends React.Component {
|
|||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
loading: false,
|
loading: false,
|
||||||
appInstallModalVisible: false
|
appInstallModalVisible: false,
|
||||||
|
appUninstallModalVisible: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
installApp = (type, payload) => {
|
appOperation = (type, payload, operation) => {
|
||||||
const config = this.props.context;
|
const config = this.props.context;
|
||||||
const release = this.props.app.applicationReleases[0];
|
const release = this.props.app.applicationReleases[0];
|
||||||
const {uuid} = release;
|
const {uuid} = release;
|
||||||
@ -48,7 +50,7 @@ class ReleaseView extends React.Component {
|
|||||||
this.setState({
|
this.setState({
|
||||||
loading: true,
|
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(
|
axios.post(
|
||||||
url,
|
url,
|
||||||
payload,
|
payload,
|
||||||
@ -64,7 +66,7 @@ class ReleaseView extends React.Component {
|
|||||||
notification["success"]({
|
notification["success"]({
|
||||||
message: 'Done!',
|
message: 'Done!',
|
||||||
description:
|
description:
|
||||||
'App installed triggered.',
|
'App '+operation+'ed triggered.',
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.setState({
|
this.setState({
|
||||||
@ -74,24 +76,31 @@ class ReleaseView extends React.Component {
|
|||||||
message: "There was a problem",
|
message: "There was a problem",
|
||||||
duration: 0,
|
duration: 0,
|
||||||
description:
|
description:
|
||||||
"Error occurred while installing app",
|
"Error occurred while "+operation+"ing app",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
handleApiError(error,"Error occurred while installing the app.");
|
handleApiError(error,"Error occurred while "+operation+"ing the app.");
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
showAppInstallModal = () => {
|
showAppInstallModal = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
appInstallModalVisible: true
|
appInstallModalVisible: true
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
closeAppInstallModal = () => {
|
closeAppOperationModal = () => {
|
||||||
this.setState({
|
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}
|
uuid={release.uuid}
|
||||||
visible={this.state.appInstallModalVisible}
|
visible={this.state.appInstallModalVisible}
|
||||||
deviceType = {deviceType}
|
deviceType = {deviceType}
|
||||||
onClose={this.closeAppInstallModal}
|
onClose={this.closeAppOperationModal}
|
||||||
onInstall={this.installApp}/>
|
onInstall={this.appOperation}/>
|
||||||
|
<AppUninstallModal
|
||||||
|
uuid={release.uuid}
|
||||||
|
visible={this.state.appUninstallModalVisible}
|
||||||
|
deviceType = {deviceType}
|
||||||
|
onClose={this.closeAppOperationModal}
|
||||||
|
onUninstall={this.appOperation}/>
|
||||||
<div className="release">
|
<div className="release">
|
||||||
<Row>
|
<Row>
|
||||||
<Col xl={4} sm={6} xs={8} className="release-icon">
|
<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>
|
htmlType="button" type="primary" icon="download">Install</Button>
|
||||||
</Button.Group>
|
</Button.Group>
|
||||||
</div>
|
</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>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Divider/>
|
<Divider/>
|
||||||
|
|||||||
@ -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
|
type: device.type
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
this.props.onInstall("devices", payload);
|
this.props.onInstall("devices", payload, "install");
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
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;
|
const config = this.props.context;
|
||||||
this.setState({data: [], fetching: true});
|
this.setState({data: [], fetching: true});
|
||||||
|
|
||||||
axios.post(
|
axios.get(
|
||||||
window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.deviceMgt+"/groups?name=" + value,
|
window.location.origin+ config.serverConfig.invoker.uri + config.serverConfig.invoker.deviceMgt+"/groups?name=" + value,
|
||||||
|
|
||||||
).then(res => {
|
).then(res => {
|
||||||
@ -85,7 +85,7 @@ class GroupInstall extends React.Component {
|
|||||||
value.map(val=>{
|
value.map(val=>{
|
||||||
data.push(val.key);
|
data.push(val.key);
|
||||||
});
|
});
|
||||||
this.props.onInstall("group",data);
|
this.props.onInstall("group", data, "install");
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
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=>{
|
value.map(val=>{
|
||||||
data.push(val.key);
|
data.push(val.key);
|
||||||
});
|
});
|
||||||
this.props.onInstall("role",data);
|
this.props.onInstall("role", data, "install");
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
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 => {
|
value.map(val => {
|
||||||
data.push(val.key);
|
data.push(val.key);
|
||||||
});
|
});
|
||||||
this.props.onInstall("user", data);
|
this.props.onInstall("user", data, "install");
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
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 {
|
.mobile-menu-button {
|
||||||
margin-top: 4%;
|
margin-top: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
Header{
|
Header{
|
||||||
@ -68,7 +68,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.dashboard-body{
|
.dashboard-body{
|
||||||
margin-top: 15%;
|
margin-top: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo-image {
|
.logo-image {
|
||||||
@ -80,7 +80,7 @@
|
|||||||
@media only screen and (max-height: 350px) {
|
@media only screen and (max-height: 350px) {
|
||||||
|
|
||||||
.mobile-menu-button{
|
.mobile-menu-button{
|
||||||
margin-top: 2%;
|
margin-top: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dashboard-body{
|
.dashboard-body{
|
||||||
|
|||||||
@ -36,7 +36,9 @@ class Dashboard extends React.Component {
|
|||||||
this.state = {
|
this.state = {
|
||||||
routes: props.routes,
|
routes: props.routes,
|
||||||
selectedKeys: [],
|
selectedKeys: [],
|
||||||
deviceTypes: []
|
deviceTypes: [],
|
||||||
|
visible: false,
|
||||||
|
collapsed: false
|
||||||
};
|
};
|
||||||
this.logo = this.props.context.theme.logo;
|
this.logo = this.props.context.theme.logo;
|
||||||
}
|
}
|
||||||
@ -72,20 +74,14 @@ class Dashboard extends React.Component {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
//functions for show the drawer
|
showMobileNavigationBar = () => {
|
||||||
state = {
|
|
||||||
visible: false,
|
|
||||||
collapsed: false
|
|
||||||
};
|
|
||||||
|
|
||||||
showDrawer = () => {
|
|
||||||
this.setState({
|
this.setState({
|
||||||
visible: true,
|
visible: true,
|
||||||
collapsed: !this.state.collapsed,
|
collapsed: !this.state.collapsed,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
onClose = () => {
|
onCloseMobileNavigationBar = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
visible: false,
|
visible: false,
|
||||||
});
|
});
|
||||||
@ -153,7 +149,7 @@ class Dashboard extends React.Component {
|
|||||||
<Layout className="mobile-layout">
|
<Layout className="mobile-layout">
|
||||||
|
|
||||||
<div className="mobile-menu-button">
|
<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"/>
|
<Icon type={this.state.collapsed ? 'menu-fold' : 'menu-unfold'} className="bar-icon"/>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@ -163,7 +159,7 @@ class Dashboard extends React.Component {
|
|||||||
</Link>}
|
</Link>}
|
||||||
placement="left"
|
placement="left"
|
||||||
closable={false}
|
closable={false}
|
||||||
onClose={this.onClose}
|
onClose={this.onCloseMobileNavigationBar}
|
||||||
visible={this.state.visible}
|
visible={this.state.visible}
|
||||||
getContainer={false}
|
getContainer={false}
|
||||||
style={{position: 'absolute'}}
|
style={{position: 'absolute'}}
|
||||||
|
|||||||
@ -29,8 +29,8 @@
|
|||||||
<artifactId>io.entgra.device.mgt.ui</artifactId>
|
<artifactId>io.entgra.device.mgt.ui</artifactId>
|
||||||
<version>3.2.9-SNAPSHOT</version>
|
<version>3.2.9-SNAPSHOT</version>
|
||||||
<packaging>war</packaging>
|
<packaging>war</packaging>
|
||||||
<name>WSO2 Carbon - Device Management UI Component</name>
|
<name>Entgra - Device Management UI Component</name>
|
||||||
<url>http://wso2.org</url>
|
<url>https://entgra.io</url>
|
||||||
<description>This Component contains Device Management UI</description>
|
<description>This Component contains Device Management UI</description>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
@ -562,4 +562,18 @@ public interface DeviceDAO {
|
|||||||
*/
|
*/
|
||||||
List<DeviceLocationHistory> getDeviceLocationInfo(DeviceIdentifier deviceIdentifier, long from, long to)
|
List<DeviceLocationHistory> getDeviceLocationInfo(DeviceIdentifier deviceIdentifier, long from, long to)
|
||||||
throws DeviceManagementDAOException;
|
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.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.StringJoiner;
|
import java.util.StringJoiner;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
|
public abstract class AbstractDeviceDAOImpl implements DeviceDAO {
|
||||||
|
|
||||||
|
|||||||
@ -34,6 +34,7 @@ import java.sql.SQLException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
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.
|
* This class holds the generic implementation of DeviceDAO which can be used to support ANSI db syntax.
|
||||||
@ -583,6 +584,67 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl {
|
|||||||
return devices;
|
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 {
|
private Connection getConnection() throws SQLException {
|
||||||
return DeviceManagementDAOFactory.getConnection();
|
return DeviceManagementDAOFactory.getConnection();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,6 +37,7 @@ import java.sql.SQLException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
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.
|
* 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;
|
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 {
|
private Connection getConnection() throws SQLException {
|
||||||
return DeviceManagementDAOFactory.getConnection();
|
return DeviceManagementDAOFactory.getConnection();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,6 +34,7 @@ import java.sql.SQLException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
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.
|
* This class holds the generic implementation of DeviceDAO which can be used to support ANSI db syntax.
|
||||||
@ -566,6 +567,67 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl {
|
|||||||
return devices;
|
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 {
|
private Connection getConnection() throws SQLException {
|
||||||
return DeviceManagementDAOFactory.getConnection();
|
return DeviceManagementDAOFactory.getConnection();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,6 +34,7 @@ import java.sql.SQLException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
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.
|
* 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;
|
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 {
|
private Connection getConnection() throws SQLException {
|
||||||
return DeviceManagementDAOFactory.getConnection();
|
return DeviceManagementDAOFactory.getConnection();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -759,7 +759,6 @@ public interface DeviceManagementProviderService {
|
|||||||
|
|
||||||
DeviceTypeVersion getDeviceTypeVersion(String deviceTypeName, String version) throws
|
DeviceTypeVersion getDeviceTypeVersion(String deviceTypeName, String version) throws
|
||||||
DeviceManagementException;
|
DeviceManagementException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a list of configurations of a specific device
|
* Retrieves a list of configurations of a specific device
|
||||||
* using the device's properties
|
* using the device's properties
|
||||||
@ -782,4 +781,18 @@ public interface DeviceManagementProviderService {
|
|||||||
* @return tru if device transferee, otherwise false
|
* @return tru if device transferee, otherwise false
|
||||||
*/
|
*/
|
||||||
List<String> transferDeviceToTenant(DeviceTransferRequest deviceTransferRequest) throws DeviceManagementException, DeviceNotFoundException;
|
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);
|
deviceConfiguration.setDeviceOwner(deviceOwner);
|
||||||
return deviceConfiguration;
|
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