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

Add improvement for user subscription method in APPM

See merge request entgra/carbon-device-mgt!102
merge-requests/107/head^2
Saad Sahibjan 6 years ago
commit 199e924ea6

@ -25,14 +25,6 @@ import org.wso2.carbon.device.mgt.common.operation.mgt.Activity;
import java.util.List;
public class ApplicationInstallResponse {
@ApiModelProperty(
name = "installedDevices",
value = "List of successful devices",
dataType = "List[org.wso2.carbon.device.mgt.common.DeviceIdentifier]"
)
private List<DeviceIdentifier> installedDevices;
@ApiModelProperty(
name = "alreadyInstalledDevices",
value = "List of devices that application release is already installed.",
@ -46,14 +38,6 @@ public class ApplicationInstallResponse {
)
private Activity activity;
public List<DeviceIdentifier> getInstalledDevices() {
return installedDevices;
}
public void setInstalledDevices(List<DeviceIdentifier> installedDevices) {
this.installedDevices = installedDevices;
}
public Activity getActivity() {
return activity;
}

@ -18,5 +18,5 @@
package org.wso2.carbon.device.application.mgt.common;
public enum SubsciptionType {
USER, ROLE, DEVICE_GROUP
USER, ROLE, GROUP, DEVICE
}

@ -33,10 +33,10 @@ public interface SubscriptionManager {
* To install an application to given list of devices.
* @param applicationUUID ID of the application to install
* @param deviceList list of device ID's to install the application
* @return {@link ApplicationInstallResponseTmp} object which contains installed application and devices
* @return {@link ApplicationInstallResponse} object which contains installed application and devices
* @throws ApplicationManagementException if unable to install the application to the given devices
*/
ApplicationInstallResponseTmp installApplicationForDevices(String applicationUUID, List<DeviceIdentifier> deviceList)
ApplicationInstallResponse installApplicationForDevices(String applicationUUID, List<DeviceIdentifier> deviceList)
throws ApplicationManagementException;
/**

@ -47,11 +47,11 @@ public class GenericApplicationReleaseDAOImpl extends AbstractDAOImpl implements
* To insert the ApplicationDTO Release Details.
*
* @param appId Id of the application
* @param applicationRelease ApplicationDTO Release the properties of which that need to be inserted.
* @param applicationReleaseDTO ApplicationDTO Release the properties of which that need to be inserted.
* @param tenantId Tenant Id
* @throws ApplicationManagementDAOException ApplicationDTO Management DAO Exception.
*/
@Override public ApplicationReleaseDTO createRelease(ApplicationReleaseDTO applicationRelease, int appId, int tenantId)
@Override public ApplicationReleaseDTO createRelease(ApplicationReleaseDTO applicationReleaseDTO, int appId, int tenantId)
throws ApplicationManagementDAOException {
Connection connection;
PreparedStatement statement = null;
@ -83,31 +83,31 @@ public class GenericApplicationReleaseDAOImpl extends AbstractDAOImpl implements
try {
connection = this.getDBConnection();
statement = connection.prepareStatement(sql, generatedColumns);
statement.setString(1, applicationRelease.getDescription());
statement.setString(2, applicationRelease.getVersion());
statement.setString(1, applicationReleaseDTO.getDescription());
statement.setString(2, applicationReleaseDTO.getVersion());
statement.setInt(3, tenantId);
statement.setString(4, applicationRelease.getUuid());
statement.setString(5, String.valueOf(applicationRelease.getReleaseType()));
statement.setString(6, String.valueOf(applicationRelease.getPackageName()));
statement.setDouble(7, applicationRelease.getPrice());
statement.setString(8, applicationRelease.getInstallerName());
statement.setString(9, applicationRelease.getIconName());
statement.setString(10, applicationRelease.getBannerName());
statement.setString(11, applicationRelease.getScreenshotName1());
statement.setString(12, applicationRelease.getScreenshotName2());
statement.setString(13, applicationRelease.getScreenshotName3());
statement.setString(14, applicationRelease.getAppHashValue());
statement.setBoolean(15, applicationRelease.getIsSharedWithAllTenants());
statement.setString(16, applicationRelease.getMetaData());
statement.setString(17, applicationRelease.getSupportedOsVersions());
statement.setString(18, applicationRelease.getCurrentState().toUpperCase());
statement.setString(4, applicationReleaseDTO.getUuid());
statement.setString(5, String.valueOf(applicationReleaseDTO.getReleaseType()));
statement.setString(6, String.valueOf(applicationReleaseDTO.getPackageName()));
statement.setDouble(7, applicationReleaseDTO.getPrice());
statement.setString(8, applicationReleaseDTO.getInstallerName());
statement.setString(9, applicationReleaseDTO.getIconName());
statement.setString(10, applicationReleaseDTO.getBannerName());
statement.setString(11, applicationReleaseDTO.getScreenshotName1());
statement.setString(12, applicationReleaseDTO.getScreenshotName2());
statement.setString(13, applicationReleaseDTO.getScreenshotName3());
statement.setString(14, applicationReleaseDTO.getAppHashValue());
statement.setBoolean(15, applicationReleaseDTO.getIsSharedWithAllTenants());
statement.setString(16, applicationReleaseDTO.getMetaData());
statement.setString(17, applicationReleaseDTO.getSupportedOsVersions());
statement.setString(18, applicationReleaseDTO.getCurrentState().toUpperCase());
statement.setInt(19, appId);
statement.executeUpdate();
resultSet = statement.getGeneratedKeys();
if (resultSet.next()) {
applicationRelease.setId(resultSet.getInt(1));
applicationReleaseDTO.setId(resultSet.getInt(1));
}
return applicationRelease;
return applicationReleaseDTO;
} catch (SQLException e) {
log.error("SQL Exception while trying to release an application by executing the query " + sql, e);
throw new ApplicationManagementDAOException(

@ -443,7 +443,7 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
StringJoiner joiner = new StringJoiner(",",
"SELECT DS.DM_DEVICE_ID "
+ "FROM AP_DEVICE_SUBSCRIPTION DS "
+ "WHERE US.DM_DEVICE_ID IN (", ") AND TENANT_ID = ?");
+ "WHERE DS.DM_DEVICE_ID IN (", ") AND TENANT_ID = ?");
deviceIds.stream().map(ignored -> "?").forEach(joiner::add);
String query = joiner.toString();
try (PreparedStatement ps = conn.prepareStatement(query)) {

@ -92,13 +92,8 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -250,7 +245,7 @@ public class ApplicationManagerImpl implements ApplicationManager {
throw new ApplicationManagementException(msg, e);
}
//insert application data into databse
//insert application data into database
ApplicationStorageManager applicationStorageManager = DAOUtil.getApplicationStorageManager();
ApplicationReleaseDTO applicationReleaseDTO = applicationDTO.getApplicationReleaseDTOs().get(0);
try {
@ -1059,6 +1054,7 @@ public class ApplicationManagerImpl implements ApplicationManager {
return roleList;
}
//todo no usage
public ApplicationDTO getApplication(String appType, String appName) throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
@ -1159,33 +1155,6 @@ public class ApplicationManagerImpl implements ApplicationManager {
// return filterAppReleaseByCurrentState(applicationReleases, releaseState);
}
// private List<ApplicationReleaseDTO> filterAppReleaseByCurrentState(List<ApplicationReleaseDTO> applicationReleases,
// String state) {
// List<ApplicationReleaseDTO> filteredReleases = new ArrayList<>();
//
// if (state != null && !state.isEmpty()) {
// for (ApplicationReleaseDTO applicationRelease : applicationReleases) {
// if (state.equals(applicationRelease.getLifecycleStateChangeFlow().getCurrentState())) {
// filteredReleases.add(applicationRelease);
// }
// }
//
// if (AppLifecycleState.PUBLISHED.toString().equals(state) && filteredReleases.size() > 1) {
// log.warn("There are more than one application releases is found which is in PUBLISHED state");
// filteredReleases.sort((r1, r2) -> {
// if (r1.getLifecycleStateChangeFlow().getUpdatedAt().after(r2.getLifecycleStateChangeFlow().getUpdatedAt())) {
// return -1;
// } else if (r2.getLifecycleStateChangeFlow().getUpdatedAt().after(r1.getLifecycleStateChangeFlow().getUpdatedAt())) {
// return 1;
// }
// return 0;
// });
// }
// return filteredReleases;
// }
// return applicationReleases;
// }
@Override
public void deleteApplication(int applicationId) throws ApplicationManagementException {
if (log.isDebugEnabled()) {
@ -1283,53 +1252,6 @@ public class ApplicationManagerImpl implements ApplicationManager {
}
}
private List<String> searchLifecycleStateFlow(String start, String finish) throws ApplicationManagementException {
Map<String, String> nextNodeMap = new HashMap<>();
List<String> directions = new LinkedList<>();
Queue<String> queue = new LinkedList<>();
String currentNode = start;
queue.add(currentNode);
Set<String> visitedNodes = new HashSet<>();
visitedNodes.add(currentNode);
while (!queue.isEmpty()) {
currentNode = queue.remove();
if (currentNode.equals(finish)) {
break;
} else {
List<String> nextStates = lifecycleStateManager.getNextLifecycleStates(currentNode);
if (nextStates.contains(finish)) {
queue = new LinkedList<>();
queue.add(finish);
nextNodeMap.put(currentNode, finish);
} else {
for (String node : nextStates) {
if (!visitedNodes.contains(node)) {
queue.add(node);
visitedNodes.add(node);
nextNodeMap.put(currentNode, node);
}
}
}
}
}
//If all nodes are explored and the destination node hasn't been found.
if (!currentNode.equals(finish)) {
String errorMsg = "can't found a feasible path from " + start + " to " + finish;
throw new ApplicationManagementException(errorMsg);
}
//Reconstruct path
for (String node = start; node != null; node = nextNodeMap.get(node)) {
if (!node.equals(start)) {
directions.add(node);
}
}
return directions;
}
@Override
public void deleteApplicationRelease(String releaseUuid)
throws ApplicationManagementException {
@ -1547,49 +1469,6 @@ public class ApplicationManagerImpl implements ApplicationManager {
}
}
/**
* To get role restricted application list.
*
* @param applicationList list of applications.
* @param userName user name
* @return ApplicationDTO related with the UUID
*/
// private ApplicationList getRoleRestrictedApplicationList(ApplicationList applicationList, String userName)
// throws ApplicationManagementException {
// ApplicationList roleRestrictedApplicationList = new ApplicationList();
// ArrayList<ApplicationDTO> unRestrictedApplications = new ArrayList<>();
// for (ApplicationDTO application : applicationList.getApplications()) {
// if (application.getUnrestrictedRoles().isEmpty()) {
// unRestrictedApplications.add(application);
// } else {
// try {
// if (hasUserRole(application.getUnrestrictedRoles(), userName)) {
// unRestrictedApplications.add(application);
// }
// } catch (UserStoreException e) {
// throw new ApplicationManagementException("Role restriction verifying is failed");
// }
// }
// }
// roleRestrictedApplicationList.setApplications(unRestrictedApplications);
// return roleRestrictedApplicationList;
// }
/**
* To validate a app release creating request and app updating request to make sure all the pre-conditions
* satisfied.
*
* @param applicationRelease ApplicationReleaseDTO that need to be created.
* @throws ApplicationManagementException ApplicationDTO Management Exception.
*/
private void validateAppReleasePayload(ApplicationReleaseDTO applicationRelease)
throws ApplicationManagementException {
if (applicationRelease.getVersion() == null) {
throw new ApplicationManagementException("ApplicationReleaseDTO version name is a mandatory parameter for "
+ "creating release. It cannot be found.");
}
}
@Override
public List<LifecycleState> getLifecycleStateChangeFlow(String releaseUuid) throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
@ -2430,10 +2309,8 @@ public class ApplicationManagerImpl implements ApplicationManager {
log.error(msg);
throw new RequestValidatingException(msg);
}
}
@Override
public void validateReleaseCreatingRequest(ApplicationReleaseWrapper applicationReleaseWrapper,
String applicationType) throws RequestValidatingException {

@ -86,15 +86,56 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
}
@Override
public ApplicationInstallResponseTmp installApplicationForDevices(String applicationUUID,
public ApplicationInstallResponse installApplicationForDevices(String applicationUUID,
List<DeviceIdentifier> deviceIdentifiers) throws ApplicationManagementException {
if (log.isDebugEnabled()) {
log.debug("Install application which has UUID: " + applicationUUID + " to " + deviceIdentifiers.size()
+ "devices.");
}
ApplicationDTO applicationDTO = getApplicationDTO(applicationUUID);
validateAppInstallingForDevicesRequest(applicationDTO, deviceIdentifiers);
return installToDevicesTmp(applicationDTO, deviceIdentifiers);
List<Integer> operationTriggeredDeviceIds = new ArrayList<>();
List <Device> filteredDevices = validateAppInstallingForDevicesRequest(applicationDTO, deviceIdentifiers);
List<Integer> filteredDeviceIds = new ArrayList<>();
List<DeviceIdentifier> installedDeviceIdentifiers = new ArrayList<>();
Map<DeviceIdentifier , Integer> compatibleDevices = new HashMap<>();
Map<Integer, DeviceSubscriptionDTO> deviceSubscriptions;
for (Device device : filteredDevices){
filteredDeviceIds.add(device.getId());
}
deviceSubscriptions = getDeviceSubscriptions(filteredDeviceIds);
for (Device device : filteredDevices) {
DeviceIdentifier deviceIdentifier = new DeviceIdentifier(device.getDeviceIdentifier(),
device.getType());
DeviceSubscriptionDTO deviceSubscriptionDTO = deviceSubscriptions.get(device.getId());
if (deviceSubscriptionDTO != null && !deviceSubscriptionDTO.isUnsubscribed()
&& Operation.Status.COMPLETED.toString().equals(deviceSubscriptionDTO.getStatus())) {
installedDeviceIdentifiers.add(deviceIdentifier);
} else {
compatibleDevices.put(deviceIdentifier, device.getId());
}
}
Activity activity = installToDevices(applicationDTO, deviceIdentifiers, deviceIdentifiers.get(0).getType());
List<ActivityStatus> activityStatuses = activity.getActivityStatus();
for (ActivityStatus status : activityStatuses) {
if (status.getStatus().equals(ActivityStatus.Status.PENDING)){
operationTriggeredDeviceIds.add(compatibleDevices.get(status.getDeviceIdentifier()));
}
}
ApplicationInstallResponse applicationInstallResponse = new ApplicationInstallResponse();
applicationInstallResponse.setActivity(activity);
applicationInstallResponse.setAlreadyInstalledDevices(installedDeviceIdentifiers);
// int operationId = Integer
// .parseInt(activity.getActivityId().split(DeviceManagementConstants.OperationAttributes.ACTIVITY)[1]);
int operationId = Integer.parseInt(activity.getActivityId().split("ACTIVITY_")[1]);
addDeviceSubscriptions(applicationDTO.getApplicationReleaseDTOs().get(0).getId(),
operationTriggeredDeviceIds, new ArrayList<>(deviceSubscriptions.keySet()), null, operationId,
SubsciptionType.DEVICE.toString());
return applicationInstallResponse;
}
private ApplicationDTO getApplicationDTO(String uuid) throws ApplicationManagementException {
@ -132,9 +173,12 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
}
}
private void validateAppInstallingForDevicesRequest(ApplicationDTO applicationDTO,
private List <Device> validateAppInstallingForDevicesRequest(ApplicationDTO applicationDTO,
List<DeviceIdentifier> deviceIdentifiers) throws ApplicationManagementException {
DeviceType deviceType = null;
List <Device> existingDevices = new ArrayList<>();
DeviceManagementProviderService deviceManagementProviderService = HelperUtil
.getDeviceManagementProviderService();
if (!ApplicationType.WEB_CLIP.toString().equals(applicationDTO.getType())) {
deviceType = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId());
}
@ -149,7 +193,23 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
log.error(msg);
throw new BadRequestException(msg);
}
try {
Device device = deviceManagementProviderService.getDevice(deviceIdentifier, false);
if (device == null) {
String msg = "Couldn't found an device for device identifier " + deviceIdentifier.getId()
+ " and device type: " + deviceIdentifier.getType();
log.error(msg);
} else {
existingDevices.add(device);
}
} catch (DeviceManagementException e) {
String msg = "Error occuered when getting device data for divice identifier " + deviceIdentifier.getId()
+ " and device type " + deviceIdentifier.getType();
log.error(msg);
throw new ApplicationManagementException(msg, e);
}
}
return existingDevices;
}
@Override
@ -160,13 +220,13 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
+ " users.");
}
//todo check valid user list
//todo check valid user list - throw BadRequest exception
ApplicationDTO applicationDTO = getApplicationDTO(applicationUUID);
DeviceType appDeviceType = APIUtil.getDeviceTypeData(applicationDTO.getDeviceTypeId());
List<DeviceIdentifier> operationTriggeredDeviceIdentifiers = new ArrayList<>();
Map<DeviceIdentifier , Integer> compatibleDevices = new HashMap<>();
List<Integer> operationTriggeredDeviceIds = new ArrayList<>();
List<DeviceIdentifier> installedDeviceIdentifiers = new ArrayList<>();
Map<Integer, DeviceSubscriptionDTO> deviceSubscriptions = new HashMap<>();
for (String user : userList) {
try {
@ -174,13 +234,14 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
List<Integer> filteredDeviceIds = new ArrayList<>();
List<Device> filteredDevices = new ArrayList<>();
//todo improve for web clips
for (Device device : userDevices) {
if (appDeviceType.getName().equals(device.getType())) {
filteredDevices.add(device);
filteredDeviceIds.add(device.getId());
}
}
Map<Integer, DeviceSubscriptionDTO> deviceSubscriptions = getDeviceSubscriptions(filteredDeviceIds);
deviceSubscriptions = getDeviceSubscriptions(filteredDeviceIds);
for (Device device : filteredDevices) {
DeviceIdentifier deviceIdentifier = new DeviceIdentifier(device.getDeviceIdentifier(),
device.getType());
@ -205,22 +266,23 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
for (ActivityStatus status : activityStatuses) {
if (status.getStatus().equals(ActivityStatus.Status.PENDING)){
operationTriggeredDeviceIds.add(compatibleDevices.get(status.getDeviceIdentifier()));
operationTriggeredDeviceIdentifiers.add(status.getDeviceIdentifier());
}
}
ApplicationInstallResponse applicationInstallResponse = new ApplicationInstallResponse();
applicationInstallResponse.setActivity(activity);
applicationInstallResponse.setAlreadyInstalledDevices(installedDeviceIdentifiers);
applicationInstallResponse.setInstalledDevices(operationTriggeredDeviceIdentifiers);
int operationId = Integer
.parseInt(activity.getActivityId().split(DeviceManagementConstants.OperationAttributes.ACTIVITY)[1]);
addDeviceSubscriptionForUser(applicationDTO.getApplicationReleaseDTOs().get(0).getId(),
operationTriggeredDeviceIds, userList, operationId);
// int operationId = Integer
// .parseInt(activity.getActivityId().split(DeviceManagementConstants.OperationAttributes.ACTIVITY)[1]);
int operationId = Integer.parseInt(activity.getActivityId().split("ACTIVITY_")[1]);
addDeviceSubscriptions(applicationDTO.getApplicationReleaseDTOs().get(0).getId(),
operationTriggeredDeviceIds, new ArrayList<>(deviceSubscriptions.keySet()), userList, operationId, SubsciptionType.USER.toString());
return applicationInstallResponse;
}
private void addDeviceSubscriptionForUser(int applicationReleaseId, List<Integer> deviceIds, List<String> userList, int operationId)
private void addDeviceSubscriptions(int applicationReleaseId, List<Integer> deviceIds,
List<Integer> subDeviceIds, List<String> subscribers, int operationId, String subType)
throws ApplicationManagementException {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
String subscriber = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
@ -229,24 +291,25 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
List<Integer> deviceResubscribingIds = new ArrayList<>();
List<Integer> deviceSubscriptingIds;
List<String> subscribedUsers = subscriptionDAO.getSubscribedUsernames(userList, tenantId);
if (!subscribedUsers.isEmpty()) {
subscriptionDAO
.updateUserSubscription(tenantId, subscriber, false, subscribedUsers, applicationReleaseId);
userList.removeAll(subscribedUsers);
if (SubsciptionType.USER.toString().equals(subType)){
List<String> subscribedUsers = subscriptionDAO.getSubscribedUsernames(subscribers, tenantId);
if (!subscribedUsers.isEmpty()) {
subscriptionDAO
.updateUserSubscription(tenantId, subscriber, false, subscribedUsers, applicationReleaseId);
subscribers.removeAll(subscribedUsers);
}
subscriptionDAO.subscribeUserToApplication(tenantId, subscriber, subscribers, applicationReleaseId);
}
subscriptionDAO.subscribeUserToApplication(tenantId, subscriber, userList, applicationReleaseId);
List<Integer> subscribedDevices = subscriptionDAO.getSubscribedDeviceIds(deviceIds, tenantId);
if (!subscribedDevices.isEmpty()) {
if (!subDeviceIds.isEmpty()) {
deviceResubscribingIds = subscriptionDAO
.updateDeviceSubscription(subscriber, deviceIds, SubsciptionType.USER.toString(),
Operation.Status.PENDING.toString(), applicationReleaseId, tenantId);
deviceIds.removeAll(subscribedDevices);
.updateDeviceSubscription(subscriber, subDeviceIds, subType, Operation.Status.PENDING.toString(),
applicationReleaseId, tenantId);
deviceIds.removeAll(subDeviceIds);
}
deviceSubscriptingIds = subscriptionDAO
.subscribeDeviceToApplication(subscriber, deviceIds, SubsciptionType.USER.toString(),
Operation.Status.PENDING.toString(), applicationReleaseId, tenantId);
.subscribeDeviceToApplication(subscriber, deviceIds, subType, Operation.Status.PENDING.toString(),
applicationReleaseId, tenantId);
deviceSubscriptingIds.addAll(deviceResubscribingIds);
subscriptionDAO.addOperationMapping(operationId, deviceSubscriptingIds, tenantId);
ConnectionManagerUtil.commitDBTransaction();

@ -28,6 +28,8 @@ import io.swagger.annotations.Info;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Tag;
import org.wso2.carbon.apimgt.annotations.api.Scopes;
import org.wso2.carbon.device.application.mgt.common.ErrorResponse;
import org.wso2.carbon.device.application.mgt.common.PaginationResult;
import org.wso2.carbon.device.application.mgt.common.dto.ApplicationDTO;
import org.wso2.carbon.device.application.mgt.common.ApplicationInstallResponseTmp;
import org.wso2.carbon.device.application.mgt.common.EnterpriseInstallationDetails;
@ -181,6 +183,26 @@ public interface SubscriptionManagementAPI {
)
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully add an operation to install application for user devices..",
response = PaginationResult.class,
responseContainer = "PaginationResult"),
@ApiResponse(
code = 400,
message =
"Bad Request. \n Found invalid payload with the request."),
@ApiResponse(
code = 403,
message = "Don't have permission to install application release."),
@ApiResponse(
code = 404,
message = "Not Found. \n Not found an application release for requested UUID."),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Error occurred while adding operation to install "
+ "application for users.",
response = ErrorResponse.class)
})
Response installApplicationForRoles (

@ -64,7 +64,7 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
}
try {
SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager();
ApplicationInstallResponseTmp response = subscriptionManager
ApplicationInstallResponse response = subscriptionManager
.installApplicationForDevices(uuid, deviceIdentifiers);
return Response.status(Response.Status.OK).entity(response).build();
} catch (NotFoundException e) {
@ -94,7 +94,7 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
public Response installApplicationForUsers(
@PathParam("uuid") String uuid,
@Valid List<String> users) {
if (users.isEmpty()){
if (users.isEmpty()) {
String msg = "In order to install application release which has UUID " + uuid + ", you should provide list "
+ "of users. But found an empty list of users.";
log.error(msg);
@ -104,23 +104,27 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager();
ApplicationInstallResponse response = subscriptionManager.installApplicationForUsers(uuid, users);
return Response.status(Response.Status.OK).entity(response).build();
//todo
} catch(BadRequestException e){
} catch (NotFoundException e) {
String msg = "Couldn't found an application release for UUID: " + uuid + ". Hence, verify the payload";
log.error(msg);
return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
} catch (BadRequestException e) {
String msg = "Found invalid payload for installing application which has UUID: " + uuid
+ ". Hence verify the payload";
log.error(msg);
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 install the aplication.";
} catch (ForbiddenException e) {
String msg = "Application release is not in the installable state. Hence you are not permitted to install "
+ "the application.";
log.error(msg);
return Response.status(Response.Status.FORBIDDEN).entity(msg).build();
}catch (ApplicationManagementException e) {
String msg =
"Error occurred while installing the application release which has UUID: " + uuid + " for devices";
} catch (ApplicationManagementException e) {
String msg = "Error occurred while installing the application release which has UUID: " + uuid
+ " for user devices";
log.error(msg);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
} }
}
}
@Override
@POST
@ -201,7 +205,7 @@ public class SubscriptionManagementAPIImpl implements SubscriptionManagementAPI{
}
try {
ApplicationInstallResponseTmp response = subscriptionManager.installApplicationForDevices(applicationUUID,
ApplicationInstallResponse response = subscriptionManager.installApplicationForDevices(applicationUUID,
installationDetails.getDeviceIdentifiers());
return Response.status(Response.Status.OK).entity(response).build();
} catch (ApplicationManagementException e) {

@ -15,6 +15,22 @@
* specific language governing permissions and limitations
* under the License.
*
*
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
*
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.jaxrs.service.api;
@ -31,15 +47,23 @@ import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.ResponseHeader;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.apimgt.annotations.api.Scopes;
import org.wso2.carbon.device.mgt.common.Feature;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceTypeList;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
import org.wso2.carbon.device.mgt.jaxrs.util.Constants;
import javax.validation.constraints.Size;
import javax.ws.rs.*;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.List;
@SwaggerDefinition(
info = @Info(
@ -62,13 +86,19 @@ import javax.ws.rs.core.Response;
name = "Getting the Supported Device Platforms",
description = "Getting the Supported Device Platforms",
key = "perm:device-types:types",
permissions = {"/device-mgt/devices/owning-device/view"}
permissions = {"/device-mgt/device-type/view"}
),
@Scope(
name = "Get Feature Details of a Device Type",
description = "Get Feature Details of a Device Type",
key = "perm:device-types:features",
permissions = {"/device-mgt/devices/owning-device/view"}
permissions = {"/device-mgt/device-type/features/view"}
),
@Scope(
name = "Get Config Details of a Device Type",
description = "Get Config Details of a Device Type",
key = "perm:device-types:configs",
permissions = {"/device-mgt/device-type/config/view"}
)
}
)
@ -84,7 +114,7 @@ public interface DeviceTypeManagementService {
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Getting the Supported Device Platforms",
notes = "Get the list of device platforms supported by WSO2 EMM.",
notes = "Get the list of device platforms supported by Entgra IoTS.",
tags = "Device Type Management",
extensions = {
@Extension(properties = {
@ -133,18 +163,71 @@ public interface DeviceTypeManagementService {
name = "If-Modified-Since",
value = "Checks if the requested variant was modified, since the specified date-time.\n" +
"Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" +
"Example: Mon, 05 Jan 2014 15:10:00 +0200",
required = false)
"Example: Mon, 05 Jan 2014 15:10:00 +0200"
)
@HeaderParam("If-Modified-Since")
String ifModifiedSince);
@GET
@Path("/{type}")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Getting Details of a Device Type",
notes = "Get the details of a device by searching via the device type and the tenant domain.",
response = DeviceType.class,
tags = "Device Type Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:device-types:types")
})
}
)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK. \n Successfully fetched the device type.",
response = DeviceType.class,
responseContainer = "List",
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body")
}),
@ApiResponse(
code = 304,
message = "Not Modified. Empty body because the client already has the latest version of the " +
"requested resource.\n"),
@ApiResponse(
code = 401,
message = "Unauthorized.\n The unauthorized access to the requested resource.",
response = ErrorResponse.class),
@ApiResponse(
code = 404,
message = "Not Found.\n The specified device does not exist",
response = ErrorResponse.class),
@ApiResponse(
code = 406,
message = "Not Acceptable.\n The requested media type is not supported"),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Server error occurred while fetching the device list.",
response = ErrorResponse.class)
})
Response getDeviceTypeByName(
@ApiParam(
name = "type",
value = "The device type name, such as ios, android, windows or fire-alarm.",
required = true)
@PathParam("type")
@Size(min = 2, max = 45)
String type);
@GET
@Path("/{type}/features")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Get Feature Details of a Device Type",
notes = "The features in WSO2 EMM enables you to carry out many operations on a given device platform. " +
notes = "The features in Entgra IoTS enables you to carry out many operations on a given device platform. " +
"Using this REST API you can get the features that can be carried out on a preferred device type," +
" such as iOS, Android or Windows.",
tags = "Device Type Management",
@ -202,108 +285,78 @@ public interface DeviceTypeManagementService {
name = "If-Modified-Since",
value = "Checks if the requested variant was modified, since the specified date-time.\n" +
"Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" +
"Example: Mon, 05 Jan 2014 15:10:00 +0200",
required = false)
"Example: Mon, 05 Jan 2014 15:10:00 +0200"
)
@HeaderParam("If-Modified-Since")
String ifModifiedSince);
@GET
@Path("/all/{type}")
@Path("/{type}/configs")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Getting Details of a Device Type",
notes = "Get the details of a device by searching via the device type and the tenant domain.",
response = DeviceType.class,
tags = "Device Type Management Administrative Service",
value = "Get Configuration Details of a Device Type",
notes = "The features in Entgra IoTS enables you to carry out many operations on a given device platform. " +
"Using this REST API you can get platform configurations that can be carried out on a preferred " +
"device type, such as iOS, Android or Windows.",
tags = "Device Type Management",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:device-types:types")
@ExtensionProperty(name = Constants.SCOPE, value = "perm:device-types:configs")
})
}
)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK. \n Successfully fetched the device type.",
response = DeviceType.class,
responseContainer = "List",
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body")
}),
@ApiResponse(
code = 304,
message = "Not Modified. Empty body because the client already has the latest version of the " +
"requested resource.\n"),
@ApiResponse(
code = 401,
message = "Unauthorized.\n The unauthorized access to the requested resource.",
response = ErrorResponse.class),
@ApiResponse(
code = 404,
message = "Not Found.\n The specified device does not exist",
response = ErrorResponse.class),
@ApiResponse(
code = 406,
message = "Not Acceptable.\n The requested media type is not supported"),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Server error occurred while fetching the device list.",
response = ErrorResponse.class)
})
Response getDeviceTypeByName(
@ApiResponses(
value = {
@ApiResponse(
code = 200,
message = "OK. \n Successfully fetched configurations.",
response = PlatformConfiguration.class,
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description =
"Date and time the resource was last modified.\n" +
"Used by caches, or in conditional requests."),
}
),
@ApiResponse(
code = 304,
message =
"Not Modified. \n Empty body because the client already has the latest version " +
"of the requested resource.\n"),
@ApiResponse(
code = 406,
message = "Not Acceptable.\n The requested media type is not supported"),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Server error occurred while fetching the " +
"list of supported device types.",
response = ErrorResponse.class)
}
)
Response getConfigs(
@ApiParam(
name = "type",
value = "The device type name, such as ios, android, windows or fire-alarm.",
required = true)
@PathParam("type")
@Size(min = 2, max = 45)
String type);
@GET
@Path("/all")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Retrieve device types information",
notes = "Retrieve device types information.",
response = DeviceType.class,
tags = "Device Type Management Administrative Service",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:device-types:types")
})
}
)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK. \n Successfully fetched the device type.",
response = DeviceType.class,
responseContainer = "List",
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body")
}),
@ApiResponse(
code = 304,
message = "Not Modified. Empty body because the client already has the latest version of the " +
"requested resource.\n"),
@ApiResponse(
code = 401,
message = "Unauthorized.\n The unauthorized access to the requested resource.",
response = ErrorResponse.class),
@ApiResponse(
code = 404,
message = "Not Found.\n The specified device does not exist",
response = ErrorResponse.class),
@ApiResponse(
code = 406,
message = "Not Acceptable.\n The requested media type is not supported"),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Server error occurred while fetching the device list.",
response = ErrorResponse.class)
})
Response getDeviceTypes();
String type,
@ApiParam(
name = "If-Modified-Since",
value = "Checks if the requested variant was modified, since the specified date-time.\n" +
"Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z.\n" +
"Example: Mon, 05 Jan 2014 15:10:00 +0200"
)
@HeaderParam("If-Modified-Since")
String ifModifiedSince);
}

