Merge branch 'master' into 'master'

Add capability to store device type specific platform configurations for any device type

See merge request entgra/carbon-device-mgt!69
revert-70aa11f8
Inosh Perara 6 years ago
commit f3a04e4baa

@ -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"/>

@ -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;
@ -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);
}

@ -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.");

@ -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");

@ -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);
}
}

@ -496,7 +496,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.

@ -39,6 +39,7 @@ import org.wso2.carbon.device.mgt.common.DeviceManager;
import org.wso2.carbon.device.mgt.common.DeviceNotFoundException;
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;
@ -172,14 +173,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]) {

@ -136,6 +136,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 +155,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"]);

@ -56,12 +56,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 +75,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

@ -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

@ -26,6 +26,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;
@ -499,7 +500,14 @@ public class DeviceManagementServiceImpl implements DeviceManagementService {
try {
RequestValidationUtil.validateDeviceIdentifier(type, id);
dms = DeviceMgtAPIUtils.getDeviceManagementService();
FeatureManager fm = dms.getFeatureManager(type);
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();
}
if (fm == null) {
return Response.status(Response.Status.NOT_FOUND).entity(
new ErrorResponse.ErrorResponseBuilder().setMessage("No feature manager is " +

@ -22,6 +22,7 @@ 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.push.notification.PushNotificationConfig;
@ -76,11 +77,18 @@ public class DeviceTypeManagementServiceImpl implements DeviceTypeManagementServ
DeviceManagementProviderService dms;
try {
dms = DeviceMgtAPIUtils.getDeviceManagementService();
FeatureManager fm = dms.getFeatureManager(type);
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();
}
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();
"registered with the given type '" + type + "'").build()).build();
}
features = fm.getFeatures();
} catch (DeviceManagementException e) {

@ -31,9 +31,9 @@ import org.testng.annotations.BeforeClass;
import org.testng.annotations.ObjectFactory;
import org.testng.annotations.Test;
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;
@ -437,7 +437,7 @@ public class DeviceManagementServiceImplTest {
}
@Test(description = "Testing getting device features when feature manager is not registered for the device type")
public void testGetFeaturesOfDeviceWhenFeatureManagerIsNotRegistered() throws DeviceManagementException {
public void testGetFeaturesOfDeviceWhenFeatureManagerIsNotRegistered() throws DeviceTypeNotFoundException {
PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService"))
.toReturn(this.deviceManagementProviderService);
Mockito.when(this.deviceManagementProviderService.getFeatureManager(Mockito.anyString())).thenReturn(null);
@ -448,14 +448,14 @@ public class DeviceManagementServiceImplTest {
}
@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);
}

Loading…
Cancel
Save