@ -15,6 +15,23 @@
* specific language governing permissions and limitations
* under the License.
*
*
* Copyright (c) 2019, Entgra (pvt) Ltd. (https://entgra.io) All Rights Reserved.
*
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.device.mgt.jaxrs.service.api.admin;
@ -31,7 +48,7 @@ import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Tag;
import org.wso2.carbon.apimgt.annotations.api.Scope;
import org.wso2.carbon.apimgt.annotations.api.Scopes;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceTypeList;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
@ -40,12 +57,11 @@ import org.wso2.carbon.device.mgt.jaxrs.util.Constants;
import javax.validation.constraints.Size;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@ -73,10 +89,22 @@ import javax.ws.rs.core.Response;
@Scopes(
scopes = {
@Scope(
name = "Getting Details of a Device",
description = "Getting Details of a Device",
name = "Manage a Device Type",
description = "Add, Edit or View a Device Type",
key = "perm:admin:device-type",
permissions = {"/device-mgt/admin/device-type"}
),
@Scope(
name = "Getting Details of a Device Type",
description = "Getting Details of a Device Type",
key = "perm:admin:device-type:view",
permissions = {"/device-mgt/admin/device-type/view"}
),
@Scope(
name = "Add Device Type Config",
description = "Add Platform Config of a Device Type",
key = "perm:admin:device-type:configs",
permissions = {"/device-mgt/admin/device-type/config"}
)
}
)
@ -88,10 +116,10 @@ public interface DeviceTypeManagementAdminService {
httpMethod = "GET",
value = "Getting the Supported Device Type with Meta Definition",
notes = "Get the list of device types supported by WSO2 IoT.",
tags = "Device Type Management",
tags = "Device Type Management Administrative Service",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:admin:device-type")
@ExtensionProperty(name = Constants.SCOPE, value = "perm:admin:device-type:view")
})
}
)
@ -133,6 +161,59 @@ public interface DeviceTypeManagementAdminService {
)
Response getDeviceTypes();
@GET
@Path("/{type}")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "GET",
value = "Getting Details of a Device Type",
notes = "Get the details of a device by searching via the device type and the tenant domain.",
response = DeviceType.class,
tags = "Device Type Management Administrative Service",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:admin:device-type:view")
})
}
)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK. \n Successfully fetched the device type.",
response = DeviceType.class,
responseContainer = "List",
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body")
}),
@ApiResponse(
code = 304,
message = "Not Modified. Empty body because the client already has the latest version of the " +
"requested resource.\n"),
@ApiResponse(
code = 401,
message = "Unauthorized.\n The unauthorized access to the requested resource.",
response = ErrorResponse.class),
@ApiResponse(
code = 404,
message = "Not Found.\n The specified device does not exist",
response = ErrorResponse.class),
@ApiResponse(
code = 406,
message = "Not Acceptable.\n The requested media type is not supported"),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Server error occurred while fetching the device list.",
response = ErrorResponse.class)
})
Response getDeviceTypeByName(
@ApiParam(
name = "type",
value = "The device type name, such as ios, android, windows or fire-alarm.",
required = true)
@PathParam("type")
@Size(min = 2, max = 45)
String type);
@POST
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
@ -179,6 +260,7 @@ public interface DeviceTypeManagementAdminService {
required = true)DeviceType deviceType);
@PUT
@Path("/{type}")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "PUT",
@ -219,9 +301,73 @@ public interface DeviceTypeManagementAdminService {
message = "Internal Server Error. \n Server error occurred while fetching the device list.",
response = ErrorResponse.class)
})
Response updateDeviceType(@ApiParam(
name = "type",
Response updateDeviceType(
@ApiParam(
name = "type",
value = "The device type name, such as ios, android, windows or fire-alarm.",
required = true)
@PathParam("type")
@Size(min = 2, max = 45)
String name,
@ApiParam(
name = "deviceType",
value = "The device type such as ios, android, windows or fire-alarm.",
required = true) DeviceType deviceType);
@POST
@Path("/{type}/configs")
@ApiOperation(
produces = MediaType.APPLICATION_JSON,
httpMethod = "POST",
value = "Add Configuration Details",
notes = "Add Configuration Details of a Device Type.",
tags = "Device Type Management Administrative Service",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = Constants.SCOPE, value = "perm:admin:device-type:configs")
})
}
)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK. \n Successfully added the device type config.",
responseHeaders = {
@ResponseHeader(
name = "Content-Type",
description = "The content type of the body")
}),
@ApiResponse(
code = 304,
message = "Not Modified. Empty body because the client already has the latest version of the " +
"requested resource.\n"),
@ApiResponse(
code = 401,
message = "Unauthorized.\n The unauthorized access to the requested resource.",
response = ErrorResponse.class),
@ApiResponse(
code = 404,
message = "Not Found.\n The specified device does not exist",
response = ErrorResponse.class),
@ApiResponse(
code = 406,
message = "Not Acceptable.\n The requested media type is not supported"),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n Server error occurred while fetching the device list.",
response = ErrorResponse.class)
})
Response addDeviceTypePlatformConfig(
@ApiParam(
name = "type",
value = "The device type name, such as ios, android, windows or fire-alarm.",
required = true)
@PathParam("type")
@Size(min = 2, max = 45)
String type,
@ApiParam(
name = "config",
value = "Platform configuration of specified device type.",
required = true)
PlatformConfiguration config);
}

@ -25,6 +25,7 @@ import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.DeviceTypeNotFoundException;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.Feature;
import org.wso2.carbon.device.mgt.common.FeatureManager;
@ -506,18 +507,22 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
@PathParam("type") @Size(max = 45) String type,
@PathParam("id") @Size(max = 45) String id,
@HeaderParam("If-Modified-Since") String ifModifiedSince) {
List<Feature> features;
List<Feature> features = new ArrayList<>();
DeviceManagementProviderService dms;
try {
RequestValidationUtil.validateDeviceIdentifier(type, id);
dms = DeviceMgtAPIUtils.getDeviceManagementService();
FeatureManager fm = dms.getFeatureManager(type);
if (fm == null) {
FeatureManager fm;
try {
fm = dms.getFeatureManager(type);
} catch (DeviceTypeNotFoundException e) {
return Response.status(Response.Status.NOT_FOUND).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("No feature manager is " +
"registered with the given type '" + type + "'").build()).build();
new ErrorResponse.ErrorResponseBuilder()
.setMessage("No device type found with name '" + type + "'").build()).build();
}
if (fm != null) {
features = fm.getFeatures();
}
features = fm.getFeatures();
} catch (DeviceManagementException e) {
String msg = "Error occurred while retrieving the list of features of '" + type + "' device, which " +
"carries the id '" + id + "'";

@ -15,22 +15,39 @@
* specific language governing permissions and limitations
* under the License.
*
*
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
*
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.device.mgt.jaxrs.service.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.DeviceTypeNotFoundException;
import org.wso2.carbon.device.mgt.common.Feature;
import org.wso2.carbon.device.mgt.common.FeatureManager;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.common.push.notification.PushNotificationConfig;
import org.wso2.carbon.device.mgt.common.type.mgt.DeviceTypeMetaDefinition;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceTypeList;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
import org.wso2.carbon.device.mgt.jaxrs.service.api.DeviceTypeManagementService;
import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil;
import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils;
import javax.validation.constraints.Size;
@ -38,7 +55,6 @@ import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.List;
@ -51,50 +67,6 @@ public class DeviceTypeManagementServiceImpl implements DeviceTypeManagementServ
@GET
@Override
public Response getDeviceTypes(@HeaderParam("If-Modified-Since") String ifModifiedSince) {
List<String> deviceTypes;
try {
deviceTypes = DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes();
DeviceTypeList deviceTypeList = new DeviceTypeList();
deviceTypeList.setCount(deviceTypes.size());
deviceTypeList.setList(deviceTypes);
return Response.status(Response.Status.OK).entity(deviceTypeList).build();
} catch (DeviceManagementException e) {
String msg = "Error occurred while fetching the list of device types.";
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
}
}
@GET
@Override
@Path("/{type}/features")
public Response getFeatures(@PathParam("type") @Size(max = 45) String type, @HeaderParam("If-Modified-Since") String ifModifiedSince) {
List<Feature> features;
DeviceManagementProviderService dms;
try {
dms = DeviceMgtAPIUtils.getDeviceManagementService();
FeatureManager fm = dms.getFeatureManager(type);
if (fm == null) {
return Response.status(Response.Status.NOT_FOUND).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("No feature manager is " +
"registered with the given type '" + type + "'").build()).build();
}
features = fm.getFeatures();
} catch (DeviceManagementException e) {
String msg = "Error occurred while retrieving the list of features of '" + type + "' device type";
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
}
return Response.status(Response.Status.OK).entity(features).build();
}
@Override
@GET
@Path("/config")
public Response getDeviceTypes() {
try {
List<DeviceType> deviceTypes = DeviceMgtAPIUtils.getDeviceManagementService().getDeviceTypes();
List<DeviceType> filteredDeviceTypes = new ArrayList<>();
@ -111,8 +83,8 @@ public class DeviceTypeManagementServiceImpl implements DeviceTypeManagementServ
@Override
@GET
@Path("/config/{type}")
public Response getDeviceTypeByName(@PathParam("type") String type) {
@Path("/{type}")
public Response getDeviceTypeByName(@PathParam("type") @Size(min = 2, max = 45) String type) {
if (type != null && type.length() > 0) {
try {
DeviceType deviceType = DeviceMgtAPIUtils.getDeviceManagementService().getDeviceType(type);
@ -120,7 +92,7 @@ public class DeviceTypeManagementServiceImpl implements DeviceTypeManagementServ
String msg = "Device type does not exist, " + type;
return Response.status(Response.Status.NO_CONTENT).entity(msg).build();
}
return Response.status(Response.Status.OK).entity(deviceType).build();
return Response.status(Response.Status.OK).entity(clearMetaEntryInfo(deviceType)).build();
} catch (DeviceManagementException e) {
String msg = "Error occurred at server side while fetching device type.";
log.error(msg, e);
@ -131,10 +103,62 @@ public class DeviceTypeManagementServiceImpl implements DeviceTypeManagementServ
}
}
@GET
@Override
@Path("/{type}/features")
public Response getFeatures(@PathParam("type") @Size(max = 45) String type,
@HeaderParam("If-Modified-Since") String ifModifiedSince) {
List<Feature> features = new ArrayList<>();
DeviceManagementProviderService dms;
try {
dms = DeviceMgtAPIUtils.getDeviceManagementService();
FeatureManager fm;
try {
fm = dms.getFeatureManager(type);
} catch (DeviceTypeNotFoundException e) {
return Response.status(Response.Status.NOT_FOUND).entity(
new ErrorResponse.ErrorResponseBuilder()
.setMessage("No device type found with name '" + type + "'").build()).build();
}
if (fm != null) {
features = fm.getFeatures();
}
} catch (DeviceManagementException e) {
String msg = "Error occurred while retrieving the list of features of '" + type + "' device type";
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
}
return Response.status(Response.Status.OK).entity(features).build();
}
@GET
@Override
@Path("/{type}/configs")
public Response getConfigs(@PathParam("type") @Size(min = 2, max = 45) String type,
@HeaderParam("If-Modified-Since") String ifModifiedSince) {
PlatformConfiguration platformConfiguration;
try {
platformConfiguration = DeviceMgtAPIUtils.getDeviceManagementService().getConfiguration(type);
if (platformConfiguration == null) {
platformConfiguration = new PlatformConfiguration();
platformConfiguration.setType(type);
platformConfiguration.setConfiguration(new ArrayList<>());
}
} catch (DeviceManagementException e) {
String msg = "Error occurred while retrieving the '" + type + "' platform configuration";
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
}
return Response.status(Response.Status.OK).entity(platformConfiguration).build();
}
/**
* This cleans up the configs that should not be exposed to iot users.
* @param deviceType
* @return
*
* @param deviceType device type retrieved from service layer.
* @return sanitized device type.
*/
private DeviceType clearMetaEntryInfo(DeviceType deviceType) {
DeviceTypeMetaDefinition metaDefinition = deviceType.getDeviceTypeMetaDefinition();

@ -15,13 +15,31 @@
* specific language governing permissions and limitations
* under the License.
*
*
* Copyright (c) 2019, Entgra (pvt) Ltd. (https://entgra.io) All Rights Reserved.
*
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.wso2.carbon.device.mgt.jaxrs.service.impl.admin;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.InvalidConfigurationException;
import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration;
import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import org.wso2.carbon.device.mgt.core.dto.DeviceType;
import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse;
@ -33,6 +51,7 @@ import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@ -63,6 +82,28 @@ public class DeviceTypeManagementAdminServiceImpl implements DeviceTypeManagemen
}
}
@Override
@GET
@Path("/{type}")
public Response getDeviceTypeByName(@PathParam("type") String type) {
if (type != null && type.length() > 0) {
try {
DeviceType deviceType = DeviceMgtAPIUtils.getDeviceManagementService().getDeviceType(type);
if (deviceType == null) {
String msg = "Device type does not exist, " + type;
return Response.status(Response.Status.NO_CONTENT).entity(msg).build();
}
return Response.status(Response.Status.OK).entity(deviceType).build();
} catch (DeviceManagementException e) {
String msg = "Error occurred at server side while fetching device type.";
log.error(msg, e);
return Response.serverError().entity(msg).build();
}
} else {
return Response.status(Response.Status.BAD_REQUEST).build();
}
}
@Override
@POST
public Response addDeviceType(DeviceType deviceType) {
@ -81,8 +122,8 @@ public class DeviceTypeManagementAdminServiceImpl implements DeviceTypeManagemen
DeviceMgtAPIUtils.getDeviceManagementService().registerDeviceType(httpDeviceTypeManagerService);
return Response.status(Response.Status.OK).build();
} else {
return Response.status(Response.Status.BAD_REQUEST).entity("Device type name does not match the pattern "
+ DEVICETYPE_REGEX_PATTERN).build();
return Response.status(Response.Status.BAD_REQUEST).entity("Device type name does not match " +
"the pattern " + DEVICETYPE_REGEX_PATTERN).build();
}
} catch (DeviceManagementException e) {
String msg = "Error occurred at server side while adding a device type.";
@ -96,11 +137,15 @@ public class DeviceTypeManagementAdminServiceImpl implements DeviceTypeManagemen
@Override
@PUT
public Response updateDeviceType(DeviceType deviceType) {
public Response updateDeviceType(String type, DeviceType deviceType) {
if (deviceType != null && deviceType.getDeviceTypeMetaDefinition() != null) {
if (deviceType.getName() == null || !deviceType.getName().equals(type)) {
return Response.status(Response.Status.BAD_REQUEST).entity("Type name mismatch. Expected: '" + type +
"' Found: '"+ deviceType.getName() + "'").build();
}
try {
if (DeviceMgtAPIUtils.getDeviceManagementService().getDeviceType(deviceType.getName()) == null) {
String msg = "Device type does not exist, " + deviceType.getName();
if (DeviceMgtAPIUtils.getDeviceManagementService().getDeviceType(type) == null) {
String msg = "Device type does not exist, " + type;
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
}
DeviceManagementService httpDeviceTypeManagerService = DeviceMgtAPIUtils.getDeviceTypeGeneratorService()
@ -116,4 +161,22 @@ public class DeviceTypeManagementAdminServiceImpl implements DeviceTypeManagemen
return Response.status(Response.Status.BAD_REQUEST).build();
}
}
@Override
public Response addDeviceTypePlatformConfig(String type, PlatformConfiguration platformConfiguration) {
boolean isSaved;
if (platformConfiguration.getType() == null || !platformConfiguration.getType().equals(type)) {
return Response.status(Response.Status.BAD_REQUEST).entity("Type name mismatch. Expected: '" + type +
"' Found: '"+ platformConfiguration.getType() + "'").build();
}
try {
isSaved = DeviceMgtAPIUtils.getDeviceManagementService().saveConfiguration(platformConfiguration);
} catch (DeviceManagementException e) {
String msg = "Error occurred while retrieving the Android tenant configuration";
log.error(msg, e);
return Response.serverError().entity(
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
}
return Response.status(isSaved ? Response.Status.OK : Response.Status.BAD_REQUEST).build();
}
}

@ -66,7 +66,7 @@
<property name="schemes" value="https" />
<property name="basePath" value="/api/device-mgt/v1.0"/>
<property name="title" value="Device Management Admin Service API Definitions"/>
<property name="contact" value="dev@wso2.org"/>
<property name="contact" value="dev@entgra.io"/>
<property name="license" value="Apache 2.0"/>
<property name="licenseUrl" value="http://www.apache.org/licenses/LICENSE-2.0.html"/>
<property name="scan" value="true"/>

@ -55,7 +55,7 @@ import static org.mockito.MockitoAnnotations.initMocks;
/**
* This is a test class for {@link ActivityProviderServiceImpl}.
*/
@PowerMockIgnore("javax.ws.rs.*")
@PowerMockIgnore({"javax.ws.rs.*", "org.apache.log4j.*"})
@SuppressStaticInitializationFor({ "org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils",
"org.wso2.carbon.context.CarbonContext", "org.wso2.carbon.context.PrivilegedCarbonContext" })
@PrepareForTest({ DeviceMgtAPIUtils.class, PolicyManagerUtil.class, PrivilegedCarbonContext.class })

@ -44,7 +44,7 @@ import java.util.List;
/**
* This is a test class for {@link ConfigurationServiceImpl}.
*/
@PowerMockIgnore("javax.ws.rs.*")
@PowerMockIgnore({"javax.ws.rs.*", "org.apache.log4j.*"})
@SuppressStaticInitializationFor({"org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils",
"org.wso2.carbon.context.CarbonContext"})
@PrepareForTest({DeviceMgtAPIUtils.class, PolicyManagerUtil.class})

@ -75,7 +75,7 @@ import static org.mockito.MockitoAnnotations.initMocks;
/**
* This class holds the unit tests for the class {@link DeviceAgentServiceImpl}
*/
@PowerMockIgnore("javax.ws.rs.*")
@PowerMockIgnore({"javax.ws.rs.*", "org.apache.log4j.*"})
@SuppressStaticInitializationFor({"org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils",
"org.wso2.carbon.context.CarbonContext", "org.wso2.carbon.context.internal.CarbonContextDataHolder"})
@PrepareForTest({DeviceMgtAPIUtils.class, DeviceManagementProviderService.class,

@ -34,6 +34,7 @@ import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.DeviceTypeNotFoundException;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.PaginationRequest;
import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException;
@ -67,7 +68,7 @@ import static org.mockito.MockitoAnnotations.initMocks;
/**
* This class includes unit tests for testing the functionality of {@link DeviceManagementServiceImpl}
*/
@PowerMockIgnore("javax.ws.rs.*")
@PowerMockIgnore({"javax.ws.rs.*", "org.apache.log4j.*"})
@SuppressStaticInitializationFor({"org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils",
"org.wso2.carbon.context.CarbonContext"})
@PrepareForTest({DeviceMgtAPIUtils.class, MultitenantUtils.class, CarbonContext.class})
@ -437,26 +438,15 @@ public class DeviceManagementServiceImplTest {
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode());
}
@Test(description = "Testing getting device features when feature manager is not registered for the device type")
public void testGetFeaturesOfDeviceWhenFeatureManagerIsNotRegistered() throws DeviceManagementException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService.getFeatureManager(Mockito.anyString())).thenReturn(null);
Response response = this.deviceManagementService
.getFeaturesOfDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), null);
Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode());
Mockito.reset(this.deviceManagementProviderService);
}
@Test(description = "Testing getting device features when unable to get the feature manager")
public void testGetFeaturesException() throws DeviceManagementException {
public void testGetFeaturesException() throws DeviceTypeNotFoundException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService.getFeatureManager(Mockito.anyString()))
.thenThrow(new DeviceManagementException());
.thenThrow(new DeviceTypeNotFoundException());
Response response = this.deviceManagementService
.getFeaturesOfDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString(), null);
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode());
Mockito.reset(this.deviceManagementProviderService);
}

@ -48,7 +48,7 @@ import static org.mockito.MockitoAnnotations.initMocks;
/**
* This class holds the unit tests for the class {@link DeviceTypeManagementAdminService}
*/
@PowerMockIgnore("javax.ws.rs.*")
@PowerMockIgnore({"javax.ws.rs.*", "org.apache.log4j.*"})
@SuppressStaticInitializationFor({"org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils"})
@PrepareForTest({DeviceMgtAPIUtils.class, DeviceManagementProviderService.class})
public class DeviceTypeManagementAdminServiceTest {
@ -171,7 +171,7 @@ public class DeviceTypeManagementAdminServiceTest {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceTypeGeneratorService"))
.toReturn(this.deviceTypeGeneratorService);
DeviceType deviceType = DeviceMgtAPITestHelper.getDummyDeviceType(TEST_DEVICE_TYPE, TEST_DEVICE_TYPE_ID);
Response response = this.deviceTypeManagementAdminService.updateDeviceType(deviceType);
Response response = this.deviceTypeManagementAdminService.updateDeviceType(TEST_DEVICE_TYPE, deviceType);
Assert.assertNotNull(response, "The response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
"The Response Status code should be 200.");
@ -185,7 +185,7 @@ public class DeviceTypeManagementAdminServiceTest {
.toReturn(this.deviceTypeGeneratorService);
Mockito.when(deviceManagementProviderService.getDeviceType(Mockito.anyString())).thenReturn(null);
DeviceType deviceType = DeviceMgtAPITestHelper.getDummyDeviceType(TEST_DEVICE_TYPE, TEST_DEVICE_TYPE_ID);
Response response = this.deviceTypeManagementAdminService.updateDeviceType(deviceType);
Response response = this.deviceTypeManagementAdminService.updateDeviceType(TEST_DEVICE_TYPE, deviceType);
Assert.assertNotNull(response, "The response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(),
"The Response Status code should be 400.");
@ -196,7 +196,7 @@ public class DeviceTypeManagementAdminServiceTest {
public void testUpdateDeviceTypeWithNullDeviceType() {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Response response = this.deviceTypeManagementAdminService.updateDeviceType(null);
Response response = this.deviceTypeManagementAdminService.updateDeviceType(TEST_DEVICE_TYPE, null);
Assert.assertNotNull(response, "The response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode(),
"The Response Status code should be 400.");
@ -210,7 +210,7 @@ public class DeviceTypeManagementAdminServiceTest {
Mockito.when(this.deviceManagementProviderService.getDeviceType(Mockito.anyString()))
.thenThrow(new DeviceManagementException());
DeviceType deviceType = DeviceMgtAPITestHelper.getDummyDeviceType(TEST_DEVICE_TYPE, TEST_DEVICE_TYPE_ID);
Response response = this.deviceTypeManagementAdminService.updateDeviceType(deviceType);
Response response = this.deviceTypeManagementAdminService.updateDeviceType(TEST_DEVICE_TYPE, deviceType);
Assert.assertNotNull(response, "The response should not be null");
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"The Response Status code should be 500.");

@ -48,7 +48,7 @@ import static org.mockito.MockitoAnnotations.initMocks;
/**
* This class holds the unit tests for the class {@link DeviceTypeManagementService}
*/
@PowerMockIgnore("javax.ws.rs.*")
@PowerMockIgnore({"javax.ws.rs.*", "org.apache.log4j.*"})
@SuppressStaticInitializationFor({"org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils"})
@PrepareForTest({DeviceMgtAPIUtils.class, DeviceManagementProviderService.class})
public class DeviceTypeManagementServiceTest {
@ -89,7 +89,7 @@ public class DeviceTypeManagementServiceTest {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService.getDeviceTypes()).thenThrow(new DeviceManagementException());
Response response = this.deviceTypeManagementService.getDeviceTypes();
Response response = this.deviceTypeManagementService.getDeviceTypes(MODIFIED_SINCE);
Assert.assertNotNull(response, "The response object is null.");
Assert.assertEquals(response.getStatus(), Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"The response status should be 500.");
@ -100,7 +100,7 @@ public class DeviceTypeManagementServiceTest {
public void testExistingDeviceTypesModifiedError() throws Exception {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService.getAvailableDeviceTypes()).thenThrow(new
Mockito.when(this.deviceManagementProviderService.getDeviceTypes()).thenThrow(new
DeviceManagementException());
Response response = this.deviceTypeManagementService.getDeviceTypes(MODIFIED_SINCE);
Assert.assertNotNull(response, "The response object is null.");
@ -142,8 +142,9 @@ public class DeviceTypeManagementServiceTest {
Mockito.when(this.deviceManagementProviderService.getFeatureManager(Mockito.anyString())).thenReturn(null);
Response response = this.deviceTypeManagementService.getFeatures(TEST_DEVICE_TYPE, MODIFIED_SINCE);
Assert.assertNotNull(response, "The response object is null.");
Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode(),
"The response status should be 404.");
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
"The response status should be 200.");
Assert.assertEquals(response.getEntity().toString(), "[]", "The response should be [].");
Mockito.reset(deviceManagementProviderService);
}
@ -151,7 +152,7 @@ public class DeviceTypeManagementServiceTest {
public void testGetDeviceTypes() throws Exception {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Response response = this.deviceTypeManagementService.getDeviceTypes();
Response response = this.deviceTypeManagementService.getDeviceTypes(MODIFIED_SINCE);
Assert.assertNotNull(response, "The response object is null.");
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
"The response status should be 200.");
@ -163,7 +164,7 @@ public class DeviceTypeManagementServiceTest {
.toReturn(this.deviceManagementProviderService);
List<DeviceType> deviceTypes = DeviceMgtAPITestHelper.getDummyDeviceTypeList(5);
Mockito.when(this.deviceManagementProviderService.getDeviceTypes()).thenReturn(deviceTypes);
Response response = this.deviceTypeManagementService.getDeviceTypes();
Response response = this.deviceTypeManagementService.getDeviceTypes(MODIFIED_SINCE);
Assert.assertNotNull(response, "The response object is null.");
Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(),
"The response state should be 200");

@ -1,6 +1,7 @@
package org.wso2.carbon.device.mgt.jaxrs.service.impl;
import org.mockito.Mockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@ -15,6 +16,7 @@ import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.List;
@PowerMockIgnore({"javax.ws.rs.*", "org.apache.log4j.*"})
public class GeoLocationBasedServiceImplTest {
private DeviceManagementProviderService deviceManagementProviderService;
private PrivilegedCarbonContext context;

@ -54,7 +54,7 @@ import java.util.List;
/**
* This is a test case for {@link GroupManagementServiceImpl}.
*/
@PowerMockIgnore({"javax.ws.rs.*", "javax.xml.parsers"})
@PowerMockIgnore({"javax.ws.rs.*", "org.apache.log4j.*", "javax.xml.parsers"})
@SuppressStaticInitializationFor({"org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils",
"org.wso2.carbon.context.PrivilegedCarbonContext"})
@PrepareForTest({DeviceMgtAPIUtils.class, CarbonContext.class})

@ -46,7 +46,7 @@ import static org.mockito.MockitoAnnotations.initMocks;
/**
* This is a test class for {@link NotificationManagementServiceImpl}.
*/
@PowerMockIgnore("javax.ws.rs.*")
@PowerMockIgnore({"javax.ws.rs.*", "org.apache.log4j.*"})
@SuppressStaticInitializationFor({"org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils",
"org.wso2.carbon.context.CarbonContext"})
@PrepareForTest({DeviceMgtAPIUtils.class, MultitenantUtils.class, CarbonContext.class})

@ -58,7 +58,7 @@ import static org.mockito.MockitoAnnotations.initMocks;
/**
* This is a test case for {@link UserManagementService}.
*/
@PowerMockIgnore("javax.ws.rs.*")
@PowerMockIgnore({"javax.ws.rs.*", "org.apache.log4j.*"})
@SuppressStaticInitializationFor({"org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils",
"org.wso2.carbon.context.CarbonContext"})
@PrepareForTest({DeviceMgtAPIUtils.class, MultitenantUtils.class, CarbonContext.class})

@ -0,0 +1,44 @@
/*
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
*
* Entgra (pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* you may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.common;
public class DeviceTypeNotFoundException extends Exception {
private static final long serialVersionUID = 3821589758650454161L;
public DeviceTypeNotFoundException(String msg, Exception nestedEx) {
super(msg, nestedEx);
}
public DeviceTypeNotFoundException(String message, Throwable cause) {
super(message, cause);
}
public DeviceTypeNotFoundException(String msg) {
super(msg);
}
public DeviceTypeNotFoundException() {
super();
}
public DeviceTypeNotFoundException(Throwable cause) {
super(cause);
}
}

@ -20,6 +20,7 @@ package org.wso2.carbon.device.mgt.core.service;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.DeviceTypeNotFoundException;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.FeatureManager;
import org.wso2.carbon.device.mgt.common.InvalidDeviceException;
@ -496,7 +497,7 @@ public interface DeviceManagementProviderService {
void sendRegistrationEmail(EmailMetaInfo metaInfo) throws DeviceManagementException, ConfigurationManagementException;
FeatureManager getFeatureManager(String deviceType) throws DeviceManagementException;
FeatureManager getFeatureManager(String deviceType) throws DeviceTypeNotFoundException;
/**
* Proxy method to get the tenant configuration of a given platform.

@ -44,6 +44,7 @@ import org.wso2.carbon.device.mgt.core.dao.ApplicationMappingDAO;
import org.wso2.carbon.device.mgt.core.dto.DeviceTypeServiceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceNotification;
import org.wso2.carbon.device.mgt.common.DevicePropertyNotification;
import org.wso2.carbon.device.mgt.common.DeviceTypeNotFoundException;
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
import org.wso2.carbon.device.mgt.common.FeatureManager;
import org.wso2.carbon.device.mgt.common.InitialOperationConfig;
@ -176,14 +177,14 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv
}
@Override
public FeatureManager getFeatureManager(String deviceType) throws DeviceManagementException {
public FeatureManager getFeatureManager(String deviceType) throws DeviceTypeNotFoundException {
DeviceManager deviceManager = this.getDeviceManager(deviceType);
if (deviceManager == null) {
if (log.isDebugEnabled()) {
log.debug("Device Manager associated with the device type '" + deviceType + "' is null. " +
"Therefore, not attempting method 'getFeatureManager'");
}
return null;
throw new DeviceTypeNotFoundException("Device type '" + deviceType + "' not found.");
}
return deviceManager.getFeatureManager();
}

@ -59,10 +59,10 @@ if (uriMatcher.match("/{context}/api/data-tables/invoker/filters")) {
result.deviceTypes = [];
var deviceTypesRes = deviceModule.getDeviceTypes();
if (deviceTypesRes.status === "success") {
var deviceTypes = deviceTypesRes["content"]["deviceTypes"];
var deviceTypes = deviceTypesRes["content"];
for (i = 0; i < deviceTypes.length; i++) {
var deviceTypeName = deviceTypes[i];
var deviceTypeLabel = deviceTypeName;
var deviceTypeName = deviceTypes[i].name;
var deviceTypeLabel = deviceTypeName.charAt(0).toUpperCase() + deviceTypeName.slice(1);
var configs = utility.getDeviceTypeConfig(deviceTypeLabel);
if (configs) {
if (configs[DTYPE_CONF_DEVICE_TYPE_KEY][DTYPE_CONF_DEVICE_TYPE_LABEL_KEY]) {

@ -122,6 +122,7 @@
"perm:users:update",
"perm:users:send-invitation",
"perm:admin-users:view",
"perm:admin:devices:update-enrollment",
"perm:groups:devices",
"perm:groups:update",
"perm:groups:add",
@ -136,6 +137,7 @@
"perm:groups:devices-remove",
"perm:groups:devices-add",
"perm:groups:assign",
"perm:device-types:configs",
"perm:device-types:features",
"perm:device-types:types",
"perm:applications:install",
@ -154,6 +156,8 @@
"perm:device-types:events",
"perm:device-types:events:view",
"perm:admin:device-type",
"perm:admin:device-type:view",
"perm:admin:device-type:configs",
"perm:device:enroll",
"perm:geo-service:analytics-view",
"perm:geo-service:alerts-manage",

@ -303,7 +303,7 @@ deviceModule = function () {
}
return serviceInvokers.XMLHttp.get(
url, function (responsePayload) {
return parse(responsePayload["responseText"])["count"];
return parse(responsePayload["responseText"]).length;
},
function (responsePayload) {
log.error(responsePayload["responseText"]);

@ -620,6 +620,9 @@ var userModule = function () {
if (publicMethods.isAuthorized("/permission/admin/device-mgt/topics/view")) {
permissions["VIEW_TOPICS"] = true;
}
if (publicMethods.isAuthorized("/permission/admin/device-mgt/admin/devices/update-enrollment")) {
permissions["UPDATE_ENROLLMENT"] = true;
}
return permissions;
};

@ -209,6 +209,22 @@
{{/if}}
</a>
</li>
<!--update enrollment-->
{{#if permissions.updateEnrollment}}
<li>
<a href="#" style="width: 100px;height: 80px;"
data-click-event="remove-form"
class="btn square-element update-enrollment-link"
data-toggle="modal" data-target="#modalDemo">
<span class="icon fw-stack">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw fw-user fw-stack-1x"></i>
</span>
Update Enrollment
</a>
</li>
{{/if}}
<!--/update enrollment-->
</ul>
</th>
</tr>
@ -513,6 +529,58 @@
</div>
</div>
</div>
<!--update enrollment modal-->
<div id="update-enrollment-modal-content" class="hide">
<div class="modal-header">
<h3 class="pull-left modal-title">
Please enter the username to update the enrollment device(s).
</h3>
<div id="update-enrollment-error-content" class="pull-left modal-title hidden"
style="color: #d9534f;">
<strong>
<span><i class="fw fw-error"></i></span>
<div id="update-enrollment-error-msg" style="display: inline">
</div>
</strong>
</div>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i
class="fw fw-cancel"></i>
</button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
<input id="update-enrollment-name" style="color:#3f3f3f;padding:5px;" type="text"
placeholder="[ username ]" size="60" required>
</div>
<div class="modal-footer">
<div class="buttons">
<a href="#" id="update-enrollment-yes-link" class="btn-operations">
Update
</a>
<a href="#" id="update-enrollment-cancel-link" class="btn-operations">
Cancel
</a>
</div>
</div>
</div>
<div id="update-enrollment-200-content" class="hide">
<div class="modal-header">
<h3 class="pull-left modal-title">
Successfully updated enrollment.
</h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i
class="fw fw-cancel"></i>
</button>
</div>
<div class="modal-body add-margin-top-2x add-margin-bottom-2x">
</div>
<div class="modal-footer">
<div class="buttons">
<a href="javascript:hidePopup()" class="btn-operations">Ok</a>
</div>
</div>
</div>
<!--/update enrollment modal-->
</div>
</div>
</div>

@ -43,6 +43,9 @@ function onRequest(context) {
if (uiPermissions.ADD_DEVICE) {
viewModel.permissions.enroll = true;
}
if (uiPermissions.UPDATE_ENROLLMENT) {
viewModel.permissions.updateEnrollment = true;
}
viewModel.currentUser = currentUser;
var deviceCount = 0;
if (groupId) {
@ -56,12 +59,12 @@ function onRequest(context) {
var typesListResponse = deviceModule.getDeviceTypes();
var deviceTypes = [];
if (typesListResponse["status"] == "success") {
var data = typesListResponse.content.deviceTypes;
var data = typesListResponse.content;
if (data) {
for (var i = 0; i < data.length; i++) {
var config = utility.getDeviceTypeConfig(data[i]);
var config = utility.getDeviceTypeConfig(data[i].name);
var category = "iot";
var label = data[i];
var label = data[i].name;
var analyticsEnabled = "false";
var groupingEnabled = "true";
var analyticsView = null;
@ -75,10 +78,10 @@ function onRequest(context) {
}
deviceTypes.push({
"type": data[i],
"type": data[i].name,
"category": category,
"label": label,
"thumb": utility.getDeviceThumb(data[i]),
"thumb": utility.getDeviceThumb(data[i].name),
"analyticsEnabled": analyticsEnabled,
"groupingEnabled": groupingEnabled,
"analyticsView" : analyticsView

@ -809,6 +809,68 @@ function attachDeviceEvents() {
});
});
/**
* Following click function would execute
* when a user clicks on "Update Enrollment" link
* on Device Management page.
*/
$("a.update-enrollment-link").click(function () {
var deviceIdentifiers = [];
var deviceId = $(this).data("deviceid");
var deviceType = $(this).data("devicetype");
if (deviceId && deviceType) {
deviceIdentifiers = [{"id": deviceId, "type": deviceType}];
} else {
deviceIdentifiers = getSelectedDevices();
}
if (deviceIdentifiers.length === 0) {
$(modalPopupContent).html($('#no-device-selected').html());
$("a#no-device-selected-link").click(function () {
hidePopup();
});
showPopup();
return;
}
$(modalPopupContent).html($('#update-enrollment-modal-content').html());
showPopup();
$("a#update-enrollment-yes-link").click(function () {
var username = $("#update-enrollment-name").val();
console.log(username);
if (username) {
var i;
var deviceIds = [];
for (i=0; i<deviceIdentifiers.length; i++) {
deviceIds.push(deviceIdentifiers[i].id);
}
var serviceURL = "/api/device-mgt/v1.0/admin/devices/device-owner?owner=" + username;
invokerUtil.put(serviceURL, deviceIds, function (message) {
$(modalPopupContent).html($('#update-enrollment-200-content').html());
setTimeout(function () {
hidePopup();
location.reload(false);
}, 2000);
}, function (jqXHR) {
displayDeviceErrors(jqXHR);
});
} else {
$("div#update-enrollment-error-msg").text("Username cannot be empty");
$("div#update-enrollment-error-content").removeClass("hidden");
setTimeout(function() {
$("div#update-enrollment-error-content").addClass("hidden");
$("div#update-enrollment-error-msg").text();
}, 2000)
}
});
$("a#update-enrollment-cancel-link").click(function () {
hidePopup();
});
});
/**
* Following click function would execute
* when a user clicks on "Add to Group" link

@ -28,14 +28,14 @@ function onRequest(context) {
var utility = require("/app/modules/utility.js").utility;
var typesListResponse = deviceModule.getDeviceTypes();
if (typesListResponse["status"] == "success") {
var deviceTypes = typesListResponse.content.deviceTypes;
var deviceTypes = typesListResponse.content;
if (deviceTypes) {
if (deviceTypes.length > 0){
viewModel.hasDeviceTypes = true;
}
var deviceTypesList = [], virtualDeviceTypesList = [];
for (var i = 0; i < deviceTypes.length; i++) {
var deviceType = deviceTypes[i];
var deviceType = deviceTypes[i].name;
var deviceTypeLabel = deviceType;
var configs = utility.getDeviceTypeConfig(deviceTypeLabel);
var deviceCategory = "device";

@ -3,7 +3,7 @@
{{#each applications}}
<a style="text-align: center;width: 100px;height: 100px;">
{{#equal platform "android"}}<i class="fw fw-android"></i>{{/equal}}
{{#equal platform "ios"}}<i class="fw fw-apple"></i>{{/equal}}
{{#equal platform "ios"}}<i class="fw fw-ios"></i>{{/equal}}
{{#equal platform "windows"}}<i class="fw fw-windows"></i>{{/equal}}
<span>{{name}}</span>
</a>

@ -0,0 +1,41 @@
{{!
Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
WSO2 Inc. licenses this file to you under the Apache License,
Version 2.0 (the "License"); you may not use this file except
in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
}}
<div class="panel panel-default">
<div class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
Platform Configuration - {{@unit.params.deviceType}}
</h2>
</div>
<div id="{{@unit.params.deviceType}}-config-body" class="panel-collapse panel-body" role="tabpanel">
<div id="{{@unit.params.deviceType}}-config-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<div class="form-group" id="{{@unit.params.deviceType}}-config-field-wrapper">
</div>
<div class="wr-input-control wr-btn-grp">
<button class="wr-btn" onclick="onDynamicConfigSubmit('{{@unit.params.deviceType}}')">Save</button>
</div>
</div>
</div>
{{#zone "bottomJs"}}
<script type="text/javascript">
$(document).ready(function () {
loadDynamicDeviceTypeConfig('{{@unit.params.deviceType}}');
});
</script>
{{/zone}}

@ -15,6 +15,11 @@
specific language governing permissions and limitations
under the License.
}}
{{#zone "topCss"}}
{{css "css/platform-configuration.css"}}
{{/zone}}
{{#zone "content"}}
{{#if isAuthorized}}
<div class="row">
@ -37,7 +42,7 @@
<br>
<div class="wr-advance-operations">
<div class="row no-gutter">
<div class="row">
<div class="wr-hidden-operations-nav col-lg-4">
{{#unless isCloud}}
@ -63,7 +68,11 @@
<span class="fw-stack fw-move-right fw-move-bottom">
<i class="fw fw-circle fw-stack-2x fw-stroke fw-inverse"></i>
<i class="fw fw-circle fw-stack-2x"></i>
<i class="fw fw-{{name}} fw-stack-1x fw-inverse"></i>
{{#if unitName}}
<i class="fw fw-{{name}} fw-stack-1x fw-inverse"></i>
{{else}}
<i class="fw fw-devices fw-stack-1x fw-inverse"></i>
{{/if}}
</span>
</span>
{{label}} Configurations
@ -124,7 +133,11 @@
<!-- general-->
{{#each deviceTypes}}
<div class="wr-hidden-operation" data-operation="{{name}}" style="display: none;">
{{unit unitName}}
{{#if unitName}}
{{unit unitName deviceType=name}}
{{else}}
{{unit "cdmf.unit.dynamic.platform.configuration" deviceType=name}}
{{/if}}
</div>
{{/each}}

@ -14,6 +14,23 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://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.
*/
function onRequest(context) {
@ -29,23 +46,23 @@ function onRequest(context) {
var deviceTypesArray = [];
var typesListResponse = deviceModule.getDeviceTypes();
if (typesListResponse["status"] == "success") {
var data = typesListResponse["content"].deviceTypes;
var data = typesListResponse["content"];
if (data) {
for (var i = 0; i < data.length; i++) {
var deviceTypeName = data[i];
var deviceTypeName = data[i].name;
var deviceTypeLabel = deviceTypeName.charAt(0).toUpperCase() + deviceTypeName.slice(1);;
var configUnitName = utility.getTenantedDeviceUnitName(deviceTypeName, "platform.configuration");
if (configUnitName) {
var deviceTypeConfig = utility.getDeviceTypeConfig(deviceTypeName);
var deviceTypeLabel = deviceTypeName;
if (deviceTypeConfig) {
deviceTypeLabel = deviceTypeConfig.deviceType.label;
}
deviceTypesArray.push({
name: deviceTypeName,
label: deviceTypeLabel,
unitName: configUnitName
});
}
deviceTypesArray.push({
name: deviceTypeName,
label: deviceTypeLabel,
unitName: configUnitName
});
}
}
}

@ -16,6 +16,8 @@
* under the License.
*/
var configRowId = 0;
$(document).ready(function () {
var configParams = {
@ -41,25 +43,25 @@ $(document).ready(function () {
}
invokerUtil.get(
"/api/device-mgt/v1.0/configuration",
function (data) {
data = JSON.parse(data);
if (data && data.configuration) {
for (var i = 0; i < data.configuration.length; i++) {
var config = data.configuration[i];
if (config.name == configParams["NOTIFIER_FREQUENCY"]) {
$("input#monitoring-config-frequency").val(config.value / 1000);
}
"/api/device-mgt/v1.0/configuration",
function (data) {
data = JSON.parse(data);
if (data && data.configuration) {
for (var i = 0; i < data.configuration.length; i++) {
var config = data.configuration[i];
if (config.name == configParams["NOTIFIER_FREQUENCY"]) {
$("input#monitoring-config-frequency").val(config.value / 1000);
}
}
}, function (data) {
console.log(data);
});
}
}, function (data) {
console.log(data);
});
/**
* Following click function would execute
* when a user clicks on "Save" button
* on General platform configuration page in WSO2 EMM Console.
* on General platform configuration page in Entgra devicemgt Console.
*/
$("button#save-general-btn").click(function () {
var notifierFrequency = $("input#monitoring-config-frequency").val();
@ -87,33 +89,33 @@ $(document).ready(function () {
var addConfigAPI = "/api/device-mgt/v1.0/configuration";
invokerUtil.put(
addConfigAPI,
addConfigFormData,
function (data, textStatus, jqXHR) {
data = jqXHR.status;
if (data == 200) {
$("#config-save-form").addClass("hidden");
$("#record-created-msg").removeClass("hidden");
} else if (data == 500) {
$(errorMsg).text("Exception occurred at backend.");
} else if (data == 403) {
$(errorMsg).text("Action was not permitted.");
} else {
$(errorMsg).text("An unexpected error occurred.");
}
$(errorMsgWrapper).removeClass("hidden");
}, function (data) {
data = data.status;
if (data == 500) {
$(errorMsg).text("Exception occurred at backend.");
} else if (data == 403) {
$(errorMsg).text("Action was not permitted.");
} else {
$(errorMsg).text("An unexpected error occurred.");
}
$(errorMsgWrapper).removeClass("hidden");
addConfigAPI,
addConfigFormData,
function (data, textStatus, jqXHR) {
data = jqXHR.status;
if (data == 200) {
$("#config-save-form").addClass("hidden");
$("#record-created-msg").removeClass("hidden");
} else if (data == 500) {
$(errorMsg).text("Exception occurred at backend.");
} else if (data == 403) {
$(errorMsg).text("Action was not permitted.");
} else {
$(errorMsg).text("An unexpected error occurred.");
}
$(errorMsgWrapper).removeClass("hidden");
}, function (data) {
data = data.status;
if (data == 500) {
$(errorMsg).text("Exception occurred at backend.");
} else if (data == 403) {
$(errorMsg).text("Action was not permitted.");
} else {
$(errorMsg).text("An unexpected error occurred.");
}
$(errorMsgWrapper).removeClass("hidden");
}
);
}
});
@ -154,3 +156,121 @@ var artifactGeoUpload = function () {
showPopup();
}, contentType);
};
var loadDynamicDeviceTypeConfig = function (deviceType) {
var configAPI = '/api/device-mgt/v1.0/device-types/' + deviceType + '/configs';
invokerUtil.get(
configAPI,
function (data) {
data = JSON.parse(data);
var fieldWrapper = "#" + deviceType + "-config-field-wrapper";
$(fieldWrapper).html("");
if (data.configuration) {
var config;
var i;
for (i = 0; i < data.configuration.length; i++) {
config = data.configuration[i];
onDynamicConfigAddNew(deviceType, config.name, config.value);
}
}
$(fieldWrapper).append(
'<div class="row form-group ' + deviceType + '-config-row"' +
' id="' + deviceType + '-config-row-' + (++configRowId) + '">' +
'<div class="col-xs-3">' +
'<input type="text" class="form-control ' + deviceType + '-config-name" placeholder="name"/>' +
'</div>' +
'<div class="col-xs-4">' +
'<textarea aria-describedby="basic-addon1" placeholder="value" data-error-msg="invalid value"' +
' class="form-control ' + deviceType + '-config-value" rows="1" cols="30"></textarea>' +
'</div>' +
'<button type="button" class="wr-btn wr-btn-horizontal"' +
' onclick="onDynamicConfigAddNew(\'' + deviceType + '\', \'\', \'\')">' +
'<i class="fa fa-plus"></i>' +
'</button>' +
'</div>'
);
}, function (data) {
console.log(data);
}
);
};
var onDynamicConfigSubmit = function (deviceType) {
var errorMsgWrapper = "#" + deviceType + "-config-error-msg";
var errorMsg = "#" + deviceType + "-config-error-msg span";
var addConfigFormData = {};
var configList = [];
$('.' + deviceType + '-config-row').each(function () {
var configName = $(this).find("." + deviceType + "-config-name").val();
var configVal = $(this).find("." + deviceType + "-config-value").val();
if (configName && configName.trim() !== "" && configVal && configVal.trim() !== "") {
var configurationEntry = {};
configurationEntry.name = configName.trim();
configurationEntry.contentType = "text";
configurationEntry.value = configVal.trim();
configList.push(configurationEntry);
}
});
addConfigFormData.type = deviceType;
addConfigFormData.configuration = configList;
var addConfigAPI = '/api/device-mgt/v1.0/admin/device-types/' + deviceType + '/configs';
invokerUtil.post(
addConfigAPI,
addConfigFormData,
function (data, textStatus, jqXHR) {
data = jqXHR.status;
if (data == 200) {
$("#config-save-form").addClass("hidden");
$("#record-created-msg").removeClass("hidden");
} else if (data == 500) {
$(errorMsg).text("Exception occurred at backend.");
} else if (data == 400) {
$(errorMsg).text("Configurations cannot be empty.");
} else {
$(errorMsg).text("An unexpected error occurred.");
}
$(errorMsgWrapper).removeClass("hidden");
}, function (data) {
data = data.status;
if (data == 500) {
$(errorMsg).text("Exception occurred at backend.");
} else if (data == 403) {
$(errorMsg).text("Action was not permitted.");
} else {
$(errorMsg).text("An unexpected error occurred.");
}
$(errorMsgWrapper).removeClass("hidden");
}
);
};
var onDynamicConfigAddNew = function (deviceType, name, value) {
$("#" + deviceType + "-config-field-wrapper").append(
'<div class="row form-group ' + deviceType + '-config-row"' +
' id="' + deviceType + '-config-row-' + (++configRowId) + '">' +
'<div class="col-xs-3">' +
'<input type="text" class="form-control ' + deviceType + '-config-name" placeholder="name"' +
' value="' + name + '"/>' +
'</div>' +
'<div class="col-xs-4">' +
'<textarea aria-describedby="basic-addon1" placeholder="value" data-error-msg="invalid value"' +
' class="form-control ' + deviceType + '-config-value" rows="1" cols="30">' + value + '</textarea>' +
'</div>' +
'<button type="button" class="wr-btn wr-btn-horizontal"' +
' onclick="onDynamicConfigRemove(\'' + deviceType + '\', ' + configRowId + ')">' +
'<i class="fa fa-minus"></i>' +
'</button>' +
'</div>'
);
};
var onDynamicConfigRemove = function (deviceType, rawId) {
$("#" + deviceType + "-config-row-" + rawId).remove()
};

@ -50,7 +50,7 @@ function onRequest(context) {
types.isAuthorizedViewGroups = userModule.isAuthorized("/permission/admin/device-mgt/groups/view");
types["types"] = [];
var typesListResponse = deviceModule.getDeviceTypesConfig();
var typesListResponse = deviceModule.getDeviceTypes();
if (typesListResponse["status"] == "success") {
for (var type in typesListResponse["content"]) {
var content = {};

@ -118,7 +118,7 @@
{{/if}}
{{#if iosPluginFlag}}
<li>
<a href="{{@app.context}}/dep/devices"><i class="fw fw-apple"></i>
<a href="{{@app.context}}/dep/devices"><i class="fw fw-ios"></i>
DEP Configurations
</a>
</li>

@ -27,8 +27,8 @@ function onRequest(context) {
return options.fn(this);
}
});
var utility = require("/app/modules/utility.js").utility;
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"];
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
var constants = require("/app/modules/constants.js");
var uiPermissions = userModule.getUIPermissions();
@ -43,15 +43,10 @@ function onRequest(context) {
"device-mgt": []
};
var typesListResponse = deviceModule.getDeviceTypesConfig();
var temp = [];
temp = typesListResponse["content"];
var iosPluginFlag = false;
temp.forEach(function(element) {
if (element["name"] == "ios") {
iosPluginFlag = true;
}
});
if (utility.getTenantedDeviceUnitName("ios", "type-view")) {
iosPluginFlag = true;
}
context["iosPluginFlag"] = iosPluginFlag;
// following context.link value comes here based on the value passed at the point

Loading…
Cancel
Save