From e71c3623094ce67c25270ab3959103cce484cfad Mon Sep 17 00:00:00 2001 From: charitha Date: Sun, 14 Apr 2019 15:58:51 +0530 Subject: [PATCH 01/34] Add device type specific platform config endpoint --- .../api/DeviceTypeManagementService.java | 239 +++++++++++------- .../DeviceTypeManagementAdminService.java | 164 +++++++++++- .../impl/DeviceTypeManagementServiceImpl.java | 117 +++++---- .../DeviceTypeManagementAdminServiceImpl.java | 75 +++++- .../src/main/webapp/WEB-INF/cxf-servlet.xml | 2 +- .../devicemgt/app/conf/config.json | 3 + .../modules/business-controllers/device.js | 2 +- .../app/pages/cdmf.page.devices/devices.js | 10 +- .../cdmf.unit.device.types.listing/listing.js | 4 +- .../units/cdmf.unit.policy.create/create.js | 2 +- .../cdmf.unit.ui.navbar.nav-menu/nav-menu.js | 13 +- 11 files changed, 452 insertions(+), 179 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceTypeManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceTypeManagementService.java index 390bb2dca4..db10142cc4 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceTypeManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceTypeManagementService.java @@ -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(); + @Size(max = 45) + 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); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceTypeManagementAdminService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceTypeManagementAdminService.java index aa90b5b304..d669b2c309 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceTypeManagementAdminService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceTypeManagementAdminService.java @@ -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); + + } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceImpl.java index 5fdc06a501..2c22f76e77 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceImpl.java @@ -15,6 +15,23 @@ * 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; @@ -23,14 +40,13 @@ import org.apache.commons.logging.LogFactory; import org.wso2.carbon.device.mgt.common.DeviceManagementException; 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 +54,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 +66,6 @@ public class DeviceTypeManagementServiceImpl implements DeviceTypeManagementServ @GET @Override public Response getDeviceTypes(@HeaderParam("If-Modified-Since") String ifModifiedSince) { - List 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 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 deviceTypes = DeviceMgtAPIUtils.getDeviceManagementService().getDeviceTypes(); List filteredDeviceTypes = new ArrayList<>(); @@ -111,8 +82,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(max = 45) String type) { if (type != null && type.length() > 0) { try { DeviceType deviceType = DeviceMgtAPIUtils.getDeviceManagementService().getDeviceType(type); @@ -120,7 +91,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 +102,52 @@ 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 features; + DeviceManagementProviderService dms; + try { + dms = DeviceMgtAPIUtils.getDeviceManagementService(); + FeatureManager fm = dms.getFeatureManager(type); + if (fm == null) { + features = new ArrayList<>(); + } else { + 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(max = 45) String type, + @HeaderParam("If-Modified-Since") String ifModifiedSince) { + PlatformConfiguration platformConfiguration; + try { + platformConfiguration = DeviceMgtAPIUtils.getDeviceManagementService().getConfiguration(type); + } 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(); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceTypeManagementAdminServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceTypeManagementAdminServiceImpl.java index 57c0b7cde6..d7f659871d 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceTypeManagementAdminServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceTypeManagementAdminServiceImpl.java @@ -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(); + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/cxf-servlet.xml b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/cxf-servlet.xml index e1e2c46e8c..7a2013037a 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/cxf-servlet.xml +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/cxf-servlet.xml @@ -66,7 +66,7 @@ - + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/conf/config.json b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/conf/config.json index ffe9bcaa86..8e74ac0232 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/conf/config.json +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/conf/config.json @@ -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", diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/device.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/device.js index 16be67eb43..ca8fa6dbd8 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/device.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/device.js @@ -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"]); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devices/devices.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devices/devices.js index c973d07985..41afed6ae9 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devices/devices.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devices/devices.js @@ -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 diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.types.listing/listing.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.types.listing/listing.js index 9b0cdacddb..23ee3e59d0 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.types.listing/listing.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.types.listing/listing.js @@ -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"; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.policy.create/create.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.policy.create/create.js index db1d8169a2..94f0b1235b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.policy.create/create.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.policy.create/create.js @@ -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 = {}; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.navbar.nav-menu/nav-menu.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.navbar.nav-menu/nav-menu.js index 5bbd9926bf..3fce92e8e7 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.navbar.nav-menu/nav-menu.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.navbar.nav-menu/nav-menu.js @@ -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 From fbaf21adc68669bb1851976d1728ec6d4ddfb663 Mon Sep 17 00:00:00 2001 From: charitha Date: Wed, 17 Apr 2019 02:18:16 +0530 Subject: [PATCH 02/34] Add device type specific platform config UIs --- .../api/DeviceTypeManagementService.java | 2 +- .../impl/DeviceTypeManagementServiceImpl.java | 9 +- .../public/images/thumb.png | Bin 42033 -> 26701 bytes .../public/templates/applications-list.hbs | 2 +- .../configuration.hbs | 41 + .../configuration.json | 3 + .../configuration.hbs | 19 +- .../configuration.js | 33 +- .../public/js/platform-configuration.js | 198 +- .../cdmf.unit.ui.navbar.nav-menu/nav-menu.hbs | 2 +- .../lib/font-wso2-1.3.0/css/font-wso2.css | 3004 ++++++++--------- .../lib/font-wso2-1.3.0/css/font-wso2.min.css | 30 +- 12 files changed, 1771 insertions(+), 1572 deletions(-) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.dynamic.platform.configuration/configuration.hbs create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.dynamic.platform.configuration/configuration.json diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceTypeManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceTypeManagementService.java index db10142cc4..1b59cfe4fd 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceTypeManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceTypeManagementService.java @@ -348,7 +348,7 @@ public interface DeviceTypeManagementService { value = "The device type name, such as ios, android, windows or fire-alarm.", required = true) @PathParam("type") - @Size(max = 45) + @Size(min = 2, max = 45) String type, @ApiParam( name = "If-Modified-Since", diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceImpl.java index 2c22f76e77..b20b3462de 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceImpl.java @@ -83,7 +83,7 @@ public class DeviceTypeManagementServiceImpl implements DeviceTypeManagementServ @Override @GET @Path("/{type}") - public Response getDeviceTypeByName(@PathParam("type") @Size(max = 45) String 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); @@ -129,11 +129,16 @@ public class DeviceTypeManagementServiceImpl implements DeviceTypeManagementServ @GET @Override @Path("/{type}/configs") - public Response getConfigs(@PathParam("type") @Size(max = 45) String type, + 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); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.type-view/public/images/thumb.png b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.type-view/public/images/thumb.png index 71e5c0c28b8161aab740a38422f10de5ca3ae955..109ed11017ae0b2a61e1ce0abd616cfbb462f916 100644 GIT binary patch literal 26701 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 Lid2<^S=j#qJ$(xW literal 42033 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 diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.view/public/templates/applications-list.hbs b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.view/public/templates/applications-list.hbs index 8fba28621b..2f6af71aa6 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.view/public/templates/applications-list.hbs +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.view/public/templates/applications-list.hbs @@ -3,7 +3,7 @@ {{#each applications}} {{#equal platform "android"}}{{/equal}} - {{#equal platform "ios"}}{{/equal}} + {{#equal platform "ios"}}{{/equal}} {{#equal platform "windows"}}{{/equal}} {{name}} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.dynamic.platform.configuration/configuration.hbs b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.dynamic.platform.configuration/configuration.hbs new file mode 100644 index 0000000000..b4c64f7fd5 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.dynamic.platform.configuration/configuration.hbs @@ -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. +}} +
+ +
+ +
+
+
+ +
+
+
+{{#zone "bottomJs"}} + +{{/zone}} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.dynamic.platform.configuration/configuration.json b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.dynamic.platform.configuration/configuration.json new file mode 100644 index 0000000000..fd25901297 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.dynamic.platform.configuration/configuration.json @@ -0,0 +1,3 @@ +{ + "version" : "1.0.0" +} \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.platform.configuration/configuration.hbs b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.platform.configuration/configuration.hbs index 1d42bd01d8..597b38ce18 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.platform.configuration/configuration.hbs +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.platform.configuration/configuration.hbs @@ -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}}
@@ -37,7 +42,7 @@
-
+
{{#unless isCloud}} @@ -63,7 +68,11 @@ - + {{#if unitName}} + + {{else}} + + {{/if}} {{label}} Configurations @@ -124,7 +133,11 @@ {{#each deviceTypes}} {{/each}} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.platform.configuration/configuration.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.platform.configuration/configuration.js index 361579554f..4fc10b836f 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.platform.configuration/configuration.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.platform.configuration/configuration.js @@ -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 + }); } } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.platform.configuration/public/js/platform-configuration.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.platform.configuration/public/js/platform-configuration.js index 45f753b4ed..d3a2152b06 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.platform.configuration/public/js/platform-configuration.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.platform.configuration/public/js/platform-configuration.js @@ -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( + '
' + + '
' + + '' + + '
' + + '
' + + '' + + '
' + + '' + + '
' + ); + }, 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( + '
' + + '
' + + '' + + '
' + + '
' + + '' + + '
' + + '' + + '
' + ); +}; + +var onDynamicConfigRemove = function (deviceType, rawId) { + $("#" + deviceType + "-config-row-" + rawId).remove() +}; \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.navbar.nav-menu/nav-menu.hbs b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.navbar.nav-menu/nav-menu.hbs index b071abf81d..8c80bd6fc7 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.navbar.nav-menu/nav-menu.hbs +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.navbar.nav-menu/nav-menu.hbs @@ -118,7 +118,7 @@ {{/if}} {{#if iosPluginFlag}}
  • - + DEP Configurations
  • diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/css/font-wso2.css b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/css/font-wso2.css index 870013db19..c6544d6f2e 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/css/font-wso2.css +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/css/font-wso2.css @@ -1,1506 +1,1506 @@ -/*! -~ Copyright (c) WSO2 Inc. (http://wso2.com) All Rights Reserved. -~ -~ Licensed 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. -*/ - - -@font-face { - font-family:"font-wso2"; - src:local("font-wso2"), url("../fonts/font-wso2.eot?6563fa91278f239ef8c827d90a165223"); - src:local("font-wso2"), +/*! +~ Copyright (c) WSO2 Inc. (http://wso2.com) All Rights Reserved. +~ +~ Licensed 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. +*/ + + +@font-face { + font-family:"font-wso2"; + src:local("font-wso2"), url("../fonts/font-wso2.eot?6563fa91278f239ef8c827d90a165223"); + src:local("font-wso2"), url("../fonts/font-wso2.eot?#iefix") format("embedded-opentype"), url("../fonts/font-wso2.woff2?6563fa91278f239ef8c827d90a165223") format("woff2"), url("../fonts/font-wso2.woff?6563fa91278f239ef8c827d90a165223") format("woff"), url("../fonts/font-wso2.ttf?6563fa91278f239ef8c827d90a165223") format("truetype"), - url("../fonts/font-wso2.svg?6563fa91278f239ef8c827d90a165223#font-wso2") format("svg"); - font-weight:normal; - font-style:normal; -} - -.fw, [class^="fw-"], [class*=" fw-"] { - font: normal normal normal 14px/1 font-wso2; - display: inline-block; - font-weight: normal; - font-style: normal; - font-size: inherit; - font-variant: normal; - speak: none; - text-decoration: inherit; - - /* Better Font Rendering =========== */ - text-transform: none; - text-rendering: auto; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - - -/* ======================================================================== - * font options - * ======================================================================== */ - -.fw-lg { - font-size: 1.33333333em; - line-height: 0.75em; - vertical-align: -15%; -} -.fw-2x { - font-size: 2em; -} -.fw-3x { - font-size: 3em; -} -.fw-4x { - font-size: 4em; -} -.fw-5x { - font-size: 5em; -} -.fw-fw { - width: 1.28571429em; - text-align: center; -} -.fw-ul { - padding-left: 0; - margin-left: 2.14285714em; - list-style-type: none; -} -.fw-ul > li { - position: relative; -} -.fw-li { - position: absolute; - left: -2.14285714em; - width: 2.14285714em; - top: 0.14285714em; - text-align: center; -} -.fw-li.fw-lg { - left: -1.85714286em; -} -.fw-border { - padding: .2em .25em .15em; - border: solid 0.08em #eeeeee; - border-radius: .1em; -} -.fw-background { - background: #888; - border-radius: .3em; - padding: .4em .50em .45em; -} -.fw-pull-left { - float: left; -} -.fw-pull-right { - float: right; -} -.fw.fw-pull-left { - margin-right: .3em; -} -.fw.fw-pull-right { - margin-left: .3em; -} -.fw-spin { - -webkit-animation: fw-spin 2s infinite linear; - animation: fw-spin 2s infinite linear; -} -@-webkit-keyframes fw-spin { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - 100% { - -webkit-transform: rotate(359deg); - transform: rotate(359deg); - } -} -@keyframes fw-spin { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - 100% { - -webkit-transform: rotate(359deg); - transform: rotate(359deg); - } -} -.fw-pulse { - -webkit-animation: fw-pulse 2s ease-out infinite; - animation: fw-pulse 2s ease-out infinite; -} -@-webkit-keyframes fw-pulse { - 0%, 30% { - opacity: 0.3; - } - 40% { - opacity: 1; - } - 100% { - opacity: 0.3; - } -} -@keyframes fw-pulse { - 0%, 30% { - opacity: 0.3; - } - 40% { - opacity: 1; - } - 100% { - opacity: 0.3; - } -} -.fw-rotate-90 { - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); - -webkit-transform: rotate(90deg); - -ms-transform: rotate(90deg); - transform: rotate(90deg); -} -.fw-rotate-180 { - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2); - -webkit-transform: rotate(180deg); - -ms-transform: rotate(180deg); - transform: rotate(180deg); -} -.fw-rotate-270 { - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); - -webkit-transform: rotate(270deg); - -ms-transform: rotate(270deg); - transform: rotate(270deg); -} -.fw-flip-horizontal { - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1); - -webkit-transform: scale(-1, 1); - -ms-transform: scale(-1, 1); - transform: scale(-1, 1); -} -.fw-flip-vertical { - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1); - -webkit-transform: scale(1, -1); - -ms-transform: scale(1, -1); - transform: scale(1, -1); -} -:root .fw-rotate-90, -:root .fw-rotate-180, -:root .fw-rotate-270, -:root .fw-flip-horizontal, -:root .fw-flip-vertical { - filter: none; -} -.fw-stack, -.fw-helper { - position: relative; - display: inline-block; - width: 2em; - height: 2em; - line-height: 1.85em; - vertical-align: middle; -} -.fw-stack-1x, -.fw-stack-2x, -.fw-helper:before, -.fw-helper:after { - position: absolute; - left: 0; - width: 100%; - text-align: center; -} -.fw-stack-1x, -.fw-helper:before { - line-height: inherit; -} -.fw-stack-2x, -.fw-helper:after { - font-size: 1.9em; -} -.fw-helper-slash:before { - font-size: 1.4em; -} -.fw-helper-circle:before, -.fw-helper-square:before { - z-index: 1; -} -.fw-helper-circle-outline:after { - content: "\e61f"; -} -.fw-helper-circle:after { - content: "\e61a"; -} -.fw-helper-square-outline:after { - content: "\e6b2"; -} -.fw-helper-square:after { - content: "\e6b1"; -} -.fw-helper-slash:after { - content: "\e6e1"; -} -.fw-stack > .fw-stack { - position: absolute; - font-size: 0.5em; -} -.fw-stack > .fw-stack.fw-move-top { - top: -0.2em; -} -.fw-stack > .fw-stack.fw-move-bottom { - bottom: -0.2em; -} -.fw-stack > .fw.stack.fw-move-left { - left: -0.5em; -} -.fw-stack > .fw-stack.fw-move-right { - right: -0.5em; -} -.fw-inverse:before, -.fw-helper-inverse:after, -.fw-number { - color: #ffffff; -} -.fw-shadow:before, -.fw-helper-shadow:after { - text-shadow: #ffffff 1px 1px 0; -} -.fw-stroke:before, -.fw-helper-stroke:after { - text-shadow: -2px -2px 0 #ffffff, - 2px -2px 0 #ffffff, - -2px 2px 0 #ffffff, - 2px 2px 0 #ffffff; -} -.fw-number { - line-height: 2em; - font-family: Arial, Helvetica, sans-serif; -} - - -/* ======================================================================== - * font icons - * ======================================================================== */ - -.fw-abort:before { - content:"\e72a"; -} - -.fw-action-invoke:before { - content:"\e6fe"; -} - -.fw-action:before { - content:"\e709"; -} - -.fw-activate:before { - content:"\e6cf"; -} - -.fw-add:before { - content:"\e615"; -} - -.fw-airplay:before { - content:"\e600"; -} - -.fw-alarm:before { - content:"\e6c2"; -} - -.fw-alert:before { - content:"\e6be"; -} - -.fw-analytics-extensions:before { - content:"\e6e2"; -} - -.fw-android-logcat:before { - content:"\e72c"; -} - -.fw-android-sense:before { - content:"\e72d"; -} - -.fw-android:before { - content:"\e606"; -} - -.fw-annotation:before { - content:"\e6e6"; -} - -.fw-api:before { - content:"\e601"; -} - -.fw-apn:before { - content:"\e602"; -} - -.fw-apple:before { - content:"\e604"; -} - -.fw-application:before { - content:"\e608"; -} - -.fw-arduino:before { - content:"\e6ab"; -} - -.fw-assign:before { - content:"\e6ff"; -} - -.fw-ballerina-service:before { - content:"\e729"; -} - -.fw-ballerina:before { - content:"\e728"; -} - -.fw-bar-chart:before { - content:"\e690"; -} - -.fw-battery:before { - content:"\e60a"; -} - -.fw-blank-document:before { - content:"\e60c"; -} - -.fw-block:before { - content:"\e695"; -} - -.fw-bookmark:before { - content:"\e60d"; -} - -.fw-bpel:before { - content:"\e60e"; -} - -.fw-bpmn:before { - content:"\e60f"; -} - -.fw-break:before { - content:"\e721"; -} - -.fw-bug:before { - content:"\e611"; -} - -.fw-build:before { - content:"\e6c1"; -} - -.fw-calendar:before { - content:"\e612"; -} - -.fw-camera:before { - content:"\e613"; -} - -.fw-cancel:before { - content:"\e618"; -} - -.fw-carbon:before { - content:"\e6c5"; -} - -.fw-chat:before { - content:"\e65b"; -} - -.fw-check:before { - content:"\e617"; -} - -.fw-checklist:before { - content:"\e619"; -} - -.fw-circle-outline:before { - content:"\e61f"; -} - -.fw-circle:before { - content:"\e61a"; -} - -.fw-clear:before { - content:"\e61b"; -} - -.fw-clock:before { - content:"\e61d"; -} - -.fw-cloud:before { - content:"\e61e"; -} - -.fw-code-view:before { - content:"\e70e"; -} - -.fw-code:before { - content:"\e6f1"; -} - -.fw-comment:before { - content:"\e710"; -} - -.fw-compare:before { - content:"\e610"; -} - -.fw-computer:before { - content:"\e653"; -} - -.fw-configarations:before { - content:"\e609"; -} - -.fw-connector:before { - content:"\e700"; -} - -.fw-console:before { - content:"\e71d"; -} - -.fw-constant:before { - content:"\e701"; -} - -.fw-contact:before { - content:"\e620"; -} - -.fw-contract:before { - content:"\e614"; -} - -.fw-copy:before { - content:"\e621"; -} - -.fw-cut:before { - content:"\e6f2"; -} - -.fw-dashboard:before { - content:"\e622"; -} - -.fw-database:before { - content:"\e623"; -} - -.fw-delete:before { - content:"\e624"; -} - -.fw-depend:before { - content:"\e6c6"; -} - -.fw-deploy:before { - content:"\e625"; -} - -.fw-deprecate:before { - content:"\e6cb"; -} - -.fw-design-view:before { - content:"\e70f"; -} - -.fw-devices:before { - content:"\e704"; -} - -.fw-dgm-action-invoke:before { - content:"\e712"; -} - -.fw-dgm-action:before { - content:"\e711"; -} - -.fw-dgm-connector:before { - content:"\e6f4"; -} - -.fw-dgm-constant-definition:before { - content:"\e6f5"; -} - -.fw-dgm-fork:before { - content:"\e6e7"; -} - -.fw-dgm-header:before { - content:"\e6e8"; -} - -.fw-dgm-if-else:before { - content:"\e6e9"; -} - -.fw-dgm-import:before { - content:"\e717"; -} - -.fw-dgm-lifeline:before { - content:"\e6ea"; -} - -.fw-dgm-logger:before { - content:"\e6eb"; -} - -.fw-dgm-resource:before { - content:"\e6f6"; -} - -.fw-dgm-service:before { - content:"\e6f7"; -} - -.fw-dgm-try-catch:before { - content:"\e6ec"; -} - -.fw-dgm-type-convertor:before { - content:"\e6f8"; -} - -.fw-dgm-type:before { - content:"\e6f9"; -} - -.fw-dgm-while:before { - content:"\e707"; -} - -.fw-dial-up:before { - content:"\e627"; -} - -.fw-disabled:before { - content:"\e6d1"; -} - -.fw-display:before { - content:"\e626"; -} - -.fw-docker:before { - content:"\e70c"; -} - -.fw-document:before { - content:"\e628"; -} - -.fw-down-arrow:before { - content:"\e689"; -} - -.fw-down:before { - content:"\e685"; -} - -.fw-download:before { - content:"\e65f"; -} - -.fw-dss:before { - content:"\e62a"; -} - -.fw-ebook:before { - content:"\e62b"; -} - -.fw-edit:before { - content:"\e62c"; -} - -.fw-ellipsis:before { - content:"\e629"; -} - -.fw-endpoint:before { - content:"\e62d"; -} - -.fw-enterprise:before { - content:"\e6b6"; -} - -.fw-error:before { - content:"\e630"; -} - -.fw-esb-connector:before { - content:"\e6e3"; -} - -.fw-expand:before { - content:"\e61c"; -} - -.fw-export:before { - content:"\e631"; -} - -.fw-extensions:before { - content:"\e6e4"; -} - -.fw-facebook:before { - content:"\e6d3"; -} - -.fw-factory-reset:before { - content:"\e632"; -} - -.fw-fan:before { - content:"\e678"; -} - -.fw-faq:before { - content:"\e62f"; -} - -.fw-file-browse:before { - content:"\e633"; -} - -.fw-filter:before { - content:"\e634"; -} - -.fw-folder-open:before { - content:"\e70b"; -} - -.fw-folder:before { - content:"\e62e"; -} - -.fw-fork-join:before { - content:"\e720"; -} - -.fw-format:before { - content:"\e6fa"; -} - -.fw-forum:before { - content:"\e636"; -} - -.fw-function-invoke:before { - content:"\e713"; -} - -.fw-function:before { - content:"\e6fb"; -} - -.fw-gadget:before { - content:"\e637"; -} - -.fw-geo-fence-inbound:before { - content:"\e72e"; -} - -.fw-geo-fence-outbound:before { - content:"\e72f"; -} - -.fw-github:before { - content:"\e6d4"; -} - -.fw-globe:before { - content:"\e697"; -} - -.fw-google-docs:before { - content:"\e6d6"; -} - -.fw-google-drive:before { - content:"\e6da"; -} - -.fw-google-plus:before { - content:"\e6d9"; -} - -.fw-google-sheets:before { - content:"\e6d7"; -} - -.fw-google-slides:before { - content:"\e6d8"; -} - -.fw-google:before { - content:"\e6d5"; -} - -.fw-grid:before { - content:"\e638"; -} - -.fw-grip:before { - content:"\e6b7"; -} - -.fw-group:before { - content:"\e6af"; -} - -.fw-hardware:before { - content:"\e6a9"; -} - -.fw-hdd:before { - content:"\e639"; -} - -.fw-heart:before { - content:"\e6c3"; -} - -.fw-hide:before { - content:"\e6d2"; -} - -.fw-home:before { - content:"\e63a"; -} - -.fw-hour-glass:before { - content:"\e63b"; -} - -.fw-html:before { - content:"\e69d"; -} - -.fw-http:before { - content:"\e705"; -} - -.fw-image:before { - content:"\e70a"; -} - -.fw-import:before { - content:"\e63c"; -} - -.fw-incoming-call:before { - content:"\e63d"; -} - -.fw-info:before { - content:"\e63e"; -} - -.fw-instagram:before { - content:"\e6db"; -} - -.fw-invitation:before { - content:"\e63f"; -} - -.fw-invoke:before { - content:"\e6ed"; -} - -.fw-is-connector:before { - content:"\e6e5"; -} - -.fw-iterate:before { - content:"\e71f"; -} - -.fw-jaggery:before { - content:"\e640"; -} - -.fw-java-spring:before { - content:"\e644"; -} - -.fw-java:before { - content:"\e641"; -} - -.fw-javaee:before { - content:"\e642"; -} - -.fw-javascript:before { - content:"\e643"; -} - -.fw-jaxrs:before { - content:"\e645"; -} - -.fw-jaxws:before { - content:"\e6c7"; -} - -.fw-jquery:before { - content:"\e646"; -} - -.fw-key:before { - content:"\e647"; -} - -.fw-laptop:before { - content:"\e648"; -} - -.fw-layout:before { - content:"\e6bf"; -} - -.fw-ldap:before { - content:"\e649"; -} - -.fw-left-arrow:before { - content:"\e68a"; -} - -.fw-left:before { - content:"\e686"; -} - -.fw-lifecycle:before { - content:"\e64a"; -} - -.fw-light:before { - content:"\e680"; -} - -.fw-linkedin:before { - content:"\e6dc"; -} - -.fw-list-sort:before { - content:"\e64d"; -} - -.fw-list:before { - content:"\e64c"; -} - -.fw-loader:before { - content:"\e6b4"; -} - -.fw-loader2:before { - content:"\e6ba"; -} - -.fw-loader3:before { - content:"\e6bb"; -} - -.fw-loader4:before { - content:"\e6bc"; -} - -.fw-loader5:before { - content:"\e6bd"; -} - -.fw-lock:before { - content:"\e64e"; -} - -.fw-logical:before { - content:"\e702"; -} - -.fw-mail:before { - content:"\e64f"; -} - -.fw-main-function:before { - content:"\e706"; -} - -.fw-map-location:before { - content:"\e650"; -} - -.fw-menu:before { - content:"\e651"; -} - -.fw-message:before { - content:"\e635"; -} - -.fw-micro-services:before { - content:"\e6ce"; -} - -.fw-minus:before, .fw-hyphen:before, .fw-dash:before { - content:"\e616"; -} - -.fw-mobile:before { - content:"\e652"; -} - -.fw-ms-document:before { - content:"\e654"; -} - -.fw-mute:before { - content:"\e655"; -} - -.fw-nodejs:before { - content:"\e656"; -} - -.fw-notification:before { - content:"\e60b"; -} - -.fw-organization:before { - content:"\e6ac"; -} - -.fw-own:before { - content:"\e6c8"; -} - -.fw-package:before { - content:"\e6fd"; -} - -.fw-pages:before { - content:"\e6c0"; -} - -.fw-paste:before { - content:"\e658"; -} - -.fw-pdf:before { - content:"\e659"; -} - -.fw-pending:before { - content:"\e727"; -} - -.fw-php:before { - content:"\e6c9"; -} - -.fw-pie-chart:before { - content:"\e65a"; -} - -.fw-pinterest:before { - content:"\e6dd"; -} - -.fw-policy:before { - content:"\e67d"; -} - -.fw-polygon:before { - content:"\e70d"; -} - -.fw-prototype:before { - content:"\e6cc"; -} - -.fw-proxy:before { - content:"\e699"; -} - -.fw-public:before { - content:"\e6ad"; -} - -.fw-publish:before { - content:"\e65c"; -} - -.fw-question:before { - content:"\e6b0"; -} - -.fw-raspberry:before { - content:"\e6aa"; -} - -.fw-redo:before { - content:"\e65d"; -} - -.fw-refresh:before { - content:"\e692"; -} - -.fw-register:before { - content:"\e65e"; -} - -.fw-rename:before { - content:"\e6fc"; -} - -.fw-reply:before { - content:"\e714"; -} - -.fw-resource:before { - content:"\e660"; -} - -.fw-rest-api:before { - content:"\e661"; -} - -.fw-rest-service:before { - content:"\e662"; -} - -.fw-resume:before { - content:"\e71e"; -} - -.fw-retire:before { - content:"\e6cd"; -} - -.fw-return:before { - content:"\e715"; -} - -.fw-retweet:before { - content:"\e6b9"; -} - -.fw-right-arrow:before { - content:"\e68b"; -} - -.fw-right:before { - content:"\e687"; -} - -.fw-ringing:before { - content:"\e694"; -} - -.fw-rules:before { - content:"\e664"; -} - -.fw-run:before { - content:"\e708"; -} - -.fw-save:before { - content:"\e665"; -} - -.fw-scep:before { - content:"\e666"; -} - -.fw-schema:before { - content:"\e667"; -} - -.fw-search:before { - content:"\e668"; -} - -.fw-security-policy:before { - content:"\e67e"; -} - -.fw-security:before { - content:"\e669"; -} - -.fw-send:before, .fw-paper-rocket:before { - content:"\e66a"; -} - -.fw-sequence:before { - content:"\e66b"; -} - -.fw-server:before { - content:"\e66c"; -} - -.fw-service-provider:before { - content:"\e66e"; -} - -.fw-service:before, .fw-cogwheels:before, .fw-gears:before, .fw-sprockets:before { - content:"\e66d"; -} - -.fw-settings:before, .fw-cogwheel:before, .fw-gear:before, .fw-sprocket:before { - content:"\e66f"; -} - -.fw-share:before { - content:"\e670"; -} - -.fw-shell:before { - content:"\e730"; -} - -.fw-shortcut:before { - content:"\e725"; -} - -.fw-sign-in:before { - content:"\e671"; -} - -.fw-sign-out:before { - content:"\e6b8"; -} - -.fw-skype:before { - content:"\e6de"; -} - -.fw-slash:before { - content:"\e6e1"; -} - -.fw-soap:before { - content:"\e672"; -} - -.fw-sort-down:before { - content:"\e663"; -} - -.fw-sort-up:before { - content:"\e64b"; -} - -.fw-sort:before { - content:"\e673"; -} - -.fw-speed-alert:before { - content:"\e731"; -} - -.fw-square-outline:before { - content:"\e6b2"; -} - -.fw-square:before { - content:"\e6b1"; -} - -.fw-star:before { - content:"\e674"; -} - -.fw-start:before { - content:"\e718"; -} - -.fw-statistics:before { - content:"\e675"; -} - -.fw-stepin:before { - content:"\e719"; -} - -.fw-stepout:before { - content:"\e71a"; -} - -.fw-stepover:before { - content:"\e71b"; -} - -.fw-stop:before { - content:"\e71c"; -} - -.fw-store:before, .fw-cart:before { - content:"\e676"; -} - -.fw-struct:before { - content:"\e716"; -} - -.fw-subscribe:before { - content:"\e677"; -} - -.fw-success:before { - content:"\e657"; -} - -.fw-swagger:before { - content:"\e679"; -} - -.fw-sync:before { - content:"\e6b3"; -} - -.fw-table:before { - content:"\e6c4"; -} - -.fw-tag:before { - content:"\e67a"; -} - -.fw-task:before { - content:"\e67b"; -} - -.fw-text:before { - content:"\e67c"; -} - -.fw-theme:before { - content:"\e726"; -} - -.fw-throttling-policy:before { - content:"\e67f"; -} - -.fw-throw:before { - content:"\e722"; -} - -.fw-tiles:before { - content:"\e681"; -} - -.fw-transaction:before { - content:"\e72b"; -} - -.fw-try-catch:before { - content:"\e703"; -} - -.fw-twitter:before { - content:"\e6df"; -} - -.fw-type-converter:before { - content:"\e6f3"; -} - -.fw-uncheck:before { - content:"\e682"; -} - -.fw-undo:before { - content:"\e683"; -} - -.fw-ungroup:before { - content:"\e6b5"; -} - -.fw-unmute:before { - content:"\e6ae"; -} - -.fw-up-arrow:before { - content:"\e688"; -} - -.fw-up:before { - content:"\e684"; -} - -.fw-upload:before { - content:"\e68c"; -} - -.fw-uri:before { - content:"\e68d"; -} - -.fw-usb-drive:before { - content:"\e68e"; -} - -.fw-use:before { - content:"\e6ca"; -} - -.fw-user:before { - content:"\e68f"; -} - -.fw-variable:before { - content:"\e6ee"; -} - -.fw-view:before { - content:"\e691"; -} - -.fw-vpn:before { - content:"\e603"; -} - -.fw-wadl:before { - content:"\e6a1"; -} - -.fw-war:before { - content:"\e69e"; -} - -.fw-warning:before { - content:"\e693"; -} - -.fw-web-app:before { - content:"\e696"; -} - -.fw-web-clip:before { - content:"\e698"; -} - -.fw-web-service:before { - content:"\e69a"; -} - -.fw-website:before { - content:"\e69b"; -} - -.fw-wifi:before { - content:"\e607"; -} - -.fw-windows:before { - content:"\e605"; -} - -.fw-worker-invoke:before { - content:"\e723"; -} - -.fw-worker-reply:before { - content:"\e724"; -} - -.fw-worker:before { - content:"\e6ef"; -} - -.fw-wsdl:before { - content:"\e6a0"; -} - -.fw-wso2-logo:before { - content:"\e6a7"; -} - -.fw-wso2:before { - content:"\e6a8"; -} - -.fw-xacml:before { - content:"\e69f"; -} - -.fw-xml:before { - content:"\e69c"; -} - -.fw-xq:before { - content:"\e6a2"; -} - -.fw-xsd:before { - content:"\e6a3"; -} - -.fw-xslt:before { - content:"\e6a4"; -} - -.fw-youtube:before { - content:"\e6e0"; -} - -.fw-zoom-in:before { - content:"\e6a5"; -} - -.fw-zoom-out:before { - content:"\e6a6"; -} - + url("../fonts/font-wso2.svg?6563fa91278f239ef8c827d90a165223#font-wso2") format("svg"); + font-weight:normal; + font-style:normal; +} + +.fw, [class^="fw-"], [class*=" fw-"] { + font: normal normal normal 14px/1 font-wso2; + display: inline-block; + font-weight: normal; + font-style: normal; + font-size: inherit; + font-variant: normal; + speak: none; + text-decoration: inherit; + + /* Better Font Rendering =========== */ + text-transform: none; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + + +/* ======================================================================== + * font options + * ======================================================================== */ + +.fw-lg { + font-size: 1.33333333em; + line-height: 0.75em; + vertical-align: -15%; +} +.fw-2x { + font-size: 2em; +} +.fw-3x { + font-size: 3em; +} +.fw-4x { + font-size: 4em; +} +.fw-5x { + font-size: 5em; +} +.fw-fw { + width: 1.28571429em; + text-align: center; +} +.fw-ul { + padding-left: 0; + margin-left: 2.14285714em; + list-style-type: none; +} +.fw-ul > li { + position: relative; +} +.fw-li { + position: absolute; + left: -2.14285714em; + width: 2.14285714em; + top: 0.14285714em; + text-align: center; +} +.fw-li.fw-lg { + left: -1.85714286em; +} +.fw-border { + padding: .2em .25em .15em; + border: solid 0.08em #eeeeee; + border-radius: .1em; +} +.fw-background { + background: #888; + border-radius: .3em; + padding: .4em .50em .45em; +} +.fw-pull-left { + float: left; +} +.fw-pull-right { + float: right; +} +.fw.fw-pull-left { + margin-right: .3em; +} +.fw.fw-pull-right { + margin-left: .3em; +} +.fw-spin { + -webkit-animation: fw-spin 2s infinite linear; + animation: fw-spin 2s infinite linear; +} +@-webkit-keyframes fw-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes fw-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +.fw-pulse { + -webkit-animation: fw-pulse 2s ease-out infinite; + animation: fw-pulse 2s ease-out infinite; +} +@-webkit-keyframes fw-pulse { + 0%, 30% { + opacity: 0.3; + } + 40% { + opacity: 1; + } + 100% { + opacity: 0.3; + } +} +@keyframes fw-pulse { + 0%, 30% { + opacity: 0.3; + } + 40% { + opacity: 1; + } + 100% { + opacity: 0.3; + } +} +.fw-rotate-90 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); + -webkit-transform: rotate(90deg); + -ms-transform: rotate(90deg); + transform: rotate(90deg); +} +.fw-rotate-180 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2); + -webkit-transform: rotate(180deg); + -ms-transform: rotate(180deg); + transform: rotate(180deg); +} +.fw-rotate-270 { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); + -webkit-transform: rotate(270deg); + -ms-transform: rotate(270deg); + transform: rotate(270deg); +} +.fw-flip-horizontal { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1); + -webkit-transform: scale(-1, 1); + -ms-transform: scale(-1, 1); + transform: scale(-1, 1); +} +.fw-flip-vertical { + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1); + -webkit-transform: scale(1, -1); + -ms-transform: scale(1, -1); + transform: scale(1, -1); +} +:root .fw-rotate-90, +:root .fw-rotate-180, +:root .fw-rotate-270, +:root .fw-flip-horizontal, +:root .fw-flip-vertical { + filter: none; +} +.fw-stack, +.fw-helper { + position: relative; + display: inline-block; + width: 2em; + height: 2em; + line-height: 1.85em; + vertical-align: middle; +} +.fw-stack-1x, +.fw-stack-2x, +.fw-helper:before, +.fw-helper:after { + position: absolute; + left: 0; + width: 100%; + text-align: center; +} +.fw-stack-1x, +.fw-helper:before { + line-height: inherit; +} +.fw-stack-2x, +.fw-helper:after { + font-size: 1.9em; +} +.fw-helper-slash:before { + font-size: 1.4em; +} +.fw-helper-circle:before, +.fw-helper-square:before { + z-index: 1; +} +.fw-helper-circle-outline:after { + content: "\e61f"; +} +.fw-helper-circle:after { + content: "\e61a"; +} +.fw-helper-square-outline:after { + content: "\e6b2"; +} +.fw-helper-square:after { + content: "\e6b1"; +} +.fw-helper-slash:after { + content: "\e6e1"; +} +.fw-stack > .fw-stack { + position: absolute; + font-size: 0.5em; +} +.fw-stack > .fw-stack.fw-move-top { + top: -0.2em; +} +.fw-stack > .fw-stack.fw-move-bottom { + bottom: -0.2em; +} +.fw-stack > .fw.stack.fw-move-left { + left: -0.5em; +} +.fw-stack > .fw-stack.fw-move-right { + right: -0.5em; +} +.fw-inverse:before, +.fw-helper-inverse:after, +.fw-number { + color: #ffffff; +} +.fw-shadow:before, +.fw-helper-shadow:after { + text-shadow: #ffffff 1px 1px 0; +} +.fw-stroke:before, +.fw-helper-stroke:after { + text-shadow: -2px -2px 0 #ffffff, + 2px -2px 0 #ffffff, + -2px 2px 0 #ffffff, + 2px 2px 0 #ffffff; +} +.fw-number { + line-height: 2em; + font-family: Arial, Helvetica, sans-serif; +} + + +/* ======================================================================== + * font icons + * ======================================================================== */ + +.fw-abort:before { + content:"\e72a"; +} + +.fw-action-invoke:before { + content:"\e6fe"; +} + +.fw-action:before { + content:"\e709"; +} + +.fw-activate:before { + content:"\e6cf"; +} + +.fw-add:before { + content:"\e615"; +} + +.fw-airplay:before { + content:"\e600"; +} + +.fw-alarm:before { + content:"\e6c2"; +} + +.fw-alert:before { + content:"\e6be"; +} + +.fw-analytics-extensions:before { + content:"\e6e2"; +} + +.fw-android-logcat:before { + content:"\e72c"; +} + +.fw-android-sense:before { + content:"\e72d"; +} + +.fw-android:before { + content:"\e606"; +} + +.fw-annotation:before { + content:"\e6e6"; +} + +.fw-api:before { + content:"\e601"; +} + +.fw-apn:before { + content:"\e602"; +} + +.fw-ios:before { + content:"\e604"; +} + +.fw-application:before { + content:"\e608"; +} + +.fw-arduino:before { + content:"\e6ab"; +} + +.fw-assign:before { + content:"\e6ff"; +} + +.fw-ballerina-service:before { + content:"\e729"; +} + +.fw-ballerina:before { + content:"\e728"; +} + +.fw-bar-chart:before { + content:"\e690"; +} + +.fw-battery:before { + content:"\e60a"; +} + +.fw-blank-document:before { + content:"\e60c"; +} + +.fw-block:before { + content:"\e695"; +} + +.fw-bookmark:before { + content:"\e60d"; +} + +.fw-bpel:before { + content:"\e60e"; +} + +.fw-bpmn:before { + content:"\e60f"; +} + +.fw-break:before { + content:"\e721"; +} + +.fw-bug:before { + content:"\e611"; +} + +.fw-build:before { + content:"\e6c1"; +} + +.fw-calendar:before { + content:"\e612"; +} + +.fw-camera:before { + content:"\e613"; +} + +.fw-cancel:before { + content:"\e618"; +} + +.fw-carbon:before { + content:"\e6c5"; +} + +.fw-chat:before { + content:"\e65b"; +} + +.fw-check:before { + content:"\e617"; +} + +.fw-checklist:before { + content:"\e619"; +} + +.fw-circle-outline:before { + content:"\e61f"; +} + +.fw-circle:before { + content:"\e61a"; +} + +.fw-clear:before { + content:"\e61b"; +} + +.fw-clock:before { + content:"\e61d"; +} + +.fw-cloud:before { + content:"\e61e"; +} + +.fw-code-view:before { + content:"\e70e"; +} + +.fw-code:before { + content:"\e6f1"; +} + +.fw-comment:before { + content:"\e710"; +} + +.fw-compare:before { + content:"\e610"; +} + +.fw-computer:before { + content:"\e653"; +} + +.fw-configarations:before { + content:"\e609"; +} + +.fw-connector:before { + content:"\e700"; +} + +.fw-console:before { + content:"\e71d"; +} + +.fw-constant:before { + content:"\e701"; +} + +.fw-contact:before { + content:"\e620"; +} + +.fw-contract:before { + content:"\e614"; +} + +.fw-copy:before { + content:"\e621"; +} + +.fw-cut:before { + content:"\e6f2"; +} + +.fw-dashboard:before { + content:"\e622"; +} + +.fw-database:before { + content:"\e623"; +} + +.fw-delete:before { + content:"\e624"; +} + +.fw-depend:before { + content:"\e6c6"; +} + +.fw-deploy:before { + content:"\e625"; +} + +.fw-deprecate:before { + content:"\e6cb"; +} + +.fw-design-view:before { + content:"\e70f"; +} + +.fw-devices:before { + content:"\e704"; +} + +.fw-dgm-action-invoke:before { + content:"\e712"; +} + +.fw-dgm-action:before { + content:"\e711"; +} + +.fw-dgm-connector:before { + content:"\e6f4"; +} + +.fw-dgm-constant-definition:before { + content:"\e6f5"; +} + +.fw-dgm-fork:before { + content:"\e6e7"; +} + +.fw-dgm-header:before { + content:"\e6e8"; +} + +.fw-dgm-if-else:before { + content:"\e6e9"; +} + +.fw-dgm-import:before { + content:"\e717"; +} + +.fw-dgm-lifeline:before { + content:"\e6ea"; +} + +.fw-dgm-logger:before { + content:"\e6eb"; +} + +.fw-dgm-resource:before { + content:"\e6f6"; +} + +.fw-dgm-service:before { + content:"\e6f7"; +} + +.fw-dgm-try-catch:before { + content:"\e6ec"; +} + +.fw-dgm-type-convertor:before { + content:"\e6f8"; +} + +.fw-dgm-type:before { + content:"\e6f9"; +} + +.fw-dgm-while:before { + content:"\e707"; +} + +.fw-dial-up:before { + content:"\e627"; +} + +.fw-disabled:before { + content:"\e6d1"; +} + +.fw-display:before { + content:"\e626"; +} + +.fw-docker:before { + content:"\e70c"; +} + +.fw-document:before { + content:"\e628"; +} + +.fw-down-arrow:before { + content:"\e689"; +} + +.fw-down:before { + content:"\e685"; +} + +.fw-download:before { + content:"\e65f"; +} + +.fw-dss:before { + content:"\e62a"; +} + +.fw-ebook:before { + content:"\e62b"; +} + +.fw-edit:before { + content:"\e62c"; +} + +.fw-ellipsis:before { + content:"\e629"; +} + +.fw-endpoint:before { + content:"\e62d"; +} + +.fw-enterprise:before { + content:"\e6b6"; +} + +.fw-error:before { + content:"\e630"; +} + +.fw-esb-connector:before { + content:"\e6e3"; +} + +.fw-expand:before { + content:"\e61c"; +} + +.fw-export:before { + content:"\e631"; +} + +.fw-extensions:before { + content:"\e6e4"; +} + +.fw-facebook:before { + content:"\e6d3"; +} + +.fw-factory-reset:before { + content:"\e632"; +} + +.fw-fan:before { + content:"\e678"; +} + +.fw-faq:before { + content:"\e62f"; +} + +.fw-file-browse:before { + content:"\e633"; +} + +.fw-filter:before { + content:"\e634"; +} + +.fw-folder-open:before { + content:"\e70b"; +} + +.fw-folder:before { + content:"\e62e"; +} + +.fw-fork-join:before { + content:"\e720"; +} + +.fw-format:before { + content:"\e6fa"; +} + +.fw-forum:before { + content:"\e636"; +} + +.fw-function-invoke:before { + content:"\e713"; +} + +.fw-function:before { + content:"\e6fb"; +} + +.fw-gadget:before { + content:"\e637"; +} + +.fw-geo-fence-inbound:before { + content:"\e72e"; +} + +.fw-geo-fence-outbound:before { + content:"\e72f"; +} + +.fw-github:before { + content:"\e6d4"; +} + +.fw-globe:before { + content:"\e697"; +} + +.fw-google-docs:before { + content:"\e6d6"; +} + +.fw-google-drive:before { + content:"\e6da"; +} + +.fw-google-plus:before { + content:"\e6d9"; +} + +.fw-google-sheets:before { + content:"\e6d7"; +} + +.fw-google-slides:before { + content:"\e6d8"; +} + +.fw-google:before { + content:"\e6d5"; +} + +.fw-grid:before { + content:"\e638"; +} + +.fw-grip:before { + content:"\e6b7"; +} + +.fw-group:before { + content:"\e6af"; +} + +.fw-hardware:before { + content:"\e6a9"; +} + +.fw-hdd:before { + content:"\e639"; +} + +.fw-heart:before { + content:"\e6c3"; +} + +.fw-hide:before { + content:"\e6d2"; +} + +.fw-home:before { + content:"\e63a"; +} + +.fw-hour-glass:before { + content:"\e63b"; +} + +.fw-html:before { + content:"\e69d"; +} + +.fw-http:before { + content:"\e705"; +} + +.fw-image:before { + content:"\e70a"; +} + +.fw-import:before { + content:"\e63c"; +} + +.fw-incoming-call:before { + content:"\e63d"; +} + +.fw-info:before { + content:"\e63e"; +} + +.fw-instagram:before { + content:"\e6db"; +} + +.fw-invitation:before { + content:"\e63f"; +} + +.fw-invoke:before { + content:"\e6ed"; +} + +.fw-is-connector:before { + content:"\e6e5"; +} + +.fw-iterate:before { + content:"\e71f"; +} + +.fw-jaggery:before { + content:"\e640"; +} + +.fw-java-spring:before { + content:"\e644"; +} + +.fw-java:before { + content:"\e641"; +} + +.fw-javaee:before { + content:"\e642"; +} + +.fw-javascript:before { + content:"\e643"; +} + +.fw-jaxrs:before { + content:"\e645"; +} + +.fw-jaxws:before { + content:"\e6c7"; +} + +.fw-jquery:before { + content:"\e646"; +} + +.fw-key:before { + content:"\e647"; +} + +.fw-laptop:before { + content:"\e648"; +} + +.fw-layout:before { + content:"\e6bf"; +} + +.fw-ldap:before { + content:"\e649"; +} + +.fw-left-arrow:before { + content:"\e68a"; +} + +.fw-left:before { + content:"\e686"; +} + +.fw-lifecycle:before { + content:"\e64a"; +} + +.fw-light:before { + content:"\e680"; +} + +.fw-linkedin:before { + content:"\e6dc"; +} + +.fw-list-sort:before { + content:"\e64d"; +} + +.fw-list:before { + content:"\e64c"; +} + +.fw-loader:before { + content:"\e6b4"; +} + +.fw-loader2:before { + content:"\e6ba"; +} + +.fw-loader3:before { + content:"\e6bb"; +} + +.fw-loader4:before { + content:"\e6bc"; +} + +.fw-loader5:before { + content:"\e6bd"; +} + +.fw-lock:before { + content:"\e64e"; +} + +.fw-logical:before { + content:"\e702"; +} + +.fw-mail:before { + content:"\e64f"; +} + +.fw-main-function:before { + content:"\e706"; +} + +.fw-map-location:before { + content:"\e650"; +} + +.fw-menu:before { + content:"\e651"; +} + +.fw-message:before { + content:"\e635"; +} + +.fw-micro-services:before { + content:"\e6ce"; +} + +.fw-minus:before, .fw-hyphen:before, .fw-dash:before { + content:"\e616"; +} + +.fw-mobile:before { + content:"\e652"; +} + +.fw-ms-document:before { + content:"\e654"; +} + +.fw-mute:before { + content:"\e655"; +} + +.fw-nodejs:before { + content:"\e656"; +} + +.fw-notification:before { + content:"\e60b"; +} + +.fw-organization:before { + content:"\e6ac"; +} + +.fw-own:before { + content:"\e6c8"; +} + +.fw-package:before { + content:"\e6fd"; +} + +.fw-pages:before { + content:"\e6c0"; +} + +.fw-paste:before { + content:"\e658"; +} + +.fw-pdf:before { + content:"\e659"; +} + +.fw-pending:before { + content:"\e727"; +} + +.fw-php:before { + content:"\e6c9"; +} + +.fw-pie-chart:before { + content:"\e65a"; +} + +.fw-pinterest:before { + content:"\e6dd"; +} + +.fw-policy:before { + content:"\e67d"; +} + +.fw-polygon:before { + content:"\e70d"; +} + +.fw-prototype:before { + content:"\e6cc"; +} + +.fw-proxy:before { + content:"\e699"; +} + +.fw-public:before { + content:"\e6ad"; +} + +.fw-publish:before { + content:"\e65c"; +} + +.fw-question:before { + content:"\e6b0"; +} + +.fw-raspberry:before { + content:"\e6aa"; +} + +.fw-redo:before { + content:"\e65d"; +} + +.fw-refresh:before { + content:"\e692"; +} + +.fw-register:before { + content:"\e65e"; +} + +.fw-rename:before { + content:"\e6fc"; +} + +.fw-reply:before { + content:"\e714"; +} + +.fw-resource:before { + content:"\e660"; +} + +.fw-rest-api:before { + content:"\e661"; +} + +.fw-rest-service:before { + content:"\e662"; +} + +.fw-resume:before { + content:"\e71e"; +} + +.fw-retire:before { + content:"\e6cd"; +} + +.fw-return:before { + content:"\e715"; +} + +.fw-retweet:before { + content:"\e6b9"; +} + +.fw-right-arrow:before { + content:"\e68b"; +} + +.fw-right:before { + content:"\e687"; +} + +.fw-ringing:before { + content:"\e694"; +} + +.fw-rules:before { + content:"\e664"; +} + +.fw-run:before { + content:"\e708"; +} + +.fw-save:before { + content:"\e665"; +} + +.fw-scep:before { + content:"\e666"; +} + +.fw-schema:before { + content:"\e667"; +} + +.fw-search:before { + content:"\e668"; +} + +.fw-security-policy:before { + content:"\e67e"; +} + +.fw-security:before { + content:"\e669"; +} + +.fw-send:before, .fw-paper-rocket:before { + content:"\e66a"; +} + +.fw-sequence:before { + content:"\e66b"; +} + +.fw-server:before { + content:"\e66c"; +} + +.fw-service-provider:before { + content:"\e66e"; +} + +.fw-service:before, .fw-cogwheels:before, .fw-gears:before, .fw-sprockets:before { + content:"\e66d"; +} + +.fw-settings:before, .fw-cogwheel:before, .fw-gear:before, .fw-sprocket:before { + content:"\e66f"; +} + +.fw-share:before { + content:"\e670"; +} + +.fw-shell:before { + content:"\e730"; +} + +.fw-shortcut:before { + content:"\e725"; +} + +.fw-sign-in:before { + content:"\e671"; +} + +.fw-sign-out:before { + content:"\e6b8"; +} + +.fw-skype:before { + content:"\e6de"; +} + +.fw-slash:before { + content:"\e6e1"; +} + +.fw-soap:before { + content:"\e672"; +} + +.fw-sort-down:before { + content:"\e663"; +} + +.fw-sort-up:before { + content:"\e64b"; +} + +.fw-sort:before { + content:"\e673"; +} + +.fw-speed-alert:before { + content:"\e731"; +} + +.fw-square-outline:before { + content:"\e6b2"; +} + +.fw-square:before { + content:"\e6b1"; +} + +.fw-star:before { + content:"\e674"; +} + +.fw-start:before { + content:"\e718"; +} + +.fw-statistics:before { + content:"\e675"; +} + +.fw-stepin:before { + content:"\e719"; +} + +.fw-stepout:before { + content:"\e71a"; +} + +.fw-stepover:before { + content:"\e71b"; +} + +.fw-stop:before { + content:"\e71c"; +} + +.fw-store:before, .fw-cart:before { + content:"\e676"; +} + +.fw-struct:before { + content:"\e716"; +} + +.fw-subscribe:before { + content:"\e677"; +} + +.fw-success:before { + content:"\e657"; +} + +.fw-swagger:before { + content:"\e679"; +} + +.fw-sync:before { + content:"\e6b3"; +} + +.fw-table:before { + content:"\e6c4"; +} + +.fw-tag:before { + content:"\e67a"; +} + +.fw-task:before { + content:"\e67b"; +} + +.fw-text:before { + content:"\e67c"; +} + +.fw-theme:before { + content:"\e726"; +} + +.fw-throttling-policy:before { + content:"\e67f"; +} + +.fw-throw:before { + content:"\e722"; +} + +.fw-tiles:before { + content:"\e681"; +} + +.fw-transaction:before { + content:"\e72b"; +} + +.fw-try-catch:before { + content:"\e703"; +} + +.fw-twitter:before { + content:"\e6df"; +} + +.fw-type-converter:before { + content:"\e6f3"; +} + +.fw-uncheck:before { + content:"\e682"; +} + +.fw-undo:before { + content:"\e683"; +} + +.fw-ungroup:before { + content:"\e6b5"; +} + +.fw-unmute:before { + content:"\e6ae"; +} + +.fw-up-arrow:before { + content:"\e688"; +} + +.fw-up:before { + content:"\e684"; +} + +.fw-upload:before { + content:"\e68c"; +} + +.fw-uri:before { + content:"\e68d"; +} + +.fw-usb-drive:before { + content:"\e68e"; +} + +.fw-use:before { + content:"\e6ca"; +} + +.fw-user:before { + content:"\e68f"; +} + +.fw-variable:before { + content:"\e6ee"; +} + +.fw-view:before { + content:"\e691"; +} + +.fw-vpn:before { + content:"\e603"; +} + +.fw-wadl:before { + content:"\e6a1"; +} + +.fw-war:before { + content:"\e69e"; +} + +.fw-warning:before { + content:"\e693"; +} + +.fw-web-app:before { + content:"\e696"; +} + +.fw-web-clip:before { + content:"\e698"; +} + +.fw-web-service:before { + content:"\e69a"; +} + +.fw-website:before { + content:"\e69b"; +} + +.fw-wifi:before { + content:"\e607"; +} + +.fw-windows:before { + content:"\e605"; +} + +.fw-worker-invoke:before { + content:"\e723"; +} + +.fw-worker-reply:before { + content:"\e724"; +} + +.fw-worker:before { + content:"\e6ef"; +} + +.fw-wsdl:before { + content:"\e6a0"; +} + +.fw-wso2-logo:before { + content:"\e6a7"; +} + +.fw-wso2:before { + content:"\e6a8"; +} + +.fw-xacml:before { + content:"\e69f"; +} + +.fw-xml:before { + content:"\e69c"; +} + +.fw-xq:before { + content:"\e6a2"; +} + +.fw-xsd:before { + content:"\e6a3"; +} + +.fw-xslt:before { + content:"\e6a4"; +} + +.fw-youtube:before { + content:"\e6e0"; +} + +.fw-zoom-in:before { + content:"\e6a5"; +} + +.fw-zoom-out:before { + content:"\e6a6"; +} + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/css/font-wso2.min.css b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/css/font-wso2.min.css index 6c3d742e3b..8d2a487bef 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/css/font-wso2.min.css +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/css/font-wso2.min.css @@ -1,15 +1,15 @@ -/*! -~ Copyright (c) WSO2 Inc. (http://wso2.com) All Rights Reserved. -~ -~ Licensed 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. -*/.fw-fw,.fw-li{text-align:center}@font-face{font-family:font-wso2;src:local("font-wso2"),url(../fonts/font-wso2.eot?6563fa91278f239ef8c827d90a165223);src:local("font-wso2"),url(../fonts/font-wso2.eot?#iefix) format("embedded-opentype"),url(../fonts/font-wso2.woff2?6563fa91278f239ef8c827d90a165223) format("woff2"),url(../fonts/font-wso2.woff?6563fa91278f239ef8c827d90a165223) format("woff"),url(../fonts/font-wso2.ttf?6563fa91278f239ef8c827d90a165223) format("truetype"),url(../fonts/font-wso2.svg?6563fa91278f239ef8c827d90a165223#font-wso2) format("svg");font-weight:400;font-style:normal}.fw,[class*=" fw-"],[class^=fw-]{font:normal normal normal 14px/1 font-wso2;display:inline-block;font-weight:400;font-style:normal;font-size:inherit;font-variant:normal;speak:none;text-decoration:inherit;text-transform:none;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fw-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fw-2x{font-size:2em}.fw-3x{font-size:3em}.fw-4x{font-size:4em}.fw-5x{font-size:5em}.fw-fw{width:1.28571429em}.fw-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fw-ul>li{position:relative}.fw-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em}.fw-li.fw-lg{left:-1.85714286em}.fw-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fw-background{background:#888;border-radius:.3em;padding:.4em .5em .45em}.fw-pull-left{float:left}.fw-pull-right{float:right}.fw.fw-pull-left{margin-right:.3em}.fw.fw-pull-right{margin-left:.3em}.fw-spin{-webkit-animation:fw-spin 2s infinite linear;animation:fw-spin 2s infinite linear}@-webkit-keyframes fw-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fw-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fw-pulse{-webkit-animation:fw-pulse 2s ease-out infinite;animation:fw-pulse 2s ease-out infinite}@-webkit-keyframes fw-pulse{0%,100%,30%{opacity:.3}40%{opacity:1}}@keyframes fw-pulse{0%,100%,30%{opacity:.3}40%{opacity:1}}.fw-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fw-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fw-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fw-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.fw-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scale(1,-1)}:root .fw-flip-horizontal,:root .fw-flip-vertical,:root .fw-rotate-180,:root .fw-rotate-270,:root .fw-rotate-90{filter:none}.fw-helper,.fw-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:1.85em;vertical-align:middle}.fw-helper:after,.fw-helper:before,.fw-stack-1x,.fw-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fw-helper:before,.fw-stack-1x{line-height:inherit}.fw-helper:after,.fw-stack-2x{font-size:1.9em}.fw-helper-slash:before{font-size:1.4em}.fw-helper-circle:before,.fw-helper-square:before{z-index:1}.fw-helper-circle-outline:after{content:"\e61f"}.fw-helper-circle:after{content:"\e61a"}.fw-helper-square-outline:after{content:"\e6b2"}.fw-helper-square:after{content:"\e6b1"}.fw-helper-slash:after{content:"\e6e1"}.fw-stack>.fw-stack{position:absolute;font-size:.5em}.fw-stack>.fw-stack.fw-move-top{top:-.2em}.fw-stack>.fw-stack.fw-move-bottom{bottom:-.2em}.fw-stack>.fw.stack.fw-move-left{left:-.5em}.fw-stack>.fw-stack.fw-move-right{right:-.5em}.fw-helper-inverse:after,.fw-inverse:before,.fw-number{color:#fff}.fw-helper-shadow:after,.fw-shadow:before{text-shadow:#fff 1px 1px 0}.fw-helper-stroke:after,.fw-stroke:before{text-shadow:-2px -2px 0 #fff,2px -2px 0 #fff,-2px 2px 0 #fff,2px 2px 0 #fff}.fw-number{line-height:2em;font-family:Arial,Helvetica,sans-serif}.fw-abort:before{content:"\e72a"}.fw-action-invoke:before{content:"\e6fe"}.fw-action:before{content:"\e709"}.fw-activate:before{content:"\e6cf"}.fw-add:before{content:"\e615"}.fw-airplay:before{content:"\e600"}.fw-alarm:before{content:"\e6c2"}.fw-alert:before{content:"\e6be"}.fw-analytics-extensions:before{content:"\e6e2"}.fw-android-logcat:before{content:"\e72c"}.fw-android-sense:before{content:"\e72d"}.fw-android:before{content:"\e606"}.fw-annotation:before{content:"\e6e6"}.fw-api:before{content:"\e601"}.fw-apn:before{content:"\e602"}.fw-apple:before{content:"\e604"}.fw-application:before{content:"\e608"}.fw-arduino:before{content:"\e6ab"}.fw-assign:before{content:"\e6ff"}.fw-ballerina-service:before{content:"\e729"}.fw-ballerina:before{content:"\e728"}.fw-bar-chart:before{content:"\e690"}.fw-battery:before{content:"\e60a"}.fw-blank-document:before{content:"\e60c"}.fw-block:before{content:"\e695"}.fw-bookmark:before{content:"\e60d"}.fw-bpel:before{content:"\e60e"}.fw-bpmn:before{content:"\e60f"}.fw-break:before{content:"\e721"}.fw-bug:before{content:"\e611"}.fw-build:before{content:"\e6c1"}.fw-calendar:before{content:"\e612"}.fw-camera:before{content:"\e613"}.fw-cancel:before{content:"\e618"}.fw-carbon:before{content:"\e6c5"}.fw-chat:before{content:"\e65b"}.fw-check:before{content:"\e617"}.fw-checklist:before{content:"\e619"}.fw-circle-outline:before{content:"\e61f"}.fw-circle:before{content:"\e61a"}.fw-clear:before{content:"\e61b"}.fw-clock:before{content:"\e61d"}.fw-cloud:before{content:"\e61e"}.fw-code-view:before{content:"\e70e"}.fw-code:before{content:"\e6f1"}.fw-comment:before{content:"\e710"}.fw-compare:before{content:"\e610"}.fw-computer:before{content:"\e653"}.fw-configarations:before{content:"\e609"}.fw-connector:before{content:"\e700"}.fw-console:before{content:"\e71d"}.fw-constant:before{content:"\e701"}.fw-contact:before{content:"\e620"}.fw-contract:before{content:"\e614"}.fw-copy:before{content:"\e621"}.fw-cut:before{content:"\e6f2"}.fw-dashboard:before{content:"\e622"}.fw-database:before{content:"\e623"}.fw-delete:before{content:"\e624"}.fw-depend:before{content:"\e6c6"}.fw-deploy:before{content:"\e625"}.fw-deprecate:before{content:"\e6cb"}.fw-design-view:before{content:"\e70f"}.fw-devices:before{content:"\e704"}.fw-dgm-action-invoke:before{content:"\e712"}.fw-dgm-action:before{content:"\e711"}.fw-dgm-connector:before{content:"\e6f4"}.fw-dgm-constant-definition:before{content:"\e6f5"}.fw-dgm-fork:before{content:"\e6e7"}.fw-dgm-header:before{content:"\e6e8"}.fw-dgm-if-else:before{content:"\e6e9"}.fw-dgm-import:before{content:"\e717"}.fw-dgm-lifeline:before{content:"\e6ea"}.fw-dgm-logger:before{content:"\e6eb"}.fw-dgm-resource:before{content:"\e6f6"}.fw-dgm-service:before{content:"\e6f7"}.fw-dgm-try-catch:before{content:"\e6ec"}.fw-dgm-type-convertor:before{content:"\e6f8"}.fw-dgm-type:before{content:"\e6f9"}.fw-dgm-while:before{content:"\e707"}.fw-dial-up:before{content:"\e627"}.fw-disabled:before{content:"\e6d1"}.fw-display:before{content:"\e626"}.fw-docker:before{content:"\e70c"}.fw-document:before{content:"\e628"}.fw-down-arrow:before{content:"\e689"}.fw-down:before{content:"\e685"}.fw-download:before{content:"\e65f"}.fw-dss:before{content:"\e62a"}.fw-ebook:before{content:"\e62b"}.fw-edit:before{content:"\e62c"}.fw-ellipsis:before{content:"\e629"}.fw-endpoint:before{content:"\e62d"}.fw-enterprise:before{content:"\e6b6"}.fw-error:before{content:"\e630"}.fw-esb-connector:before{content:"\e6e3"}.fw-expand:before{content:"\e61c"}.fw-export:before{content:"\e631"}.fw-extensions:before{content:"\e6e4"}.fw-facebook:before{content:"\e6d3"}.fw-factory-reset:before{content:"\e632"}.fw-fan:before{content:"\e678"}.fw-faq:before{content:"\e62f"}.fw-file-browse:before{content:"\e633"}.fw-filter:before{content:"\e634"}.fw-folder-open:before{content:"\e70b"}.fw-folder:before{content:"\e62e"}.fw-fork-join:before{content:"\e720"}.fw-format:before{content:"\e6fa"}.fw-forum:before{content:"\e636"}.fw-function-invoke:before{content:"\e713"}.fw-function:before{content:"\e6fb"}.fw-gadget:before{content:"\e637"}.fw-geo-fence-inbound:before{content:"\e72e"}.fw-geo-fence-outbound:before{content:"\e72f"}.fw-github:before{content:"\e6d4"}.fw-globe:before{content:"\e697"}.fw-google-docs:before{content:"\e6d6"}.fw-google-drive:before{content:"\e6da"}.fw-google-plus:before{content:"\e6d9"}.fw-google-sheets:before{content:"\e6d7"}.fw-google-slides:before{content:"\e6d8"}.fw-google:before{content:"\e6d5"}.fw-grid:before{content:"\e638"}.fw-grip:before{content:"\e6b7"}.fw-group:before{content:"\e6af"}.fw-hardware:before{content:"\e6a9"}.fw-hdd:before{content:"\e639"}.fw-heart:before{content:"\e6c3"}.fw-hide:before{content:"\e6d2"}.fw-home:before{content:"\e63a"}.fw-hour-glass:before{content:"\e63b"}.fw-html:before{content:"\e69d"}.fw-http:before{content:"\e705"}.fw-image:before{content:"\e70a"}.fw-import:before{content:"\e63c"}.fw-incoming-call:before{content:"\e63d"}.fw-info:before{content:"\e63e"}.fw-instagram:before{content:"\e6db"}.fw-invitation:before{content:"\e63f"}.fw-invoke:before{content:"\e6ed"}.fw-is-connector:before{content:"\e6e5"}.fw-iterate:before{content:"\e71f"}.fw-jaggery:before{content:"\e640"}.fw-java-spring:before{content:"\e644"}.fw-java:before{content:"\e641"}.fw-javaee:before{content:"\e642"}.fw-javascript:before{content:"\e643"}.fw-jaxrs:before{content:"\e645"}.fw-jaxws:before{content:"\e6c7"}.fw-jquery:before{content:"\e646"}.fw-key:before{content:"\e647"}.fw-laptop:before{content:"\e648"}.fw-layout:before{content:"\e6bf"}.fw-ldap:before{content:"\e649"}.fw-left-arrow:before{content:"\e68a"}.fw-left:before{content:"\e686"}.fw-lifecycle:before{content:"\e64a"}.fw-light:before{content:"\e680"}.fw-linkedin:before{content:"\e6dc"}.fw-list-sort:before{content:"\e64d"}.fw-list:before{content:"\e64c"}.fw-loader:before{content:"\e6b4"}.fw-loader2:before{content:"\e6ba"}.fw-loader3:before{content:"\e6bb"}.fw-loader4:before{content:"\e6bc"}.fw-loader5:before{content:"\e6bd"}.fw-lock:before{content:"\e64e"}.fw-logical:before{content:"\e702"}.fw-mail:before{content:"\e64f"}.fw-main-function:before{content:"\e706"}.fw-map-location:before{content:"\e650"}.fw-menu:before{content:"\e651"}.fw-message:before{content:"\e635"}.fw-micro-services:before{content:"\e6ce"}.fw-dash:before,.fw-hyphen:before,.fw-minus:before{content:"\e616"}.fw-mobile:before{content:"\e652"}.fw-ms-document:before{content:"\e654"}.fw-mute:before{content:"\e655"}.fw-nodejs:before{content:"\e656"}.fw-notification:before{content:"\e60b"}.fw-organization:before{content:"\e6ac"}.fw-own:before{content:"\e6c8"}.fw-package:before{content:"\e6fd"}.fw-pages:before{content:"\e6c0"}.fw-paste:before{content:"\e658"}.fw-pdf:before{content:"\e659"}.fw-pending:before{content:"\e727"}.fw-php:before{content:"\e6c9"}.fw-pie-chart:before{content:"\e65a"}.fw-pinterest:before{content:"\e6dd"}.fw-policy:before{content:"\e67d"}.fw-polygon:before{content:"\e70d"}.fw-prototype:before{content:"\e6cc"}.fw-proxy:before{content:"\e699"}.fw-public:before{content:"\e6ad"}.fw-publish:before{content:"\e65c"}.fw-question:before{content:"\e6b0"}.fw-raspberry:before{content:"\e6aa"}.fw-redo:before{content:"\e65d"}.fw-refresh:before{content:"\e692"}.fw-register:before{content:"\e65e"}.fw-rename:before{content:"\e6fc"}.fw-reply:before{content:"\e714"}.fw-resource:before{content:"\e660"}.fw-rest-api:before{content:"\e661"}.fw-rest-service:before{content:"\e662"}.fw-resume:before{content:"\e71e"}.fw-retire:before{content:"\e6cd"}.fw-return:before{content:"\e715"}.fw-retweet:before{content:"\e6b9"}.fw-right-arrow:before{content:"\e68b"}.fw-right:before{content:"\e687"}.fw-ringing:before{content:"\e694"}.fw-rules:before{content:"\e664"}.fw-run:before{content:"\e708"}.fw-save:before{content:"\e665"}.fw-scep:before{content:"\e666"}.fw-schema:before{content:"\e667"}.fw-search:before{content:"\e668"}.fw-security-policy:before{content:"\e67e"}.fw-security:before{content:"\e669"}.fw-paper-rocket:before,.fw-send:before{content:"\e66a"}.fw-sequence:before{content:"\e66b"}.fw-server:before{content:"\e66c"}.fw-service-provider:before{content:"\e66e"}.fw-cogwheels:before,.fw-gears:before,.fw-service:before,.fw-sprockets:before{content:"\e66d"}.fw-cogwheel:before,.fw-gear:before,.fw-settings:before,.fw-sprocket:before{content:"\e66f"}.fw-share:before{content:"\e670"}.fw-shell:before{content:"\e730"}.fw-shortcut:before{content:"\e725"}.fw-sign-in:before{content:"\e671"}.fw-sign-out:before{content:"\e6b8"}.fw-skype:before{content:"\e6de"}.fw-slash:before{content:"\e6e1"}.fw-soap:before{content:"\e672"}.fw-sort-down:before{content:"\e663"}.fw-sort-up:before{content:"\e64b"}.fw-sort:before{content:"\e673"}.fw-speed-alert:before{content:"\e731"}.fw-square-outline:before{content:"\e6b2"}.fw-square:before{content:"\e6b1"}.fw-star:before{content:"\e674"}.fw-start:before{content:"\e718"}.fw-statistics:before{content:"\e675"}.fw-stepin:before{content:"\e719"}.fw-stepout:before{content:"\e71a"}.fw-stepover:before{content:"\e71b"}.fw-stop:before{content:"\e71c"}.fw-cart:before,.fw-store:before{content:"\e676"}.fw-struct:before{content:"\e716"}.fw-subscribe:before{content:"\e677"}.fw-success:before{content:"\e657"}.fw-swagger:before{content:"\e679"}.fw-sync:before{content:"\e6b3"}.fw-table:before{content:"\e6c4"}.fw-tag:before{content:"\e67a"}.fw-task:before{content:"\e67b"}.fw-text:before{content:"\e67c"}.fw-theme:before{content:"\e726"}.fw-throttling-policy:before{content:"\e67f"}.fw-throw:before{content:"\e722"}.fw-tiles:before{content:"\e681"}.fw-transaction:before{content:"\e72b"}.fw-try-catch:before{content:"\e703"}.fw-twitter:before{content:"\e6df"}.fw-type-converter:before{content:"\e6f3"}.fw-uncheck:before{content:"\e682"}.fw-undo:before{content:"\e683"}.fw-ungroup:before{content:"\e6b5"}.fw-unmute:before{content:"\e6ae"}.fw-up-arrow:before{content:"\e688"}.fw-up:before{content:"\e684"}.fw-upload:before{content:"\e68c"}.fw-uri:before{content:"\e68d"}.fw-usb-drive:before{content:"\e68e"}.fw-use:before{content:"\e6ca"}.fw-user:before{content:"\e68f"}.fw-variable:before{content:"\e6ee"}.fw-view:before{content:"\e691"}.fw-vpn:before{content:"\e603"}.fw-wadl:before{content:"\e6a1"}.fw-war:before{content:"\e69e"}.fw-warning:before{content:"\e693"}.fw-web-app:before{content:"\e696"}.fw-web-clip:before{content:"\e698"}.fw-web-service:before{content:"\e69a"}.fw-website:before{content:"\e69b"}.fw-wifi:before{content:"\e607"}.fw-windows:before{content:"\e605"}.fw-worker-invoke:before{content:"\e723"}.fw-worker-reply:before{content:"\e724"}.fw-worker:before{content:"\e6ef"}.fw-wsdl:before{content:"\e6a0"}.fw-wso2-logo:before{content:"\e6a7"}.fw-wso2:before{content:"\e6a8"}.fw-xacml:before{content:"\e69f"}.fw-xml:before{content:"\e69c"}.fw-xq:before{content:"\e6a2"}.fw-xsd:before{content:"\e6a3"}.fw-xslt:before{content:"\e6a4"}.fw-youtube:before{content:"\e6e0"}.fw-zoom-in:before{content:"\e6a5"}.fw-zoom-out:before{content:"\e6a6"} \ No newline at end of file +/*! +~ Copyright (c) WSO2 Inc. (http://wso2.com) All Rights Reserved. +~ +~ Licensed 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. +*/.fw-fw,.fw-li{text-align:center}@font-face{font-family:font-wso2;src:local("font-wso2"),url(../fonts/font-wso2.eot?6563fa91278f239ef8c827d90a165223);src:local("font-wso2"),url(../fonts/font-wso2.eot?#iefix) format("embedded-opentype"),url(../fonts/font-wso2.woff2?6563fa91278f239ef8c827d90a165223) format("woff2"),url(../fonts/font-wso2.woff?6563fa91278f239ef8c827d90a165223) format("woff"),url(../fonts/font-wso2.ttf?6563fa91278f239ef8c827d90a165223) format("truetype"),url(../fonts/font-wso2.svg?6563fa91278f239ef8c827d90a165223#font-wso2) format("svg");font-weight:400;font-style:normal}.fw,[class*=" fw-"],[class^=fw-]{font:normal normal normal 14px/1 font-wso2;display:inline-block;font-weight:400;font-style:normal;font-size:inherit;font-variant:normal;speak:none;text-decoration:inherit;text-transform:none;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fw-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fw-2x{font-size:2em}.fw-3x{font-size:3em}.fw-4x{font-size:4em}.fw-5x{font-size:5em}.fw-fw{width:1.28571429em}.fw-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fw-ul>li{position:relative}.fw-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em}.fw-li.fw-lg{left:-1.85714286em}.fw-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fw-background{background:#888;border-radius:.3em;padding:.4em .5em .45em}.fw-pull-left{float:left}.fw-pull-right{float:right}.fw.fw-pull-left{margin-right:.3em}.fw.fw-pull-right{margin-left:.3em}.fw-spin{-webkit-animation:fw-spin 2s infinite linear;animation:fw-spin 2s infinite linear}@-webkit-keyframes fw-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fw-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fw-pulse{-webkit-animation:fw-pulse 2s ease-out infinite;animation:fw-pulse 2s ease-out infinite}@-webkit-keyframes fw-pulse{0%,100%,30%{opacity:.3}40%{opacity:1}}@keyframes fw-pulse{0%,100%,30%{opacity:.3}40%{opacity:1}}.fw-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fw-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fw-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fw-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.fw-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scale(1,-1)}:root .fw-flip-horizontal,:root .fw-flip-vertical,:root .fw-rotate-180,:root .fw-rotate-270,:root .fw-rotate-90{filter:none}.fw-helper,.fw-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:1.85em;vertical-align:middle}.fw-helper:after,.fw-helper:before,.fw-stack-1x,.fw-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fw-helper:before,.fw-stack-1x{line-height:inherit}.fw-helper:after,.fw-stack-2x{font-size:1.9em}.fw-helper-slash:before{font-size:1.4em}.fw-helper-circle:before,.fw-helper-square:before{z-index:1}.fw-helper-circle-outline:after{content:"\e61f"}.fw-helper-circle:after{content:"\e61a"}.fw-helper-square-outline:after{content:"\e6b2"}.fw-helper-square:after{content:"\e6b1"}.fw-helper-slash:after{content:"\e6e1"}.fw-stack>.fw-stack{position:absolute;font-size:.5em}.fw-stack>.fw-stack.fw-move-top{top:-.2em}.fw-stack>.fw-stack.fw-move-bottom{bottom:-.2em}.fw-stack>.fw.stack.fw-move-left{left:-.5em}.fw-stack>.fw-stack.fw-move-right{right:-.5em}.fw-helper-inverse:after,.fw-inverse:before,.fw-number{color:#fff}.fw-helper-shadow:after,.fw-shadow:before{text-shadow:#fff 1px 1px 0}.fw-helper-stroke:after,.fw-stroke:before{text-shadow:-2px -2px 0 #fff,2px -2px 0 #fff,-2px 2px 0 #fff,2px 2px 0 #fff}.fw-number{line-height:2em;font-family:Arial,Helvetica,sans-serif}.fw-abort:before{content:"\e72a"}.fw-action-invoke:before{content:"\e6fe"}.fw-action:before{content:"\e709"}.fw-activate:before{content:"\e6cf"}.fw-add:before{content:"\e615"}.fw-airplay:before{content:"\e600"}.fw-alarm:before{content:"\e6c2"}.fw-alert:before{content:"\e6be"}.fw-analytics-extensions:before{content:"\e6e2"}.fw-android-logcat:before{content:"\e72c"}.fw-android-sense:before{content:"\e72d"}.fw-android:before{content:"\e606"}.fw-annotation:before{content:"\e6e6"}.fw-api:before{content:"\e601"}.fw-apn:before{content:"\e602"}.fw-ios:before{content:"\e604"}.fw-application:before{content:"\e608"}.fw-arduino:before{content:"\e6ab"}.fw-assign:before{content:"\e6ff"}.fw-ballerina-service:before{content:"\e729"}.fw-ballerina:before{content:"\e728"}.fw-bar-chart:before{content:"\e690"}.fw-battery:before{content:"\e60a"}.fw-blank-document:before{content:"\e60c"}.fw-block:before{content:"\e695"}.fw-bookmark:before{content:"\e60d"}.fw-bpel:before{content:"\e60e"}.fw-bpmn:before{content:"\e60f"}.fw-break:before{content:"\e721"}.fw-bug:before{content:"\e611"}.fw-build:before{content:"\e6c1"}.fw-calendar:before{content:"\e612"}.fw-camera:before{content:"\e613"}.fw-cancel:before{content:"\e618"}.fw-carbon:before{content:"\e6c5"}.fw-chat:before{content:"\e65b"}.fw-check:before{content:"\e617"}.fw-checklist:before{content:"\e619"}.fw-circle-outline:before{content:"\e61f"}.fw-circle:before{content:"\e61a"}.fw-clear:before{content:"\e61b"}.fw-clock:before{content:"\e61d"}.fw-cloud:before{content:"\e61e"}.fw-code-view:before{content:"\e70e"}.fw-code:before{content:"\e6f1"}.fw-comment:before{content:"\e710"}.fw-compare:before{content:"\e610"}.fw-computer:before{content:"\e653"}.fw-configarations:before{content:"\e609"}.fw-connector:before{content:"\e700"}.fw-console:before{content:"\e71d"}.fw-constant:before{content:"\e701"}.fw-contact:before{content:"\e620"}.fw-contract:before{content:"\e614"}.fw-copy:before{content:"\e621"}.fw-cut:before{content:"\e6f2"}.fw-dashboard:before{content:"\e622"}.fw-database:before{content:"\e623"}.fw-delete:before{content:"\e624"}.fw-depend:before{content:"\e6c6"}.fw-deploy:before{content:"\e625"}.fw-deprecate:before{content:"\e6cb"}.fw-design-view:before{content:"\e70f"}.fw-devices:before{content:"\e704"}.fw-dgm-action-invoke:before{content:"\e712"}.fw-dgm-action:before{content:"\e711"}.fw-dgm-connector:before{content:"\e6f4"}.fw-dgm-constant-definition:before{content:"\e6f5"}.fw-dgm-fork:before{content:"\e6e7"}.fw-dgm-header:before{content:"\e6e8"}.fw-dgm-if-else:before{content:"\e6e9"}.fw-dgm-import:before{content:"\e717"}.fw-dgm-lifeline:before{content:"\e6ea"}.fw-dgm-logger:before{content:"\e6eb"}.fw-dgm-resource:before{content:"\e6f6"}.fw-dgm-service:before{content:"\e6f7"}.fw-dgm-try-catch:before{content:"\e6ec"}.fw-dgm-type-convertor:before{content:"\e6f8"}.fw-dgm-type:before{content:"\e6f9"}.fw-dgm-while:before{content:"\e707"}.fw-dial-up:before{content:"\e627"}.fw-disabled:before{content:"\e6d1"}.fw-display:before{content:"\e626"}.fw-docker:before{content:"\e70c"}.fw-document:before{content:"\e628"}.fw-down-arrow:before{content:"\e689"}.fw-down:before{content:"\e685"}.fw-download:before{content:"\e65f"}.fw-dss:before{content:"\e62a"}.fw-ebook:before{content:"\e62b"}.fw-edit:before{content:"\e62c"}.fw-ellipsis:before{content:"\e629"}.fw-endpoint:before{content:"\e62d"}.fw-enterprise:before{content:"\e6b6"}.fw-error:before{content:"\e630"}.fw-esb-connector:before{content:"\e6e3"}.fw-expand:before{content:"\e61c"}.fw-export:before{content:"\e631"}.fw-extensions:before{content:"\e6e4"}.fw-facebook:before{content:"\e6d3"}.fw-factory-reset:before{content:"\e632"}.fw-fan:before{content:"\e678"}.fw-faq:before{content:"\e62f"}.fw-file-browse:before{content:"\e633"}.fw-filter:before{content:"\e634"}.fw-folder-open:before{content:"\e70b"}.fw-folder:before{content:"\e62e"}.fw-fork-join:before{content:"\e720"}.fw-format:before{content:"\e6fa"}.fw-forum:before{content:"\e636"}.fw-function-invoke:before{content:"\e713"}.fw-function:before{content:"\e6fb"}.fw-gadget:before{content:"\e637"}.fw-geo-fence-inbound:before{content:"\e72e"}.fw-geo-fence-outbound:before{content:"\e72f"}.fw-github:before{content:"\e6d4"}.fw-globe:before{content:"\e697"}.fw-google-docs:before{content:"\e6d6"}.fw-google-drive:before{content:"\e6da"}.fw-google-plus:before{content:"\e6d9"}.fw-google-sheets:before{content:"\e6d7"}.fw-google-slides:before{content:"\e6d8"}.fw-google:before{content:"\e6d5"}.fw-grid:before{content:"\e638"}.fw-grip:before{content:"\e6b7"}.fw-group:before{content:"\e6af"}.fw-hardware:before{content:"\e6a9"}.fw-hdd:before{content:"\e639"}.fw-heart:before{content:"\e6c3"}.fw-hide:before{content:"\e6d2"}.fw-home:before{content:"\e63a"}.fw-hour-glass:before{content:"\e63b"}.fw-html:before{content:"\e69d"}.fw-http:before{content:"\e705"}.fw-image:before{content:"\e70a"}.fw-import:before{content:"\e63c"}.fw-incoming-call:before{content:"\e63d"}.fw-info:before{content:"\e63e"}.fw-instagram:before{content:"\e6db"}.fw-invitation:before{content:"\e63f"}.fw-invoke:before{content:"\e6ed"}.fw-is-connector:before{content:"\e6e5"}.fw-iterate:before{content:"\e71f"}.fw-jaggery:before{content:"\e640"}.fw-java-spring:before{content:"\e644"}.fw-java:before{content:"\e641"}.fw-javaee:before{content:"\e642"}.fw-javascript:before{content:"\e643"}.fw-jaxrs:before{content:"\e645"}.fw-jaxws:before{content:"\e6c7"}.fw-jquery:before{content:"\e646"}.fw-key:before{content:"\e647"}.fw-laptop:before{content:"\e648"}.fw-layout:before{content:"\e6bf"}.fw-ldap:before{content:"\e649"}.fw-left-arrow:before{content:"\e68a"}.fw-left:before{content:"\e686"}.fw-lifecycle:before{content:"\e64a"}.fw-light:before{content:"\e680"}.fw-linkedin:before{content:"\e6dc"}.fw-list-sort:before{content:"\e64d"}.fw-list:before{content:"\e64c"}.fw-loader:before{content:"\e6b4"}.fw-loader2:before{content:"\e6ba"}.fw-loader3:before{content:"\e6bb"}.fw-loader4:before{content:"\e6bc"}.fw-loader5:before{content:"\e6bd"}.fw-lock:before{content:"\e64e"}.fw-logical:before{content:"\e702"}.fw-mail:before{content:"\e64f"}.fw-main-function:before{content:"\e706"}.fw-map-location:before{content:"\e650"}.fw-menu:before{content:"\e651"}.fw-message:before{content:"\e635"}.fw-micro-services:before{content:"\e6ce"}.fw-dash:before,.fw-hyphen:before,.fw-minus:before{content:"\e616"}.fw-mobile:before{content:"\e652"}.fw-ms-document:before{content:"\e654"}.fw-mute:before{content:"\e655"}.fw-nodejs:before{content:"\e656"}.fw-notification:before{content:"\e60b"}.fw-organization:before{content:"\e6ac"}.fw-own:before{content:"\e6c8"}.fw-package:before{content:"\e6fd"}.fw-pages:before{content:"\e6c0"}.fw-paste:before{content:"\e658"}.fw-pdf:before{content:"\e659"}.fw-pending:before{content:"\e727"}.fw-php:before{content:"\e6c9"}.fw-pie-chart:before{content:"\e65a"}.fw-pinterest:before{content:"\e6dd"}.fw-policy:before{content:"\e67d"}.fw-polygon:before{content:"\e70d"}.fw-prototype:before{content:"\e6cc"}.fw-proxy:before{content:"\e699"}.fw-public:before{content:"\e6ad"}.fw-publish:before{content:"\e65c"}.fw-question:before{content:"\e6b0"}.fw-raspberry:before{content:"\e6aa"}.fw-redo:before{content:"\e65d"}.fw-refresh:before{content:"\e692"}.fw-register:before{content:"\e65e"}.fw-rename:before{content:"\e6fc"}.fw-reply:before{content:"\e714"}.fw-resource:before{content:"\e660"}.fw-rest-api:before{content:"\e661"}.fw-rest-service:before{content:"\e662"}.fw-resume:before{content:"\e71e"}.fw-retire:before{content:"\e6cd"}.fw-return:before{content:"\e715"}.fw-retweet:before{content:"\e6b9"}.fw-right-arrow:before{content:"\e68b"}.fw-right:before{content:"\e687"}.fw-ringing:before{content:"\e694"}.fw-rules:before{content:"\e664"}.fw-run:before{content:"\e708"}.fw-save:before{content:"\e665"}.fw-scep:before{content:"\e666"}.fw-schema:before{content:"\e667"}.fw-search:before{content:"\e668"}.fw-security-policy:before{content:"\e67e"}.fw-security:before{content:"\e669"}.fw-paper-rocket:before,.fw-send:before{content:"\e66a"}.fw-sequence:before{content:"\e66b"}.fw-server:before{content:"\e66c"}.fw-service-provider:before{content:"\e66e"}.fw-cogwheels:before,.fw-gears:before,.fw-service:before,.fw-sprockets:before{content:"\e66d"}.fw-cogwheel:before,.fw-gear:before,.fw-settings:before,.fw-sprocket:before{content:"\e66f"}.fw-share:before{content:"\e670"}.fw-shell:before{content:"\e730"}.fw-shortcut:before{content:"\e725"}.fw-sign-in:before{content:"\e671"}.fw-sign-out:before{content:"\e6b8"}.fw-skype:before{content:"\e6de"}.fw-slash:before{content:"\e6e1"}.fw-soap:before{content:"\e672"}.fw-sort-down:before{content:"\e663"}.fw-sort-up:before{content:"\e64b"}.fw-sort:before{content:"\e673"}.fw-speed-alert:before{content:"\e731"}.fw-square-outline:before{content:"\e6b2"}.fw-square:before{content:"\e6b1"}.fw-star:before{content:"\e674"}.fw-start:before{content:"\e718"}.fw-statistics:before{content:"\e675"}.fw-stepin:before{content:"\e719"}.fw-stepout:before{content:"\e71a"}.fw-stepover:before{content:"\e71b"}.fw-stop:before{content:"\e71c"}.fw-cart:before,.fw-store:before{content:"\e676"}.fw-struct:before{content:"\e716"}.fw-subscribe:before{content:"\e677"}.fw-success:before{content:"\e657"}.fw-swagger:before{content:"\e679"}.fw-sync:before{content:"\e6b3"}.fw-table:before{content:"\e6c4"}.fw-tag:before{content:"\e67a"}.fw-task:before{content:"\e67b"}.fw-text:before{content:"\e67c"}.fw-theme:before{content:"\e726"}.fw-throttling-policy:before{content:"\e67f"}.fw-throw:before{content:"\e722"}.fw-tiles:before{content:"\e681"}.fw-transaction:before{content:"\e72b"}.fw-try-catch:before{content:"\e703"}.fw-twitter:before{content:"\e6df"}.fw-type-converter:before{content:"\e6f3"}.fw-uncheck:before{content:"\e682"}.fw-undo:before{content:"\e683"}.fw-ungroup:before{content:"\e6b5"}.fw-unmute:before{content:"\e6ae"}.fw-up-arrow:before{content:"\e688"}.fw-up:before{content:"\e684"}.fw-upload:before{content:"\e68c"}.fw-uri:before{content:"\e68d"}.fw-usb-drive:before{content:"\e68e"}.fw-use:before{content:"\e6ca"}.fw-user:before{content:"\e68f"}.fw-variable:before{content:"\e6ee"}.fw-view:before{content:"\e691"}.fw-vpn:before{content:"\e603"}.fw-wadl:before{content:"\e6a1"}.fw-war:before{content:"\e69e"}.fw-warning:before{content:"\e693"}.fw-web-app:before{content:"\e696"}.fw-web-clip:before{content:"\e698"}.fw-web-service:before{content:"\e69a"}.fw-website:before{content:"\e69b"}.fw-wifi:before{content:"\e607"}.fw-windows:before{content:"\e605"}.fw-worker-invoke:before{content:"\e723"}.fw-worker-reply:before{content:"\e724"}.fw-worker:before{content:"\e6ef"}.fw-wsdl:before{content:"\e6a0"}.fw-wso2-logo:before{content:"\e6a7"}.fw-wso2:before{content:"\e6a8"}.fw-xacml:before{content:"\e69f"}.fw-xml:before{content:"\e69c"}.fw-xq:before{content:"\e6a2"}.fw-xsd:before{content:"\e6a3"}.fw-xslt:before{content:"\e6a4"}.fw-youtube:before{content:"\e6e0"}.fw-zoom-in:before{content:"\e6a5"}.fw-zoom-out:before{content:"\e6a6"} \ No newline at end of file From 3565e03c1b0cfaadbb2936597eb4fb319ea4c9c9 Mon Sep 17 00:00:00 2001 From: charitha Date: Wed, 17 Apr 2019 09:21:27 +0530 Subject: [PATCH 03/34] Fix test cases --- .../impl/DeviceManagementServiceImpl.java | 17 ++++--- .../impl/DeviceTypeManagementServiceImpl.java | 16 ++++--- .../impl/DeviceManagementServiceImplTest.java | 18 ++------ .../DeviceTypeManagementAdminServiceTest.java | 8 ++-- .../impl/DeviceTypeManagementServiceTest.java | 13 +++--- .../common/DeviceTypeNotFoundException.java | 44 +++++++++++++++++++ .../DeviceManagementProviderService.java | 2 +- .../DeviceManagementProviderServiceImpl.java | 5 ++- .../impl/DeviceManagementServiceImpl.java | 10 ++++- .../impl/DeviceTypeManagementServiceImpl.java | 12 ++++- .../impl/DeviceManagementServiceImplTest.java | 10 ++--- 11 files changed, 109 insertions(+), 46 deletions(-) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceTypeNotFoundException.java diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java index 10aa8538fa..5c69f0bd4d 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java @@ -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 features; + List 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 + "'"; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceImpl.java index b20b3462de..e9129c4c6e 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceImpl.java @@ -38,6 +38,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.configuration.mgt.PlatformConfiguration; @@ -107,14 +108,19 @@ public class DeviceTypeManagementServiceImpl implements DeviceTypeManagementServ @Path("/{type}/features") public Response getFeatures(@PathParam("type") @Size(max = 45) String type, @HeaderParam("If-Modified-Since") String ifModifiedSince) { - List features; + List features = new ArrayList<>(); DeviceManagementProviderService dms; try { dms = DeviceMgtAPIUtils.getDeviceManagementService(); - FeatureManager fm = dms.getFeatureManager(type); - if (fm == null) { - features = new ArrayList<>(); - } else { + 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) { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java index c8549711fc..51aeaabde6 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java @@ -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); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementAdminServiceTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementAdminServiceTest.java index 0d275ea52d..1b8910507d 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementAdminServiceTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementAdminServiceTest.java @@ -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."); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceTest.java index 9629afb07a..7143108184 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceTest.java @@ -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 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"); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceTypeNotFoundException.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceTypeNotFoundException.java new file mode 100644 index 0000000000..d8034cc8cf --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/DeviceTypeNotFoundException.java @@ -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); + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java index 5e7658ae71..1c108fbb74 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java @@ -486,7 +486,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. diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java index fac5c6faa5..c579623d73 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java @@ -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; @@ -171,14 +172,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(); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java index d6269cc7c8..a57da167bd 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java @@ -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 " + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceImpl.java index 1fb5c0c37a..fa812a775e 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceImpl.java @@ -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) { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java index e1935904ae..c1732254aa 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java @@ -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); } From ea4954ba9d49eda7833f351b42f4a8f69cb61bf1 Mon Sep 17 00:00:00 2001 From: charitha Date: Sun, 21 Apr 2019 17:03:47 +0530 Subject: [PATCH 04/34] Fix policy UI --- .../jaggeryapps/devicemgt/api/data-tables-invoker-api.jag | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/api/data-tables-invoker-api.jag b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/api/data-tables-invoker-api.jag index 146abcf0d0..4271f463bd 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/api/data-tables-invoker-api.jag +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/api/data-tables-invoker-api.jag @@ -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]) { From 893328c0ca4bbe57e22a6c49441526efd4b61faf Mon Sep 17 00:00:00 2001 From: charitha Date: Thu, 25 Apr 2019 14:27:35 +0530 Subject: [PATCH 05/34] Fix build failure --- .../device/mgt/core/service/DeviceManagementProviderService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java index 7d3c0fdf52..3fa92a1aed 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java @@ -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; From 13511a79c42fb7863b32b9d401f80a0dc1f1928c Mon Sep 17 00:00:00 2001 From: charitha Date: Mon, 6 May 2019 13:47:56 +0530 Subject: [PATCH 06/34] Fix log issue in test cases --- .../mgt/jaxrs/service/impl/ActivityProviderServiceImplTest.java | 2 +- .../mgt/jaxrs/service/impl/ConfigurationServiceImplTest.java | 2 +- .../device/mgt/jaxrs/service/impl/DeviceAgentServiceTest.java | 2 +- .../mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java | 2 +- .../service/impl/DeviceTypeManagementAdminServiceTest.java | 2 +- .../mgt/jaxrs/service/impl/DeviceTypeManagementServiceTest.java | 2 +- .../mgt/jaxrs/service/impl/GeoLocationBasedServiceImplTest.java | 2 ++ .../mgt/jaxrs/service/impl/GroupManagementServiceImplTest.java | 2 +- .../service/impl/NotificationManagementServiceImplTest.java | 2 +- .../mgt/jaxrs/service/impl/UserManagementServiceImplTest.java | 2 +- 10 files changed, 11 insertions(+), 9 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/ActivityProviderServiceImplTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/ActivityProviderServiceImplTest.java index 0db0ac07b7..657dc4de0d 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/ActivityProviderServiceImplTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/ActivityProviderServiceImplTest.java @@ -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 }) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/ConfigurationServiceImplTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/ConfigurationServiceImplTest.java index 5a4b0cd13b..ed8478bc11 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/ConfigurationServiceImplTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/ConfigurationServiceImplTest.java @@ -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}) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceTest.java index efd573b11f..44c23440d9 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceAgentServiceTest.java @@ -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, diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java index 51aeaabde6..27e84c7fc9 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java @@ -68,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}) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementAdminServiceTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementAdminServiceTest.java index 1b8910507d..9c129cd593 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementAdminServiceTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementAdminServiceTest.java @@ -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 { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceTest.java index 7143108184..fa320b5b5f 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceTest.java @@ -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 { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GeoLocationBasedServiceImplTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GeoLocationBasedServiceImplTest.java index b655b1095e..befc2b47d6 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GeoLocationBasedServiceImplTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GeoLocationBasedServiceImplTest.java @@ -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; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImplTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImplTest.java index d3c42b794a..9a4829cb56 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImplTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GroupManagementServiceImplTest.java @@ -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}) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/NotificationManagementServiceImplTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/NotificationManagementServiceImplTest.java index 92e321745f..75a7f3cd1c 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/NotificationManagementServiceImplTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/NotificationManagementServiceImplTest.java @@ -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}) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImplTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImplTest.java index bcee738b6e..d6984503cb 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImplTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/UserManagementServiceImplTest.java @@ -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}) From 3b905f450a73c4ece361f97be4ce6993221d1eb2 Mon Sep 17 00:00:00 2001 From: charitha Date: Mon, 17 Jun 2019 09:36:54 +0530 Subject: [PATCH 07/34] Fix https://gitlab.com/entgra/product-iots/issues/109 --- .../src/main/resources/dbscripts/cdm/h2.sql | 4 ++-- .../src/main/resources/dbscripts/cdm/mssql.sql | 4 ++-- .../src/main/resources/dbscripts/cdm/mysql.sql | 4 ++-- .../src/main/resources/dbscripts/cdm/oracle.sql | 4 ++-- .../src/main/resources/dbscripts/cdm/postgresql.sql | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql index 6e4989721a..95d54b8da1 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/h2.sql @@ -12,7 +12,7 @@ CREATE TABLE IF NOT EXISTS DM_GROUP ( ID INTEGER AUTO_INCREMENT NOT NULL, GROUP_NAME VARCHAR(100) DEFAULT NULL, DESCRIPTION TEXT DEFAULT NULL, - OWNER VARCHAR(45) DEFAULT NULL, + OWNER VARCHAR(255) DEFAULT NULL, TENANT_ID INTEGER DEFAULT 0, PRIMARY KEY (ID) ); @@ -110,7 +110,7 @@ CREATE TABLE IF NOT EXISTS DM_PROFILE_OPERATION ( CREATE TABLE IF NOT EXISTS DM_ENROLMENT ( ID INTEGER AUTO_INCREMENT NOT NULL, DEVICE_ID INTEGER NOT NULL, - OWNER VARCHAR(50) NOT NULL, + OWNER VARCHAR(255) NOT NULL, OWNERSHIP VARCHAR(45) DEFAULT NULL, STATUS VARCHAR(50) NULL, DATE_OF_ENROLMENT TIMESTAMP DEFAULT NULL, diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql index 8d6bb0fb7d..eb423d96bf 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql @@ -20,7 +20,7 @@ IF NOT EXISTS(SELECT * ID INTEGER IDENTITY (1, 1) NOT NULL, GROUP_NAME VARCHAR(100) DEFAULT NULL, DESCRIPTION VARCHAR(MAX) DEFAULT NULL, - OWNER VARCHAR(45) DEFAULT NULL, + OWNER VARCHAR(255) DEFAULT NULL, TENANT_ID INTEGER DEFAULT 0, PRIMARY KEY (ID) ); @@ -140,7 +140,7 @@ IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[D CREATE TABLE DM_ENROLMENT ( ID INTEGER IDENTITY(1,1) NOT NULL, DEVICE_ID INTEGER NOT NULL, - OWNER VARCHAR(50) NOT NULL, + OWNER VARCHAR(255) NOT NULL, OWNERSHIP VARCHAR(45) DEFAULT NULL, STATUS VARCHAR(50) NULL, DATE_OF_ENROLMENT DATETIME2 DEFAULT NULL, diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql index 0ff005b6b9..2363beb5e7 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mysql.sql @@ -16,7 +16,7 @@ CREATE TABLE IF NOT EXISTS DM_GROUP ( ID INTEGER AUTO_INCREMENT NOT NULL, GROUP_NAME VARCHAR(100) DEFAULT NULL, DESCRIPTION TEXT DEFAULT NULL, - OWNER VARCHAR(45) DEFAULT NULL, + OWNER VARCHAR(255) DEFAULT NULL, TENANT_ID INTEGER DEFAULT 0, PRIMARY KEY (ID) ) @@ -125,7 +125,7 @@ CREATE TABLE IF NOT EXISTS DM_PROFILE_OPERATION ( CREATE TABLE IF NOT EXISTS DM_ENROLMENT ( ID INTEGER AUTO_INCREMENT NOT NULL, DEVICE_ID INTEGER NOT NULL, - OWNER VARCHAR(50) NOT NULL, + OWNER VARCHAR(255) NOT NULL, OWNERSHIP VARCHAR(45) DEFAULT NULL, STATUS VARCHAR(50) NULL, DATE_OF_ENROLMENT TIMESTAMP NULL DEFAULT NULL, diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql index 9ebdcf5615..f1d73729b0 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/oracle.sql @@ -27,7 +27,7 @@ CREATE TABLE DM_GROUP ( ID NUMBER(10) NOT NULL, DESCRIPTION CLOB DEFAULT NULL, GROUP_NAME VARCHAR2(100) DEFAULT NULL, - OWNER VARCHAR2(45) DEFAULT NULL, + OWNER VARCHAR2(255) DEFAULT NULL, TENANT_ID NUMBER(10) DEFAULT 0, CONSTRAINT PK_DM_GROUP PRIMARY KEY (ID) ) @@ -201,7 +201,7 @@ CREATE TABLE DM_PROFILE_OPERATION ( CREATE TABLE DM_ENROLMENT ( ID NUMBER(10) NOT NULL, DEVICE_ID NUMBER(10) NOT NULL, - OWNER VARCHAR2(50) NOT NULL, + OWNER VARCHAR2(255) NOT NULL, OWNERSHIP VARCHAR2(45) DEFAULT NULL, STATUS VARCHAR2(50) NULL, DATE_OF_ENROLMENT TIMESTAMP(0) DEFAULT NULL, diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql index 4ef06be29c..e401f099f7 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/postgresql.sql @@ -12,7 +12,7 @@ CREATE TABLE IF NOT EXISTS DM_GROUP ( ID BIGSERIAL NOT NULL PRIMARY KEY, GROUP_NAME VARCHAR(100) DEFAULT NULL, DESCRIPTION TEXT DEFAULT NULL, - OWNER VARCHAR(45) DEFAULT NULL, + OWNER VARCHAR(255) DEFAULT NULL, TENANT_ID INTEGER DEFAULT 0 ); @@ -108,7 +108,7 @@ CREATE TABLE IF NOT EXISTS DM_PROFILE_OPERATION ( CREATE TABLE IF NOT EXISTS DM_ENROLMENT ( ID BIGSERIAL NOT NULL PRIMARY KEY, DEVICE_ID INTEGER NOT NULL, - OWNER VARCHAR(50) NOT NULL, + OWNER VARCHAR(255) NOT NULL, OWNERSHIP VARCHAR(45) DEFAULT NULL, STATUS VARCHAR(50) NULL, DATE_OF_ENROLMENT TIMESTAMP NULL DEFAULT NULL, From 9d9f420c83bf4cf84bc9415b0febf6a794a47879 Mon Sep 17 00:00:00 2001 From: lasanthaDLPDS Date: Mon, 5 Aug 2019 18:26:30 +0530 Subject: [PATCH 08/34] Fix formatting issues --- .../impl/admin/DeviceManagementAdminServiceImpl.java | 12 ++++++------ .../wso2/carbon/device/mgt/core/dao/DeviceDAO.java | 4 ++-- .../mgt/core/dao/impl/AbstractDeviceDAOImpl.java | 4 ++-- .../device/mgt/core/dao/impl/EnrollmentDAOImpl.java | 12 +++++++++--- .../service/DeviceManagementProviderServiceImpl.java | 6 +++--- .../mgt/jaxrs/service/api/UserManagementService.java | 1 + .../impl/admin/DeviceManagementAdminServiceImpl.java | 12 ++++++------ 7 files changed, 29 insertions(+), 22 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java index 38e5804751..ecae28ff4f 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java @@ -99,24 +99,24 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe @QueryParam("owner") String owner, List deviceIdentifiers){ try { - if (DeviceMgtAPIUtils.getDeviceManagementService().updateEnrollment(owner, deviceIdentifiers)){ + if (DeviceMgtAPIUtils.getDeviceManagementService().updateEnrollment(owner, deviceIdentifiers)) { String msg = "Device owner is updated successfully."; return Response.status(Response.Status.OK).entity(msg).build(); } String msg = "Device owner updating is failed."; log.error(msg); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); - } catch(InvalidDeviceException e){ + } catch (InvalidDeviceException e) { String msg = "Invalid device identifiers are found with the request."; - log.error(msg); + log.error(msg, e); return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); - }catch (DeviceManagementException e) { + } catch (DeviceManagementException e) { String msg = "Error occurred when updating device owners."; - log.error(msg); + log.error(msg, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } catch (UserNotFoundException e) { String msg = "Couldn't found the owner in user store to update the owner of devices."; - log.error(msg); + log.error(msg, e); return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java index 5ea2a87b5b..6674c37a77 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java @@ -498,7 +498,8 @@ public interface DeviceDAO { * @throws DeviceManagementDAOException throws {@link DeviceManagementDAOException} if connections establishment * fails. */ - List getDevicesByIdentifiers(List deviceIdentifiers, int tenantId) throws DeviceManagementDAOException; + List getDevicesByIdentifiers(List deviceIdentifiers, int tenantId) + throws DeviceManagementDAOException; /** * This method is used to permanently delete the device and its related details @@ -508,4 +509,3 @@ public interface DeviceDAO { */ void deleteDevice(DeviceIdentifier deviceIdentifier, int tenantId) throws DeviceManagementDAOException; } - diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java index 1cd83aa794..413e9bc56c 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java @@ -1507,8 +1507,8 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { } return devices; } catch (SQLException e) { - throw new DeviceManagementDAOException("Error occurred while obtaining the DB connection when adding tags", - e); + throw new DeviceManagementDAOException("Error occurred while obtaining the DB connection to get devices for" + + " given device identifiers.", e); } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/EnrollmentDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/EnrollmentDAOImpl.java index 7bbb94bc89..77aab5bae9 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/EnrollmentDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/EnrollmentDAOImpl.java @@ -369,7 +369,11 @@ public class EnrollmentDAOImpl implements EnrollmentDAO { try { Connection conn = this.getConnection(); boolean updateStatus = true; - String sql = "UPDATE DM_ENROLMENT SET OWNER = ? WHERE ID = ? AND TENANT_ID = ?"; + String sql = "UPDATE " + + "DM_ENROLMENT " + + "SET OWNER = ? " + + "WHERE ID = ? AND " + + "TENANT_ID = ?"; try (PreparedStatement ps = conn.prepareStatement(sql)) { if (conn.getMetaData().supportsBatchUpdates()) { for (Device device : devices) { @@ -381,6 +385,7 @@ public class EnrollmentDAOImpl implements EnrollmentDAO { for (int i : ps.executeBatch()) { if (i == 0 || i == Statement.SUCCESS_NO_INFO || i == Statement.EXECUTE_FAILED) { updateStatus = false; + break; } } } else { @@ -390,14 +395,15 @@ public class EnrollmentDAOImpl implements EnrollmentDAO { ps.setInt(3, tenantId); if (ps.executeUpdate() == 0) { updateStatus = false; + break; } } } } return updateStatus; } catch (SQLException e) { - throw new DeviceManagementDAOException("Error occurred while obtaining the DB connection when adding tags", - e); + throw new DeviceManagementDAOException("Error occurred while obtaining the DB connection to update the " + + "owner of the device enrollment.", e); } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java index 11b6866433..943ee8079c 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java @@ -3086,12 +3086,12 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv DeviceManagementDAOFactory.rollbackTransaction(); return false; } catch (TransactionManagementException e) { - String msg = "Error occurred while initiating transaction"; + String msg = "Error occurred while initiating the transaction."; log.error(msg, e); throw new DeviceManagementException(msg, e); } catch (DeviceManagementDAOException e) { String msg = "Error occurred either verifying existence of device ids or updating owner of the device."; - log.error(msg); + log.error(msg, e); throw new DeviceManagementException(msg, e); } finally { DeviceManagementDAOFactory.closeConnection(); @@ -3114,7 +3114,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv return owner; } catch (UserStoreException e) { String msg = "Error occurred when checking whether owner is exist or not. Owner: " + owner; - log.error(msg); + log.error(msg, e); throw new DeviceManagementException(msg, e); } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java index a1bee403a8..3cb23087b8 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/UserManagementService.java @@ -147,6 +147,7 @@ import java.util.List; key = "perm:get-activity", permissions = {"/device-mgt/devices/owning-device/view"} ) + } ) @Path("/users") diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java index 7227f3cb0c..ddbf7eb72e 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.v09.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java @@ -97,24 +97,24 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe @QueryParam("owner") String owner, List deviceIdentifiers){ try { - if (DeviceMgtAPIUtils.getDeviceManagementService().updateEnrollment(owner, deviceIdentifiers)){ + if (DeviceMgtAPIUtils.getDeviceManagementService().updateEnrollment(owner, deviceIdentifiers)) { String msg = "Device owner is updated successfully."; return Response.status(Response.Status.OK).entity(msg).build(); } String msg = "Device owner updating is failed."; log.error(msg); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); - } catch(InvalidDeviceException e){ + } catch (InvalidDeviceException e) { String msg = "Invalid device identifiers are found with the request."; - log.error(msg); + log.error(msg, e); return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); - }catch (DeviceManagementException e) { + } catch (DeviceManagementException e) { String msg = "Error occurred when updating the device owner."; - log.error(msg); + log.error(msg, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); } catch (UserNotFoundException e) { String msg = "Couldn't found the owner in user store to update the owner of devices."; - log.error(msg); + log.error(msg, e); return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } } From bb82eb723605e008b95db0b691a84b7831a93366 Mon Sep 17 00:00:00 2001 From: charitha Date: Tue, 13 Aug 2019 00:08:58 +0530 Subject: [PATCH 09/34] Fix issue in IoT device type loading --- .../impl/admin/DeviceTypeManagementAdminServiceImpl.java | 8 ++++++-- .../devicemgt/app/modules/business-controllers/device.js | 9 --------- .../app/pages/cdmf.page.devicetype.edit/edit.js | 2 +- .../cdmf.page.devicetype.edit/public/js/bottomJs.js | 2 +- .../device-view.js | 2 +- .../cdmf.unit.default.device.type.type-view/type-view.js | 2 +- 6 files changed, 10 insertions(+), 15 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceTypeManagementAdminServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceTypeManagementAdminServiceImpl.java index d7f659871d..02c807df55 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceTypeManagementAdminServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceTypeManagementAdminServiceImpl.java @@ -137,7 +137,8 @@ public class DeviceTypeManagementAdminServiceImpl implements DeviceTypeManagemen @Override @PUT - public Response updateDeviceType(String type, DeviceType deviceType) { + @Path("/{type}") + public Response updateDeviceType(@PathParam("type") 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 + @@ -163,7 +164,10 @@ public class DeviceTypeManagementAdminServiceImpl implements DeviceTypeManagemen } @Override - public Response addDeviceTypePlatformConfig(String type, PlatformConfiguration platformConfiguration) { + @POST + @Path("/{type}/configs") + public Response addDeviceTypePlatformConfig(@PathParam("type") 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 + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/device.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/device.js index ca8fa6dbd8..c39e797bc2 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/device.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/modules/business-controllers/device.js @@ -327,15 +327,6 @@ deviceModule = function () { return response; }; - publicMethods.getDeviceTypesConfig = function () { - var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/device-types/config"; - var response = privateMethods.callBackend(url, constants["HTTP_GET"]); - if (response.status == "success") { - response.content = parse(response.content); - } - return response; - }; - /* @Updated */ diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devicetype.edit/edit.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devicetype.edit/edit.js index 94284ac016..692f692302 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devicetype.edit/edit.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devicetype.edit/edit.js @@ -35,7 +35,7 @@ function onRequest(context) { var deviceType = request.getParameter("type"); var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"]; var restAPIEndpoint = deviceMgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] - + "/device-types/config/" + deviceType; + + "/device-types/" + deviceType; displayData.name = deviceType; serviceInvokers.XMLHttp.get( restAPIEndpoint, diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devicetype.edit/public/js/bottomJs.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devicetype.edit/public/js/bottomJs.js index 3fd2548a6f..320d630efe 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devicetype.edit/public/js/bottomJs.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devicetype.edit/public/js/bottomJs.js @@ -210,7 +210,7 @@ $(document).ready(function () { }); deviceType.deviceTypeMetaDefinition.features = features; - var addRoleAPI = apiBasePath + "/admin/device-types"; + var addRoleAPI = apiBasePath + "/admin/device-types/" + deviceType.name; invokerUtil.put( addRoleAPI, diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.device-view/device-view.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.device-view/device-view.js index cf716ef35c..a431c66a71 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.device-view/device-view.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.device-view/device-view.js @@ -42,7 +42,7 @@ function onRequest(context) { var displayData = {}; var restAPIEndpoint = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] - + "/device-types/config/" + deviceType; + + "/device-types/" + deviceType; displayData.deviceType = deviceType; displayData.tenantDomain = tenantDomain; serviceInvokers.XMLHttp.get( diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.type-view/type-view.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.type-view/type-view.js index 0f3563bad1..0f24173632 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.type-view/type-view.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.type-view/type-view.js @@ -32,7 +32,7 @@ function onRequest(context) { return opts.inverse(this); }); var restAPIEndpoint = deviceMgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] - + "/device-types/config/" + deviceType; + + "/device-types/" + deviceType; displayData.deviceType = deviceType; displayData.tenantDomain = tenantDomain; serviceInvokers.XMLHttp.get( From 0d0daa5b8b56bc352155233636f22da6dfd64ce5 Mon Sep 17 00:00:00 2001 From: charitha Date: Thu, 15 Aug 2019 14:09:37 +0530 Subject: [PATCH 10/34] Fix CN extraction issue --- .../mgt/core/impl/CertificateGenerator.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/impl/CertificateGenerator.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/impl/CertificateGenerator.java index 71ce11b6b1..b25837154f 100755 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/impl/CertificateGenerator.java +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/impl/CertificateGenerator.java @@ -324,9 +324,14 @@ public class CertificateGenerator { KeyStoreReader keyStoreReader = new KeyStoreReader(); if (distinguishedName != null && !distinguishedName.isEmpty()) { if (distinguishedName.contains("/CN=")) { - String[] dnSplits = distinguishedName.split("/CN="); - String commonNameExtracted = dnSplits[dnSplits.length - 1]; - lookUpCertificate = keyStoreReader.getCertificateBySerial(commonNameExtracted); + String[] dnSplits = distinguishedName.split("/"); + for (String dnPart : dnSplits) { + if (dnPart.contains("CN=")) { + String commonNameExtracted = dnPart.replace("CN=", ""); + lookUpCertificate = keyStoreReader.getCertificateBySerial(commonNameExtracted); + break; + } + } } else { LdapName ldapName; try { @@ -711,4 +716,4 @@ public class CertificateGenerator { return generateCertificateFromCSR(privateKeyCA, certificationRequest, certCA.getIssuerX500Principal().getName()); } -} \ No newline at end of file +} From 18218a351c4e72b92008abd03bd8802d1aeba1b5 Mon Sep 17 00:00:00 2001 From: Ace Date: Thu, 15 Aug 2019 15:12:42 +0530 Subject: [PATCH 11/34] Fixing issues with searching devices with groupID as a param --- .../carbon/device/mgt/core/dao/DeviceDAO.java | 11 ++ .../dao/impl/device/GenericDeviceDAOImpl.java | 131 ++++++++++++++++++ .../dao/impl/device/OracleDeviceDAOImpl.java | 131 ++++++++++++++++++ .../impl/device/PostgreSQLDeviceDAOImpl.java | 130 +++++++++++++++++ .../impl/device/SQLServerDeviceDAOImpl.java | 130 +++++++++++++++++ .../DeviceManagementProviderServiceImpl.java | 6 +- .../cdmf.page.devices/public/js/listing.js | 5 +- .../dataTables.extended.serversidepaging.js | 3 + 8 files changed, 544 insertions(+), 3 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java index 5ea2a87b5b..6cb16016e6 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java @@ -277,6 +277,17 @@ public interface DeviceDAO { */ List getDevices(PaginationRequest request, int tenantId) throws DeviceManagementDAOException; + + /** + * This method is used to search for devices within a specific group. + * + * @param request PaginationRequest object holding the data for pagination + * @param tenantId tenant id. + * @return returns paginated list of devices. + * @throws DeviceManagementDAOException + */ + List searchDevicesInGroup(PaginationRequest request, int tenantId) throws DeviceManagementDAOException; + /** * This method is used to retrieve all the devices of a given tenant and device type. * diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java index 872ea7c285..8f38bc9d73 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/GenericDeviceDAOImpl.java @@ -153,6 +153,137 @@ public class GenericDeviceDAOImpl extends AbstractDeviceDAOImpl { return devices; } + + @Override + public List searchDevicesInGroup(PaginationRequest request, int tenantId) + throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + List devices = null; + + int groupId = request.getGroupId(); + String deviceType = request.getDeviceType(); + boolean isDeviceTypeProvided = false; + String deviceName = request.getDeviceName(); + boolean isDeviceNameProvided = false; + String owner = request.getOwner(); + boolean isOwnerProvided = false; + String ownerPattern = request.getOwnerPattern(); + boolean isOwnerPatternProvided = false; + String ownership = request.getOwnership(); + boolean isOwnershipProvided = false; + String status = request.getStatus(); + boolean isStatusProvided = false; + Date since = request.getSince(); + boolean isSinceProvided = false; + + try { + conn = this.getConnection(); + String sql = "SELECT d1.DEVICE_ID, d1.DESCRIPTION, d1.NAME AS DEVICE_NAME, d1.DEVICE_TYPE, " + + "d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " + + "e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, " + + "(SELECT gd.DEVICE_ID, gd.DESCRIPTION, gd.NAME, gd.DEVICE_IDENTIFICATION, t.NAME AS DEVICE_TYPE " + + "FROM (SELECT d.ID AS DEVICE_ID, d.DESCRIPTION, d.NAME, d.DEVICE_IDENTIFICATION, d.DEVICE_TYPE_ID " + + "FROM DM_DEVICE d, (SELECT dgm.DEVICE_ID FROM DM_DEVICE_GROUP_MAP dgm WHERE dgm.GROUP_ID = ?) dgm1 WHERE" + + " d.ID = dgm1.DEVICE_ID AND d.TENANT_ID = ?"; + + + //Add the query for device-name + if (deviceName != null && !deviceName.isEmpty()) { + sql = sql + " AND d.NAME LIKE ?"; + isDeviceNameProvided = true; + } + + sql = sql + ") gd, DM_DEVICE_TYPE t"; + + if (since != null) { + sql = sql + ", DM_DEVICE_DETAIL dt"; + isSinceProvided = true; + } + + sql = sql + " WHERE gd.DEVICE_TYPE_ID = t.ID"; + + //Add query for last updated timestamp + if (isSinceProvided) { + sql = sql + " AND dt.DEVICE_ID = gd.DEVICE_ID AND dt.UPDATE_TIMESTAMP > ?"; + } + + //Add the query for device-type + if (deviceType != null && !deviceType.isEmpty()) { + sql = sql + " AND t.NAME = ?"; + isDeviceTypeProvided = true; + } + + sql = sql + " ) d1 WHERE d1.DEVICE_ID = e.DEVICE_ID AND TENANT_ID = ? "; + + //Add the query for ownership + if (ownership != null && !ownership.isEmpty()) { + sql = sql + " AND e.OWNERSHIP = ?"; + isOwnershipProvided = true; + } + //Add the query for owner + if (owner != null && !owner.isEmpty()) { + sql = sql + " AND e.OWNER = ?"; + isOwnerProvided = true; + } else if (ownerPattern != null && !ownerPattern.isEmpty()) { + sql = sql + " AND e.OWNER LIKE ?"; + isOwnerPatternProvided = true; + } + //Add the query for status + if (status != null && !status.isEmpty()) { + sql = sql + " AND e.STATUS = ?"; + isStatusProvided = true; + } + + sql = sql + " LIMIT ?,?"; + + stmt = conn.prepareStatement(sql); + + stmt.setInt(1, groupId); + stmt.setInt(2, tenantId); + + int paramIdx = 3; + if (isDeviceNameProvided) { + stmt.setString(paramIdx++, deviceName + "%"); + } + if (isSinceProvided) { + stmt.setLong(paramIdx++, since.getTime()); + } + if (isDeviceTypeProvided) { + stmt.setString(paramIdx++, deviceType); + } + + stmt.setInt(paramIdx++, tenantId); + if (isOwnershipProvided) { + stmt.setString(paramIdx++, ownership); + } + if (isOwnerProvided) { + stmt.setString(paramIdx++, owner); + } else if (isOwnerPatternProvided) { + stmt.setString(paramIdx++, ownerPattern + "%"); + } + if (isStatusProvided) { + stmt.setString(paramIdx++, status); + } + stmt.setInt(paramIdx++, request.getStartIndex()); + stmt.setInt(paramIdx, request.getRowCount()); + + rs = stmt.executeQuery(); + devices = new ArrayList<>(); + while (rs.next()) { + Device device = DeviceManagementDAOUtil.loadDevice(rs); + devices.add(device); + } + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving information of" + + " devices belonging to group : " + groupId, e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + return devices; + } + @Override public List getDevicesOfUser(PaginationRequest request, int tenantId) throws DeviceManagementDAOException { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/OracleDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/OracleDeviceDAOImpl.java index 33875fc9c7..2d568fed7e 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/OracleDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/OracleDeviceDAOImpl.java @@ -159,6 +159,137 @@ public class OracleDeviceDAOImpl extends AbstractDeviceDAOImpl { return devices; } + @Override + public List searchDevicesInGroup(PaginationRequest request, int tenantId) + throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + List devices = null; + + int groupId = request.getGroupId(); + String deviceType = request.getDeviceType(); + boolean isDeviceTypeProvided = false; + String deviceName = request.getDeviceName(); + boolean isDeviceNameProvided = false; + String owner = request.getOwner(); + boolean isOwnerProvided = false; + String ownerPattern = request.getOwnerPattern(); + boolean isOwnerPatternProvided = false; + String ownership = request.getOwnership(); + boolean isOwnershipProvided = false; + String status = request.getStatus(); + boolean isStatusProvided = false; + Date since = request.getSince(); + boolean isSinceProvided = false; + + try { + conn = this.getConnection(); + String sql = "SELECT d1.DEVICE_ID, d1.DESCRIPTION, d1.NAME AS DEVICE_NAME, d1.DEVICE_TYPE, " + + "d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " + + "e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, " + + "(SELECT gd.DEVICE_ID, gd.DESCRIPTION, gd.NAME, gd.DEVICE_IDENTIFICATION, t.NAME AS DEVICE_TYPE " + + "FROM (SELECT d.ID AS DEVICE_ID, d.DESCRIPTION, d.NAME, d.DEVICE_IDENTIFICATION, d.DEVICE_TYPE_ID " + + "FROM DM_DEVICE d, (SELECT dgm.DEVICE_ID FROM DM_DEVICE_GROUP_MAP dgm WHERE dgm.GROUP_ID = ?) dgm1 WHERE" + + " d.ID = dgm1.DEVICE_ID AND d.TENANT_ID = ?"; + + + //Add the query for device-name + if (deviceName != null && !deviceName.isEmpty()) { + sql = sql + " AND d.NAME LIKE ?"; + isDeviceNameProvided = true; + } + + sql = sql + ") gd, DM_DEVICE_TYPE t"; + + if (since != null) { + sql = sql + ", DM_DEVICE_DETAIL dt"; + isSinceProvided = true; + } + + sql = sql + " WHERE gd.DEVICE_TYPE_ID = t.ID"; + + //Add query for last updated timestamp + if (isSinceProvided) { + sql = sql + " AND dt.DEVICE_ID = gd.DEVICE_ID AND dt.UPDATE_TIMESTAMP > ?"; + } + + //Add the query for device-type + if (deviceType != null && !deviceType.isEmpty()) { + sql = sql + " AND t.NAME = ?"; + isDeviceTypeProvided = true; + } + + sql = sql + " ) d1 WHERE d1.DEVICE_ID = e.DEVICE_ID AND TENANT_ID = ? "; + + //Add the query for ownership + if (ownership != null && !ownership.isEmpty()) { + sql = sql + " AND e.OWNERSHIP = ?"; + isOwnershipProvided = true; + } + //Add the query for owner + if (owner != null && !owner.isEmpty()) { + sql = sql + " AND e.OWNER = ?"; + isOwnerProvided = true; + } else if (ownerPattern != null && !ownerPattern.isEmpty()) { + sql = sql + " AND e.OWNER LIKE ?"; + isOwnerPatternProvided = true; + } + //Add the query for status + if (status != null && !status.isEmpty()) { + sql = sql + " AND e.STATUS = ?"; + isStatusProvided = true; + } + + sql = sql + " ORDER BY ENROLMENT_ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; + + stmt = conn.prepareStatement(sql); + + stmt.setInt(1, groupId); + stmt.setInt(2, tenantId); + + int paramIdx = 3; + if (isDeviceNameProvided) { + stmt.setString(paramIdx++, deviceName + "%"); + } + if (isSinceProvided) { + stmt.setLong(paramIdx++, since.getTime()); + } + if (isDeviceTypeProvided) { + stmt.setString(paramIdx++, deviceType); + } + + stmt.setInt(paramIdx++, tenantId); + if (isOwnershipProvided) { + stmt.setString(paramIdx++, ownership); + } + if (isOwnerProvided) { + stmt.setString(paramIdx++, owner); + } else if (isOwnerPatternProvided) { + stmt.setString(paramIdx++, ownerPattern + "%"); + } + if (isStatusProvided) { + stmt.setString(paramIdx++, status); + } + stmt.setInt(paramIdx++, request.getStartIndex()); + stmt.setInt(paramIdx, request.getRowCount()); + + rs = stmt.executeQuery(); + devices = new ArrayList<>(); + while (rs.next()) { + Device device = DeviceManagementDAOUtil.loadDevice(rs); + devices.add(device); + } + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving information of" + + " devices belonging to group : " + groupId, e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + return devices; + } + + @Override public List getDevicesOfUser(PaginationRequest request, int tenantId) throws DeviceManagementDAOException { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/PostgreSQLDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/PostgreSQLDeviceDAOImpl.java index f8bce9b286..e46d460bcb 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/PostgreSQLDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/PostgreSQLDeviceDAOImpl.java @@ -140,6 +140,136 @@ public class PostgreSQLDeviceDAOImpl extends AbstractDeviceDAOImpl { return devices; } + @Override + public List searchDevicesInGroup(PaginationRequest request, int tenantId) + throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + List devices = null; + + int groupId = request.getGroupId(); + String deviceType = request.getDeviceType(); + boolean isDeviceTypeProvided = false; + String deviceName = request.getDeviceName(); + boolean isDeviceNameProvided = false; + String owner = request.getOwner(); + boolean isOwnerProvided = false; + String ownerPattern = request.getOwnerPattern(); + boolean isOwnerPatternProvided = false; + String ownership = request.getOwnership(); + boolean isOwnershipProvided = false; + String status = request.getStatus(); + boolean isStatusProvided = false; + Date since = request.getSince(); + boolean isSinceProvided = false; + + try { + conn = this.getConnection(); + String sql = "SELECT d1.DEVICE_ID, d1.DESCRIPTION, d1.NAME AS DEVICE_NAME, d1.DEVICE_TYPE, " + + "d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " + + "e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, " + + "(SELECT gd.DEVICE_ID, gd.DESCRIPTION, gd.NAME, gd.DEVICE_IDENTIFICATION, t.NAME AS DEVICE_TYPE " + + "FROM (SELECT d.ID AS DEVICE_ID, d.DESCRIPTION, d.NAME, d.DEVICE_IDENTIFICATION, d.DEVICE_TYPE_ID " + + "FROM DM_DEVICE d, (SELECT dgm.DEVICE_ID FROM DM_DEVICE_GROUP_MAP dgm WHERE dgm.GROUP_ID = ?) dgm1 WHERE" + + " d.ID = dgm1.DEVICE_ID AND d.TENANT_ID = ?"; + + + //Add the query for device-name + if (deviceName != null && !deviceName.isEmpty()) { + sql = sql + " AND d.NAME LIKE ?"; + isDeviceNameProvided = true; + } + + sql = sql + ") gd, DM_DEVICE_TYPE t"; + + if (since != null) { + sql = sql + ", DM_DEVICE_DETAIL dt"; + isSinceProvided = true; + } + + sql = sql + " WHERE gd.DEVICE_TYPE_ID = t.ID"; + + //Add query for last updated timestamp + if (isSinceProvided) { + sql = sql + " AND dt.DEVICE_ID = gd.DEVICE_ID AND dt.UPDATE_TIMESTAMP > ?"; + } + + //Add the query for device-type + if (deviceType != null && !deviceType.isEmpty()) { + sql = sql + " AND t.NAME = ?"; + isDeviceTypeProvided = true; + } + + sql = sql + " ) d1 WHERE d1.DEVICE_ID = e.DEVICE_ID AND TENANT_ID = ? "; + + //Add the query for ownership + if (ownership != null && !ownership.isEmpty()) { + sql = sql + " AND e.OWNERSHIP = ?"; + isOwnershipProvided = true; + } + //Add the query for owner + if (owner != null && !owner.isEmpty()) { + sql = sql + " AND e.OWNER = ?"; + isOwnerProvided = true; + } else if (ownerPattern != null && !ownerPattern.isEmpty()) { + sql = sql + " AND e.OWNER LIKE ?"; + isOwnerPatternProvided = true; + } + //Add the query for status + if (status != null && !status.isEmpty()) { + sql = sql + " AND e.STATUS = ?"; + isStatusProvided = true; + } + + sql = sql + " LIMIT ? OFFSET ?"; + + stmt = conn.prepareStatement(sql); + + stmt.setInt(1, groupId); + stmt.setInt(2, tenantId); + + int paramIdx = 3; + if (isDeviceNameProvided) { + stmt.setString(paramIdx++, deviceName + "%"); + } + if (isSinceProvided) { + stmt.setLong(paramIdx++, since.getTime()); + } + if (isDeviceTypeProvided) { + stmt.setString(paramIdx++, deviceType); + } + + stmt.setInt(paramIdx++, tenantId); + if (isOwnershipProvided) { + stmt.setString(paramIdx++, ownership); + } + if (isOwnerProvided) { + stmt.setString(paramIdx++, owner); + } else if (isOwnerPatternProvided) { + stmt.setString(paramIdx++, ownerPattern + "%"); + } + if (isStatusProvided) { + stmt.setString(paramIdx++, status); + } + stmt.setInt(paramIdx, request.getRowCount()); + stmt.setInt(paramIdx++, request.getStartIndex()); + + rs = stmt.executeQuery(); + devices = new ArrayList<>(); + while (rs.next()) { + Device device = DeviceManagementDAOUtil.loadDevice(rs); + devices.add(device); + } + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving information of" + + " devices belonging to group : " + groupId, e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + return devices; + } + @Override public List getDevicesOfUser(PaginationRequest request, int tenantId) throws DeviceManagementDAOException { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/SQLServerDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/SQLServerDeviceDAOImpl.java index ee60068fa8..12635fd1a1 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/SQLServerDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/device/SQLServerDeviceDAOImpl.java @@ -156,6 +156,136 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl { return devices; } + @Override + public List searchDevicesInGroup(PaginationRequest request, int tenantId) + throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + List devices = null; + + int groupId = request.getGroupId(); + String deviceType = request.getDeviceType(); + boolean isDeviceTypeProvided = false; + String deviceName = request.getDeviceName(); + boolean isDeviceNameProvided = false; + String owner = request.getOwner(); + boolean isOwnerProvided = false; + String ownerPattern = request.getOwnerPattern(); + boolean isOwnerPatternProvided = false; + String ownership = request.getOwnership(); + boolean isOwnershipProvided = false; + String status = request.getStatus(); + boolean isStatusProvided = false; + Date since = request.getSince(); + boolean isSinceProvided = false; + + try { + conn = this.getConnection(); + String sql = "SELECT d1.DEVICE_ID, d1.DESCRIPTION, d1.NAME AS DEVICE_NAME, d1.DEVICE_TYPE, " + + "d1.DEVICE_IDENTIFICATION, e.OWNER, e.OWNERSHIP, e.STATUS, e.DATE_OF_LAST_UPDATE, " + + "e.DATE_OF_ENROLMENT, e.ID AS ENROLMENT_ID FROM DM_ENROLMENT e, " + + "(SELECT gd.DEVICE_ID, gd.DESCRIPTION, gd.NAME, gd.DEVICE_IDENTIFICATION, t.NAME AS DEVICE_TYPE " + + "FROM (SELECT d.ID AS DEVICE_ID, d.DESCRIPTION, d.NAME, d.DEVICE_IDENTIFICATION, d.DEVICE_TYPE_ID " + + "FROM DM_DEVICE d, (SELECT dgm.DEVICE_ID FROM DM_DEVICE_GROUP_MAP dgm WHERE dgm.GROUP_ID = ?) dgm1 WHERE" + + " d.ID = dgm1.DEVICE_ID AND d.TENANT_ID = ?"; + + + //Add the query for device-name + if (deviceName != null && !deviceName.isEmpty()) { + sql = sql + " AND d.NAME LIKE ?"; + isDeviceNameProvided = true; + } + + sql = sql + ") gd, DM_DEVICE_TYPE t"; + + if (since != null) { + sql = sql + ", DM_DEVICE_DETAIL dt"; + isSinceProvided = true; + } + + sql = sql + " WHERE gd.DEVICE_TYPE_ID = t.ID"; + + //Add query for last updated timestamp + if (isSinceProvided) { + sql = sql + " AND dt.DEVICE_ID = gd.DEVICE_ID AND dt.UPDATE_TIMESTAMP > ?"; + } + + //Add the query for device-type + if (deviceType != null && !deviceType.isEmpty()) { + sql = sql + " AND t.NAME = ?"; + isDeviceTypeProvided = true; + } + + sql = sql + " ) d1 WHERE d1.DEVICE_ID = e.DEVICE_ID AND TENANT_ID = ? "; + + //Add the query for ownership + if (ownership != null && !ownership.isEmpty()) { + sql = sql + " AND e.OWNERSHIP = ?"; + isOwnershipProvided = true; + } + //Add the query for owner + if (owner != null && !owner.isEmpty()) { + sql = sql + " AND e.OWNER = ?"; + isOwnerProvided = true; + } else if (ownerPattern != null && !ownerPattern.isEmpty()) { + sql = sql + " AND e.OWNER LIKE ?"; + isOwnerPatternProvided = true; + } + //Add the query for status + if (status != null && !status.isEmpty()) { + sql = sql + " AND e.STATUS = ?"; + isStatusProvided = true; + } + + sql = sql + " ORDER BY ENROLMENT_ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; + + stmt = conn.prepareStatement(sql); + + stmt.setInt(1, groupId); + stmt.setInt(2, tenantId); + + int paramIdx = 3; + if (isDeviceNameProvided) { + stmt.setString(paramIdx++, deviceName + "%"); + } + if (isSinceProvided) { + stmt.setLong(paramIdx++, since.getTime()); + } + if (isDeviceTypeProvided) { + stmt.setString(paramIdx++, deviceType); + } + + stmt.setInt(paramIdx++, tenantId); + if (isOwnershipProvided) { + stmt.setString(paramIdx++, ownership); + } + if (isOwnerProvided) { + stmt.setString(paramIdx++, owner); + } else if (isOwnerPatternProvided) { + stmt.setString(paramIdx++, ownerPattern + "%"); + } + if (isStatusProvided) { + stmt.setString(paramIdx++, status); + } + stmt.setInt(paramIdx++, request.getStartIndex()); + stmt.setInt(paramIdx, request.getRowCount()); + + rs = stmt.executeQuery(); + devices = new ArrayList<>(); + while (rs.next()) { + Device device = DeviceManagementDAOUtil.loadDevice(rs); + devices.add(device); + } + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving information of" + + " devices belonging to group : " + groupId, e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + return devices; + } + @Override public List getDevicesOfUser(PaginationRequest request, int tenantId) throws DeviceManagementDAOException { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java index 11b6866433..e3a2fb8fa9 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java @@ -824,7 +824,11 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv } else { try { DeviceManagementDAOFactory.openConnection(); - allDevices = deviceDAO.getDevices(request, tenantId); + if(request.getGroupId()!=0){ + allDevices = deviceDAO.searchDevicesInGroup(request, tenantId); + } else{ + allDevices = deviceDAO.getDevices(request, tenantId); + } count = deviceDAO.getDeviceCount(request, tenantId); } catch (DeviceManagementDAOException e) { String msg = "Error occurred while retrieving device list pertaining to the current tenant"; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devices/public/js/listing.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devices/public/js/listing.js index fbba497e09..2448a89f8f 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devices/public/js/listing.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/pages/cdmf.page.devices/public/js/listing.js @@ -506,7 +506,7 @@ function loadDevices(searchType, searchParam) { $('#device-grid').datatables_extended_serverside_paging( null, - serviceURL, + "/api/device-mgt/v1.0/devices/", dataFilter, columns, fnCreatedRow, @@ -525,7 +525,8 @@ function loadDevices(searchType, searchParam) { }, { "placeholder": "Top-Device-Name-Search", - "searchKey": "namePattern" + "searchKey": "namePattern", + "groupId": groupId } ); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.data-tables-extended/public/js/dataTables.extended.serversidepaging.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.data-tables-extended/public/js/dataTables.extended.serversidepaging.js index aff3ea3942..3f8e0a7b64 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.data-tables-extended/public/js/dataTables.extended.serversidepaging.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.data-tables-extended/public/js/dataTables.extended.serversidepaging.js @@ -76,6 +76,9 @@ $.fn.datatables_extended_serverside_paging = function (settings, url, dataFilter searchParams[params.columns[i].data] = encodeURIComponent(params.columns[i].search.value); } if (options) { + if (options.groupId){ + searchParams["groupId"] = options.groupId; + } searchParams[options.searchKey] = encodeURIComponent(params.search.value); } params.filter = JSON.stringify(searchParams); From 1c825af79d6c0da0ee87727531c93cd305bf615c Mon Sep 17 00:00:00 2001 From: Saad Sahibjan Date: Thu, 15 Aug 2019 17:08:21 +0530 Subject: [PATCH 12/34] Move delete device permanently to device-mgt admin API --- .../service/api/DeviceManagementService.java | 7 +- .../admin/DeviceManagementAdminService.java | 90 +++++++++++++++++++ .../impl/DeviceManagementServiceImpl.java | 14 +-- .../DeviceManagementAdminServiceImpl.java | 45 +++++++++- .../impl/DeviceManagementServiceImplTest.java | 9 +- 5 files changed, 138 insertions(+), 27 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java index 4cf332c0b8..aba6d9819c 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceManagementService.java @@ -901,12 +901,7 @@ public interface DeviceManagementService { required = true) @PathParam("device-id") @Size(max = 45) - String deviceId, - @ApiParam( - name = "permanentDelete", - value = "Boolean flag indicating whether to permanently delete the device.", - required = false) - @QueryParam("permanentDelete") boolean permanentDelete); + String deviceId); @GET @Path("/{type}/{id}/features") diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceManagementAdminService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceManagementAdminService.java index b96977adfb..4377c9d185 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceManagementAdminService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceManagementAdminService.java @@ -15,6 +15,22 @@ * 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; @@ -76,6 +92,12 @@ import java.util.List; description = "Update the ownership of the device", key = "perm:admin:devices:update-enrollment", permissions = {"/device-mgt/admin/devices/update-enrollment"} + ), + @Scope( + name = "Permanently Delete the device specified by device id", + description = "Permanently Delete the device specified by device id", + key = "perm:devices:permanent-delete", + permissions = {"/device-mgt/admin/devices/permanent-delete"} ) } ) @@ -225,4 +247,72 @@ public interface DeviceManagementAdminService { value = "List of device identifiers.", required = true) List deviceIdentifiers); + + @DELETE + @Path("/type/{device-type}/id/{device-id}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + consumes = MediaType.APPLICATION_JSON, + httpMethod = "DELETE", + value = "Permanently remove the Device Specified by the Device ID", + notes = "Returns the status of the permanently deleted device operation and the details of the deleted device.", + tags = "Device Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:devices:permanent-delete") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully deleted the device permanently.", + response = Device.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 has been modified the last time.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 304, + message = "Not Modified. Empty body because the client already has the latest " + + "version of the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n No device is found under the provided type and id.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n " + + "Server error occurred while retrieving information requested device.", + response = ErrorResponse.class) + }) + Response deleteDevicePermanently( + @ApiParam( + name = "device-type", + value = "The device type, such as ios, android, or windows.", + required = true) + @PathParam("device-type") + @Size(max = 45) + String deviceType, + @ApiParam( + name = "device-id", + value = "The device identifier of the device.", + required = true) + @PathParam("device-id") + @Size(max = 45) + String deviceId); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java index 2e7aeb9e53..33cf2ec35b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java @@ -105,7 +105,6 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; -import java.util.Map; @Path("/devices") @Produces(MediaType.APPLICATION_JSON) @@ -326,8 +325,7 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { @Override @Path("/type/{device-type}/id/{device-id}") public Response deleteDevice(@PathParam("device-type") String deviceType, - @PathParam("device-id") String deviceId, - @QueryParam("permanentDelete") boolean permanentDelete) { + @PathParam("device-id") String deviceId) { DeviceManagementProviderService deviceManagementProviderService = DeviceMgtAPIUtils.getDeviceManagementService(); try { @@ -336,16 +334,8 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { if (persistedDevice == null) { return Response.status(Response.Status.NOT_FOUND).build(); } - - boolean response; - - if (permanentDelete) { - response = deviceManagementProviderService.deleteDevice(deviceIdentifier); - } else { - response = deviceManagementProviderService.disenrollDevice(deviceIdentifier); - } + boolean response = deviceManagementProviderService.disenrollDevice(deviceIdentifier); return Response.status(Response.Status.OK).entity(response).build(); - } catch (DeviceManagementException e) { String msg = "Error encountered while deleting device of type : " + deviceType + " and " + "ID : " + deviceId; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java index ecae28ff4f..d3d0fe194c 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java @@ -15,28 +15,43 @@ * 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.apache.solr.common.StringUtils; -import org.wso2.carbon.apimgt.integration.generated.client.publisher.StringUtil; import org.wso2.carbon.base.MultitenantConstants; import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext; 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.InvalidDeviceException; import org.wso2.carbon.device.mgt.common.PaginationRequest; import org.wso2.carbon.device.mgt.common.UserNotFoundException; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceList; import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; import org.wso2.carbon.device.mgt.jaxrs.service.api.admin.DeviceManagementAdminService; import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; -import javax.validation.constraints.Past; import javax.validation.constraints.Size; import javax.ws.rs.*; import javax.ws.rs.core.MediaType; @@ -120,4 +135,28 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe return Response.status(Response.Status.BAD_REQUEST).entity(msg).build(); } } + + @DELETE + @Override + @Path("/type/{device-type}/id/{device-id}") + public Response deleteDevicePermanently(@PathParam("device-type") String deviceType, + @PathParam("device-id") String deviceId) { + DeviceManagementProviderService deviceManagementProviderService = + DeviceMgtAPIUtils.getDeviceManagementService(); + try { + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(deviceId, deviceType); + Device persistedDevice = deviceManagementProviderService.getDevice(deviceIdentifier, true); + if (persistedDevice == null) { + return Response.status(Response.Status.NOT_FOUND).build(); + } + boolean response = deviceManagementProviderService.deleteDevice(deviceIdentifier); + return Response.status(Response.Status.OK).entity(response).build(); + } catch (DeviceManagementException e) { + String msg = "Error encountered while permanently deleting device of type : " + deviceType + " and " + + "ID : " + deviceId; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST) + .entity(new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java index 6b923ba775..fc26189f40 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/test/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImplTest.java @@ -481,8 +481,7 @@ public class DeviceManagementServiceImplTest { public void testDeleteDevice() { PowerMockito.stub(PowerMockito.method(DeviceMgtAPIUtils.class, "getDeviceManagementService")) .toReturn(this.deviceManagementProviderService); - Response response = this.deviceManagementService.deleteDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString() - , false); + Response response = this.deviceManagementService.deleteDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString()); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); } @@ -492,8 +491,7 @@ public class DeviceManagementServiceImplTest { .toReturn(this.deviceManagementProviderService); Mockito.when(this.deviceManagementProviderService .getDevice(Mockito.any(DeviceIdentifier.class), Mockito.anyBoolean())).thenReturn(null); - Response response = this.deviceManagementService.deleteDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString() - , false); + Response response = this.deviceManagementService.deleteDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString()); Assert.assertEquals(response.getStatus(), Response.Status.NOT_FOUND.getStatusCode()); Mockito.reset(this.deviceManagementProviderService); } @@ -504,8 +502,7 @@ public class DeviceManagementServiceImplTest { .toReturn(this.deviceManagementProviderService); Mockito.when(this.deviceManagementProviderService.disenrollDevice(Mockito.any(DeviceIdentifier.class))) .thenThrow(new DeviceManagementException()); - Response response = this.deviceManagementService.deleteDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString() - , false); + Response response = this.deviceManagementService.deleteDevice(TEST_DEVICE_TYPE, UUID.randomUUID().toString()); Assert.assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode()); Mockito.reset(this.deviceManagementProviderService); } From 1cf86ee95888572f89e10780342fdb7952ba9560 Mon Sep 17 00:00:00 2001 From: Milan Perera Date: Thu, 15 Aug 2019 17:08:45 +0200 Subject: [PATCH 13/34] Remove additional HTTP call from mssl handler This fixes the entgra/product-iots#128 --- .../handlers/AuthenticationHandler.java | 13 +++----- .../carbon/apimgt/handlers/utils/Utils.java | 32 +++---------------- 2 files changed, 9 insertions(+), 36 deletions(-) diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandler.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandler.java index 8bad3de1a8..5638f3ba58 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandler.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandler.java @@ -95,7 +95,7 @@ public class AuthenticationHandler extends AbstractHandler { log.debug("Verify Cert:\n" + mdmSignature); } URI certVerifyUrl = new URI(iotServerConfiguration.getVerificationEndpoint() + "ios"); - Map certVerifyHeaders = this.setHeaders(this.restInvoker); + Map certVerifyHeaders = this.setHeaders(); Certificate certificate = new Certificate(); certificate.setPem(mdmSignature); @@ -127,7 +127,7 @@ public class AuthenticationHandler extends AbstractHandler { String deviceType = this.getDeviceType(messageContext.getTo().getAddress().trim()); URI certVerifyUrl = new URI(iotServerConfiguration.getVerificationEndpoint() + deviceType); - Map certVerifyHeaders = this.setHeaders(this.restInvoker); + Map certVerifyHeaders = this.setHeaders(); Certificate certificate = new Certificate(); certificate.setPem(subjectDN); certificate.setTenantId(tenantId); @@ -157,7 +157,7 @@ public class AuthenticationHandler extends AbstractHandler { } String deviceType = this.getDeviceType(messageContext.getTo().getAddress().trim()); URI certVerifyUrl = new URI(iotServerConfiguration.getVerificationEndpoint() + deviceType); - Map certVerifyHeaders = this.setHeaders(this.restInvoker); + Map certVerifyHeaders = this.setHeaders(); Certificate certificate = new Certificate(); certificate.setPem(encodedPem); @@ -184,9 +184,6 @@ public class AuthenticationHandler extends AbstractHandler { } catch (URISyntaxException e) { log.error("Error while processing certificate.", e); return false; - } catch (APIMCertificateMGTException e) { - log.error("Error while processing certificate.", e); - return false; } catch (CertificateException e) { log.error("Certificate issue occurred when generating converting PEM to x509Certificate", e); return false; @@ -212,9 +209,9 @@ public class AuthenticationHandler extends AbstractHandler { return null; } - private Map setHeaders(RESTInvoker restInvoker) throws APIMCertificateMGTException { + private Map setHeaders() { Map map = new HashMap<>(); - String accessToken = Utils.getAccessToken(iotServerConfiguration, restInvoker); + String accessToken = Utils.getBase64EncodedToken(iotServerConfiguration); map.put(AUTHORIZATION, BEARER + accessToken); map.put(CONTENT_TYPE, "application/json"); return map; diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/utils/Utils.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/utils/Utils.java index f149868e76..5be2c18705 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/utils/Utils.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/utils/Utils.java @@ -135,38 +135,14 @@ public class Utils { } /** - * This class get the access token from the key manager. + * This method is used to get the base64 encoded token. * * @param iotServerConfiguration Instance of the IoTsererConfiguration. * @return Access token will be returned. - * @throws APIMCertificateMGTException */ - public static String getAccessToken(IOTServerConfiguration iotServerConfiguration, RESTInvoker restInvoker) - throws APIMCertificateMGTException { - try { - if (clientId == null || clientSecret == null) { - getClientSecretes(iotServerConfiguration, restInvoker); - } - URI tokenUrl = new URI(iotServerConfiguration.getOauthTokenEndpoint()); - String tokenContent = "grant_type=password&username=" + iotServerConfiguration.getUsername() + "&password=" + - iotServerConfiguration.getPassword() + "&scope=activity-view"; - String tokenBasicAuth = "Basic " + Base64.encode((clientId + ":" + clientSecret).getBytes()); - Map tokenHeaders = new HashMap<>(); - tokenHeaders.put("Authorization", tokenBasicAuth); - tokenHeaders.put("Content-Type", "application/x-www-form-urlencoded"); - - RESTResponse response = restInvoker.invokePOST(tokenUrl, tokenHeaders, tokenContent); - if (log.isDebugEnabled()) { - log.debug("Token response:" + response.getContent()); - } - JSONObject jsonResponse = new JSONObject(response.getContent()); - return jsonResponse.getString("access_token"); - - } catch (URISyntaxException | IOException e) { - throw new APIMCertificateMGTException("Error occurred while trying to call oauth token endpoint", e); - } catch (JSONException e) { - throw new APIMCertificateMGTException("Error occurred while converting the json to object", e); - } + public static String getBase64EncodedToken(IOTServerConfiguration iotServerConfiguration) { + return Base64.encode((iotServerConfiguration.getUsername() + ":" + iotServerConfiguration.getPassword()). + getBytes()); } /** From b7757a65ce8e424cce3884a4dc2456e1b2170f84 Mon Sep 17 00:00:00 2001 From: Milan Perera Date: Thu, 15 Aug 2019 20:49:14 +0200 Subject: [PATCH 14/34] Enable basic authentication in cert-mgt webapp --- .../src/main/webapp/WEB-INF/web.xml | 4 ++++ .../src/main/webapp/WEB-INF/web.xml | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.api/src/main/webapp/WEB-INF/web.xml b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.api/src/main/webapp/WEB-INF/web.xml index 6fd45f33b3..9722ee843e 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.api/src/main/webapp/WEB-INF/web.xml +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.api/src/main/webapp/WEB-INF/web.xml @@ -37,6 +37,10 @@ doAuthentication true + + basicAuth + true + diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/webapp/WEB-INF/web.xml b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/webapp/WEB-INF/web.xml index 9c7b5bea47..d642acfffa 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/webapp/WEB-INF/web.xml +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.v09.api/src/main/webapp/WEB-INF/web.xml @@ -41,6 +41,10 @@ isDefault false + + basicAuth + true + From 439ce4f1ece64dcf6b6ef190fa0639a8e6aa95a8 Mon Sep 17 00:00:00 2001 From: Milan Perera Date: Thu, 15 Aug 2019 22:23:46 +0200 Subject: [PATCH 15/34] Fix apim handler test failures --- .../wso2/carbon/apimgt/handlers/AuthenticationHandler.java | 2 +- .../carbon/apimgt/handlers/AuthenticationHandlerTest.java | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandler.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandler.java index 5638f3ba58..06d344a514 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandler.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandler.java @@ -55,7 +55,7 @@ public class AuthenticationHandler extends AbstractHandler { private static final String X_JWT_ASSERTION = "X-JWT-Assertion"; private static final String JWTTOKEN = "JWTToken"; private static final String AUTHORIZATION = "Authorization"; - private static final String BEARER = "Bearer "; + private static final String BEARER = "Basic "; private static final String CONTENT_TYPE = "Content-Type"; private IOTServerConfiguration iotServerConfiguration; diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/test/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandlerTest.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/test/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandlerTest.java index b3b8cdac78..23e6b251fc 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/test/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandlerTest.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/test/java/org/wso2/carbon/apimgt/handlers/AuthenticationHandlerTest.java @@ -92,8 +92,6 @@ public class AuthenticationHandlerTest extends BaseAPIHandlerTest { HashMap transportHeaders = new HashMap<>(); transportHeaders.put(AuthConstants.MDM_SIGNATURE, "some cert"); setMockClient(); - this.mockClient.setResponse(getDCRResponse()); - this.mockClient.setResponse(getAccessTokenReponse()); this.mockClient.setResponse(getValidationResponse()); boolean response = this.handler.handleRequest(createSynapseMessageContext("", this.synapseConfiguration, transportHeaders, "https://test.com/testservice/device-mgt/testdevice")); @@ -107,7 +105,6 @@ public class AuthenticationHandlerTest extends BaseAPIHandlerTest { HashMap transportHeaders = new HashMap<>(); transportHeaders.put(AuthConstants.PROXY_MUTUAL_AUTH_HEADER, "Test Header"); setMockClient(); - this.mockClient.setResponse(getAccessTokenReponse()); this.mockClient.setResponse(getValidationResponse()); boolean response = this.handler.handleRequest(createSynapseMessageContext("", this.synapseConfiguration, transportHeaders, "https://test.com/testservice/device-mgt/testdevice")); @@ -121,7 +118,6 @@ public class AuthenticationHandlerTest extends BaseAPIHandlerTest { HashMap transportHeaders = new HashMap<>(); transportHeaders.put(AuthConstants.MUTUAL_AUTH_HEADER, "Test Header"); setMockClient(); - this.mockClient.setResponse(getAccessTokenReponse()); this.mockClient.setResponse(getValidationResponse()); MessageContext messageContext = createSynapseMessageContext("", this.synapseConfiguration, transportHeaders, "https://test.com/testservice/device-mgt/testdevice"); @@ -141,7 +137,6 @@ public class AuthenticationHandlerTest extends BaseAPIHandlerTest { HashMap transportHeaders = new HashMap<>(); transportHeaders.put(AuthConstants.ENCODED_PEM, "encoded pem"); setMockClient(); - this.mockClient.setResponse(getAccessTokenReponse()); this.mockClient.setResponse(getValidationResponse()); MessageContext messageContext = createSynapseMessageContext("", this.synapseConfiguration, transportHeaders, "https://test.com/testservice/device-mgt/testdevice"); @@ -156,7 +151,6 @@ public class AuthenticationHandlerTest extends BaseAPIHandlerTest { HashMap transportHeaders = new HashMap<>(); transportHeaders.put(AuthConstants.ENCODED_PEM, "encoded pem"); setMockClient(); - this.mockClient.setResponse(getAccessTokenReponse()); this.mockClient.setResponse(getInvalidResponse()); MessageContext messageContext = createSynapseMessageContext("", this.synapseConfiguration, transportHeaders, "https://test.com/testservice/device-mgt/testdevice"); @@ -185,7 +179,6 @@ public class AuthenticationHandlerTest extends BaseAPIHandlerTest { HashMap transportHeaders = new HashMap<>(); transportHeaders.put(AuthConstants.ENCODED_PEM, "encoded pem"); setMockClient(); - this.mockClient.setResponse(getAccessTokenReponse()); this.mockClient.setResponse(null); MessageContext messageContext = createSynapseMessageContext("", this.synapseConfiguration, transportHeaders, "https://test.com/testservice/device-mgt/testdevice"); From dd4a31beb70f54b41e7b7a70ce0b6129947ddf93 Mon Sep 17 00:00:00 2001 From: Saad Sahibjan Date: Fri, 16 Aug 2019 13:49:49 +0530 Subject: [PATCH 16/34] Log and set message in response whend device not found to delete --- .../impl/admin/DeviceManagementAdminServiceImpl.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java index d3d0fe194c..4a2fb4f25d 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java @@ -147,7 +147,11 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe DeviceIdentifier deviceIdentifier = new DeviceIdentifier(deviceId, deviceType); Device persistedDevice = deviceManagementProviderService.getDevice(deviceIdentifier, true); if (persistedDevice == null) { - return Response.status(Response.Status.NOT_FOUND).build(); + String msg = "No device found with the device type: " + deviceType + + " having the device ID: " + deviceId + " to permanently delete."; + log.error(msg); + return Response.status(Response.Status.NOT_FOUND).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); } boolean response = deviceManagementProviderService.deleteDevice(deviceIdentifier); return Response.status(Response.Status.OK).entity(response).build(); @@ -155,8 +159,8 @@ public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminSe String msg = "Error encountered while permanently deleting device of type : " + deviceType + " and " + "ID : " + deviceId; log.error(msg, e); - return Response.status(Response.Status.BAD_REQUEST) - .entity(new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + return Response.status(Response.Status.BAD_REQUEST).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); } } } From 5271fc41635e80c6fb3bbb4a8f182842ae5165e9 Mon Sep 17 00:00:00 2001 From: Saad Sahibjan Date: Thu, 1 Aug 2019 17:57:44 +0530 Subject: [PATCH 17/34] Add device type extension config --- .../DeviceTypeManagerExtensionConfig.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/config/DeviceTypeManagerExtensionConfig.java diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/config/DeviceTypeManagerExtensionConfig.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/config/DeviceTypeManagerExtensionConfig.java new file mode 100644 index 0000000000..5cd564367a --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/config/DeviceTypeManagerExtensionConfig.java @@ -0,0 +1,19 @@ +package org.wso2.carbon.device.mgt.extensions.device.type.template.config; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement(name = "DeviceTypeManagerExtensionConfig") +public class DeviceTypeManagerExtensionConfig { + + private String extensionClass; + + @XmlElement(name = "ExtensionClass", required = true) + public String getExtensionClass() { + return extensionClass; + } + + public void setExtensionClass(String extensionClass) { + this.extensionClass = extensionClass; + } +} From f1c6ee70685ec9bdf61814835ea1c4cc2d2d0f07 Mon Sep 17 00:00:00 2001 From: Saad Sahibjan Date: Thu, 1 Aug 2019 17:58:05 +0530 Subject: [PATCH 18/34] Add interface for device type plugin dao --- .../DeviceTypeManagerExtensionService.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/spi/DeviceTypeManagerExtensionService.java diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/spi/DeviceTypeManagerExtensionService.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/spi/DeviceTypeManagerExtensionService.java new file mode 100644 index 0000000000..4155523595 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/spi/DeviceTypeManagerExtensionService.java @@ -0,0 +1,26 @@ +/* + * 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.extensions.spi; + +import org.wso2.carbon.device.mgt.extensions.device.type.template.dao.DeviceTypePluginDAOManager; + +public interface DeviceTypeManagerExtensionService { + + void setDeviceTypePluginDAOManager(DeviceTypePluginDAOManager deviceManager); +} From 9d81ee6cb40531583caeabf3aba8409436b3888e Mon Sep 17 00:00:00 2001 From: Saad Sahibjan Date: Thu, 1 Aug 2019 17:59:08 +0530 Subject: [PATCH 19/34] Expose device type extension dao plugin via device type deployer --- .../type/template/DeviceTypeManager.java | 32 +++++++++++++++++++ .../config/DeviceTypeConfiguration.java | 23 +++++++++++++ .../template/dao/DeviceTypeDAOHandler.java | 14 ++++++++ 3 files changed, 69 insertions(+) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManager.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManager.java index 948e5a5ff6..fc331d8220 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManager.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManager.java @@ -34,6 +34,7 @@ */ package org.wso2.carbon.device.mgt.extensions.device.type.template; +import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.w3c.dom.Document; @@ -48,9 +49,11 @@ import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration import org.wso2.carbon.device.mgt.common.license.mgt.License; import org.wso2.carbon.device.mgt.common.license.mgt.LicenseManagementException; import org.wso2.carbon.device.mgt.common.license.mgt.LicenseManager; +import org.wso2.carbon.device.mgt.extensions.spi.DeviceTypeManagerExtensionService; import org.wso2.carbon.device.mgt.extensions.device.type.template.config.DataSource; import org.wso2.carbon.device.mgt.extensions.device.type.template.config.DeviceDetails; import org.wso2.carbon.device.mgt.extensions.device.type.template.config.DeviceTypeConfiguration; +import org.wso2.carbon.device.mgt.extensions.device.type.template.config.DeviceTypeManagerExtensionConfig; import org.wso2.carbon.device.mgt.extensions.device.type.template.config.Feature; import org.wso2.carbon.device.mgt.extensions.device.type.template.config.Table; import org.wso2.carbon.device.mgt.extensions.device.type.template.config.TableConfig; @@ -213,6 +216,35 @@ public class DeviceTypeManager implements DeviceManager { } } } + setDeviceTypeManagerExtensionServices(deviceTypeConfiguration); + } + + private void setDeviceTypeManagerExtensionServices(DeviceTypeConfiguration deviceTypeConfiguration) { + DeviceTypeManagerExtensionConfig deviceTypeExtensionConfig = deviceTypeConfiguration.getDeviceTypeExtensionConfig(); + if (deviceTypeExtensionConfig != null) { + String extensionClass = deviceTypeExtensionConfig.getExtensionClass(); + if (StringUtils.isNotEmpty(extensionClass)) { + try { + Class clz = Class.forName(extensionClass); + DeviceTypeManagerExtensionService deviceTypeManagerExtensionService = (DeviceTypeManagerExtensionService) clz.newInstance(); + if (deviceTypePluginDAOManager != null) { + deviceTypeManagerExtensionService.setDeviceTypePluginDAOManager(deviceTypePluginDAOManager); + } + } catch (ClassNotFoundException e) { + String msg = "Extension class cannot be located"; + log.error(msg, e); + throw new DeviceTypeDeployerPayloadException(msg, e); + } catch (IllegalAccessException e) { + String msg = "Cannot access the class or its constructor is not accessible."; + log.error(msg, e); + throw new DeviceTypeDeployerPayloadException(msg, e); + } catch (InstantiationException e) { + String msg = "Extension class instantiation is failed"; + log.error(msg, e); + throw new DeviceTypeDeployerPayloadException(msg, e); + } + } + } } @Override diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/config/DeviceTypeConfiguration.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/config/DeviceTypeConfiguration.java index b1ba2d8fe8..568aa5ae73 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/config/DeviceTypeConfiguration.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/config/DeviceTypeConfiguration.java @@ -105,6 +105,8 @@ public class DeviceTypeConfiguration { @XmlElementWrapper(name = "StartupOperationConfig") @XmlElement(name = "Operation", required = true) protected List startupOperations; + @XmlElement(name = "DeviceTypeManagerExtensionConfig") + private DeviceTypeManagerExtensionConfig deviceTypeExtensionConfig; public List getOperations() { return operations; @@ -402,4 +404,25 @@ public class DeviceTypeConfiguration { public void setStartupOperations(List startupOperations) { this.startupOperations = startupOperations; } + + /** + * Gets the value of DeviceTypeManagerExtensionConfig + * + * @return possible object is + * {@link DeviceTypeManagerExtensionConfig} + */ + public DeviceTypeManagerExtensionConfig getDeviceTypeExtensionConfig() { + return deviceTypeExtensionConfig; + } + + /** + * Sets the value for DeviceTypeManagerExtensionConfig + * + * @param deviceTypeExtensionConfig possible object is + * {@link DeviceTypeManagerExtensionConfig} + */ + public void setDeviceTypeExtensionConfig( + DeviceTypeManagerExtensionConfig deviceTypeExtensionConfig) { + this.deviceTypeExtensionConfig = deviceTypeExtensionConfig; + } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypeDAOHandler.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypeDAOHandler.java index e31149fafe..b37eca5f85 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypeDAOHandler.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypeDAOHandler.java @@ -2,6 +2,7 @@ package org.wso2.carbon.device.mgt.extensions.device.type.template.dao; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.common.IllegalTransactionStateException; import org.wso2.carbon.device.mgt.extensions.device.type.template.exception.DeviceTypeDeployerPayloadException; import org.wso2.carbon.device.mgt.extensions.device.type.template.exception.DeviceTypeMgtPluginException; @@ -35,6 +36,19 @@ public class DeviceTypeDAOHandler { } } + public void openConnection() throws DeviceTypeMgtPluginException { + try { + Connection conn = currentConnection.get(); + if (conn != null) { + throw new IllegalTransactionStateException("Database connection has already been obtained."); + } + conn = dataSource.getConnection(); + currentConnection.set(conn); + } catch (SQLException e) { + throw new DeviceTypeMgtPluginException("Failed to get a database connection.", e); + } + } + public void beginTransaction() throws DeviceTypeMgtPluginException { try { Connection conn = dataSource.getConnection(); From 0d203e0cd598b504a4a120fcc3359270f48c736f Mon Sep 17 00:00:00 2001 From: Saad Sahibjan Date: Thu, 8 Aug 2019 16:38:33 +0530 Subject: [PATCH 20/34] Set device type plugin DAO manager in hashmap --- .../type/template/DeviceTypeManager.java | 108 +++++------------- .../DeviceTypeManagerExtensionService.java | 26 ----- 2 files changed, 29 insertions(+), 105 deletions(-) delete mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/spi/DeviceTypeManagerExtensionService.java diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManager.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManager.java index fc331d8220..1551d302b7 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManager.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManager.java @@ -49,11 +49,9 @@ import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration import org.wso2.carbon.device.mgt.common.license.mgt.License; import org.wso2.carbon.device.mgt.common.license.mgt.LicenseManagementException; import org.wso2.carbon.device.mgt.common.license.mgt.LicenseManager; -import org.wso2.carbon.device.mgt.extensions.spi.DeviceTypeManagerExtensionService; import org.wso2.carbon.device.mgt.extensions.device.type.template.config.DataSource; import org.wso2.carbon.device.mgt.extensions.device.type.template.config.DeviceDetails; import org.wso2.carbon.device.mgt.extensions.device.type.template.config.DeviceTypeConfiguration; -import org.wso2.carbon.device.mgt.extensions.device.type.template.config.DeviceTypeManagerExtensionConfig; import org.wso2.carbon.device.mgt.extensions.device.type.template.config.Feature; import org.wso2.carbon.device.mgt.extensions.device.type.template.config.Table; import org.wso2.carbon.device.mgt.extensions.device.type.template.config.TableConfig; @@ -65,6 +63,7 @@ import org.wso2.carbon.device.mgt.extensions.device.type.template.feature.Config import org.wso2.carbon.device.mgt.extensions.device.type.template.util.DeviceTypePluginConstants; import org.wso2.carbon.device.mgt.extensions.device.type.template.util.DeviceTypeUtils; import org.wso2.carbon.device.mgt.extensions.license.mgt.registry.RegistryBasedLicenseManager; +import org.wso2.carbon.device.mgt.extensions.spi.DeviceTypePluginExtensionService; import org.wso2.carbon.registry.api.RegistryException; import org.wso2.carbon.registry.api.Resource; import org.wso2.carbon.utils.CarbonUtils; @@ -216,34 +215,18 @@ public class DeviceTypeManager implements DeviceManager { } } } - setDeviceTypeManagerExtensionServices(deviceTypeConfiguration); + setDeviceTypePluginManager(); } - private void setDeviceTypeManagerExtensionServices(DeviceTypeConfiguration deviceTypeConfiguration) { - DeviceTypeManagerExtensionConfig deviceTypeExtensionConfig = deviceTypeConfiguration.getDeviceTypeExtensionConfig(); - if (deviceTypeExtensionConfig != null) { - String extensionClass = deviceTypeExtensionConfig.getExtensionClass(); - if (StringUtils.isNotEmpty(extensionClass)) { - try { - Class clz = Class.forName(extensionClass); - DeviceTypeManagerExtensionService deviceTypeManagerExtensionService = (DeviceTypeManagerExtensionService) clz.newInstance(); - if (deviceTypePluginDAOManager != null) { - deviceTypeManagerExtensionService.setDeviceTypePluginDAOManager(deviceTypePluginDAOManager); - } - } catch (ClassNotFoundException e) { - String msg = "Extension class cannot be located"; - log.error(msg, e); - throw new DeviceTypeDeployerPayloadException(msg, e); - } catch (IllegalAccessException e) { - String msg = "Cannot access the class or its constructor is not accessible."; - log.error(msg, e); - throw new DeviceTypeDeployerPayloadException(msg, e); - } catch (InstantiationException e) { - String msg = "Extension class instantiation is failed"; - log.error(msg, e); - throw new DeviceTypeDeployerPayloadException(msg, e); - } - } + /** + * Set device type plugin DAO manager of each device type in a HashMap which can then be used via individual + * device type plugin in working with its DAO components + */ + private void setDeviceTypePluginManager() { + if (StringUtils.isNotEmpty(deviceType) && deviceTypePluginDAOManager != null) { + DeviceTypePluginExtensionService deviceTypeManagerExtensionService = + new DeviceTypePluginExtensionServiceImpl(); + deviceTypeManagerExtensionService.addPluginDAOManager(deviceType, deviceTypePluginDAOManager); } } @@ -339,15 +322,11 @@ public class DeviceTypeManager implements DeviceManager { deviceTypePluginDAOManager.getDeviceTypeDAOHandler().commitTransaction(); } } catch (DeviceTypeMgtPluginException e) { - try { - deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction(); - } catch (DeviceTypeMgtPluginException ex) { - String msg = "Error occurred while roll back the device enrol transaction :" + - device.toString(); - log.warn(msg, ex); - } + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction(); String msg = "Error while enrolling the " + deviceType + " device : " + device.getDeviceIdentifier(); throw new DeviceManagementException(msg, e); + } finally { + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection(); } return status; } @@ -366,16 +345,12 @@ public class DeviceTypeManager implements DeviceManager { status = deviceTypePluginDAOManager.getDeviceDAO().updateDevice(device); deviceTypePluginDAOManager.getDeviceTypeDAOHandler().commitTransaction(); } catch (DeviceTypeMgtPluginException e) { - try { - deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction(); - } catch (DeviceTypeMgtPluginException mobileDAOEx) { - String msg = "Error occurred while roll back the update device transaction :" + - device.toString(); - log.warn(msg, mobileDAOEx); - } + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction(); String msg = "Error while updating the enrollment of the " + deviceType + " device : " + device.getDeviceIdentifier(); throw new DeviceManagementException(msg, e); + } finally { + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection(); } return status; } @@ -410,13 +385,7 @@ public class DeviceTypeManager implements DeviceManager { deviceId.getId(); throw new DeviceManagementException(msg, e); } finally { - try { - deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection(); - } catch (DeviceTypeMgtPluginException e) { - String msg = "Error occurred while closing the transaction to check device " + - deviceId.getId() + " is enrolled."; - log.warn(msg, e); - } + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection(); } return isEnrolled; } @@ -451,12 +420,7 @@ public class DeviceTypeManager implements DeviceManager { throw new DeviceManagementException( "Error occurred while fetching the " + deviceType + " device: '" + deviceId.getId() + "'", e); } finally { - try { - deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection(); - } catch (DeviceTypeMgtPluginException e) { - String msg = "Error occurred while closing the transaction to get device " + deviceId.getId(); - log.warn(msg, e); - } + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection(); } return device; } @@ -479,14 +443,11 @@ public class DeviceTypeManager implements DeviceManager { status = deviceTypePluginDAOManager.getDeviceDAO().updateDevice(updatedDevice); deviceTypePluginDAOManager.getDeviceTypeDAOHandler().commitTransaction(); } catch (DeviceTypeMgtPluginException e) { - try { - deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction(); - } catch (DeviceTypeMgtPluginException transactionException) { - String msg = "Error occurred while rolling back transaction for device: " + deviceId.getId(); - log.warn(msg, transactionException); - } + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction(); throw new DeviceManagementException( "Error occurred while fetching the " + deviceType + " device: '" + deviceId.getId() + "'", e); + } finally { + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection(); } } return status; @@ -576,15 +537,12 @@ public class DeviceTypeManager implements DeviceManager { status = deviceTypePluginDAOManager.getDeviceDAO().updateDevice(existingDevice); deviceTypePluginDAOManager.getDeviceTypeDAOHandler().commitTransaction(); } catch (DeviceTypeMgtPluginException e) { - try { - deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction(); - } catch (DeviceTypeMgtPluginException e1) { - log.warn("Error occurred while roll back the update device info transaction : '" + - device.toString() + "'", e1); - } + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction(); throw new DeviceManagementException( "Error occurred while updating the " + deviceType + " device: '" + device.getDeviceIdentifier() + "'", e); + } finally { + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection(); } return status; } @@ -604,12 +562,7 @@ public class DeviceTypeManager implements DeviceManager { } catch (DeviceTypeMgtPluginException e) { throw new DeviceManagementException("Error occurred while fetching all " + deviceType + " devices", e); } finally { - try { - deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection(); - } catch (DeviceTypeMgtPluginException e) { - String msg = "Error occurred while closing the transaction to get all devices."; - log.warn(msg, e); - } + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection(); } return devices; } @@ -632,15 +585,12 @@ public class DeviceTypeManager implements DeviceManager { status = deviceTypePluginDAOManager.getDeviceDAO().deleteDevice(existingDevice); deviceTypePluginDAOManager.getDeviceTypeDAOHandler().commitTransaction(); } catch (DeviceTypeMgtPluginException e) { - try { - deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction(); - } catch (DeviceTypeMgtPluginException e1) { - log.warn("Error occurred while roll back the delete device info transaction : '" + - device.toString() + "'", e1); - } + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().rollbackTransaction(); throw new DeviceManagementException( "Error occurred while deleting the " + deviceType + " device: '" + device.getDeviceIdentifier() + "'", e); + } finally { + deviceTypePluginDAOManager.getDeviceTypeDAOHandler().closeConnection(); } return status; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/spi/DeviceTypeManagerExtensionService.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/spi/DeviceTypeManagerExtensionService.java deleted file mode 100644 index 4155523595..0000000000 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/spi/DeviceTypeManagerExtensionService.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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.extensions.spi; - -import org.wso2.carbon.device.mgt.extensions.device.type.template.dao.DeviceTypePluginDAOManager; - -public interface DeviceTypeManagerExtensionService { - - void setDeviceTypePluginDAOManager(DeviceTypePluginDAOManager deviceManager); -} From f0103f27c4cb70447a17e7157eb2836f2c84fd18 Mon Sep 17 00:00:00 2001 From: Saad Sahibjan Date: Thu, 8 Aug 2019 16:39:18 +0530 Subject: [PATCH 21/34] Modify error messages and exception handling --- .../template/dao/DeviceTypeDAOHandler.java | 46 ++++++++----------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypeDAOHandler.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypeDAOHandler.java index b37eca5f85..6347aa136e 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypeDAOHandler.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypeDAOHandler.java @@ -70,25 +70,21 @@ public class DeviceTypeDAOHandler { return currentConnection.get(); } - public void commitTransaction() throws DeviceTypeMgtPluginException { + public void commitTransaction() { + Connection conn = currentConnection.get(); + if (conn == null) { + throw new IllegalStateException("No connection is associated with the current transaction. " + + "This might have ideally been caused by not properly initiating the " + + "transaction via 'beginTransaction'/'openConnection' methods"); + } try { - Connection conn = currentConnection.get(); - if (conn != null) { - conn.commit(); - } else { - if (log.isDebugEnabled()) { - log.debug("Datasource connection associated with the current thread is null, hence commit " - + "has not been attempted"); - } - } + conn.commit(); } catch (SQLException e) { - throw new DeviceTypeMgtPluginException("Error occurred while committing the transaction", e); - } finally { - closeConnection(); + log.error("Error occurred while committing the transaction.", e); } } - public void closeConnection() throws DeviceTypeMgtPluginException { + public void closeConnection() { Connection con = currentConnection.get(); if (con != null) { @@ -101,21 +97,17 @@ public class DeviceTypeDAOHandler { currentConnection.remove(); } - public void rollbackTransaction() throws DeviceTypeMgtPluginException { + public void rollbackTransaction() { + Connection conn = currentConnection.get(); + if (conn == null) { + throw new IllegalStateException("No connection is associated with the current transaction. " + + "This might have ideally been caused by not properly initiating the " + + "transaction via 'beginTransaction'/'openConnection' methods"); + } try { - Connection conn = currentConnection.get(); - if (conn != null) { - conn.rollback(); - } else { - if (log.isDebugEnabled()) { - log.debug("Datasource connection associated with the current thread is null, hence rollback " - + "has not been attempted"); - } - } + conn.rollback(); } catch (SQLException e) { - throw new DeviceTypeMgtPluginException("Error occurred while rollback the transaction", e); - } finally { - closeConnection(); + log.error("Error occurred while roll-backing the transaction.", e); } } } From 42b092d43ae9a06df12d3add14e14c6177a7d177 Mon Sep 17 00:00:00 2001 From: Saad Sahibjan Date: Thu, 8 Aug 2019 16:41:37 +0530 Subject: [PATCH 22/34] Add license header for DeviceTypeDAOHandler --- .../type/template/dao/DeviceTypeDAOHandler.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypeDAOHandler.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypeDAOHandler.java index 6347aa136e..edbbba52c6 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypeDAOHandler.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypeDAOHandler.java @@ -1,3 +1,20 @@ +/* + * 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.extensions.device.type.template.dao; import org.apache.commons.logging.Log; From c5b46415971024f30fe54bc7fe76953a943961a9 Mon Sep 17 00:00:00 2001 From: Saad Sahibjan Date: Thu, 8 Aug 2019 16:50:55 +0530 Subject: [PATCH 23/34] Add the interface of DeviceTypePluginExtensionService --- .../spi/DeviceTypePluginExtensionService.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/spi/DeviceTypePluginExtensionService.java diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/spi/DeviceTypePluginExtensionService.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/spi/DeviceTypePluginExtensionService.java new file mode 100644 index 0000000000..3c57300cec --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/spi/DeviceTypePluginExtensionService.java @@ -0,0 +1,41 @@ +/* + * 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.extensions.spi; + +import org.wso2.carbon.device.mgt.extensions.device.type.template.dao.DeviceTypePluginDAOManager; + +/** + * This represents the device type plugin extension service which can be used by any device type plugin implementation + * intended to use the same plugin DAO instances to be used with its plugin level DAO components + */ +public interface DeviceTypePluginExtensionService { + + /** + * Save device type specific pluginDAOManager in a HashMap + * @param deviceType - Type of the device (i.e; android, ios, windows) + * @param pluginDAOManager - Device type plugin DAO manager instance to be saved against device type + */ + void addPluginDAOManager(String deviceType, DeviceTypePluginDAOManager pluginDAOManager); + + /** + * Retrieve the DeviceTypePluginDAOManager instance given the device type + * @param deviceType - Type of the device (i.e; android, ios, windows) + * @return an Instance of {@link DeviceTypePluginDAOManager} + */ + DeviceTypePluginDAOManager getPluginDAOManager(String deviceType); +} From b9bceadec88d582711eedc037359155de2799915 Mon Sep 17 00:00:00 2001 From: Saad Sahibjan Date: Thu, 8 Aug 2019 16:51:21 +0530 Subject: [PATCH 24/34] Add the implementation of DeviceTypePluginExtensionService --- .../DeviceTypePluginExtensionServiceImpl.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypePluginExtensionServiceImpl.java diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypePluginExtensionServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypePluginExtensionServiceImpl.java new file mode 100644 index 0000000000..4ccaeadb60 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypePluginExtensionServiceImpl.java @@ -0,0 +1,43 @@ +/* + * 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.extensions.device.type.template; + +import org.wso2.carbon.device.mgt.extensions.device.type.template.dao.DeviceTypePluginDAOManager; +import org.wso2.carbon.device.mgt.extensions.spi.DeviceTypePluginExtensionService; + +import java.util.HashMap; +import java.util.Map; + +public class DeviceTypePluginExtensionServiceImpl implements DeviceTypePluginExtensionService { + + private static volatile Map pluginDAOManagers = new HashMap<>(); + + @Override + public void addPluginDAOManager(String deviceType, DeviceTypePluginDAOManager pluginDAOManager) { + if (pluginDAOManager != null) { + if (!pluginDAOManagers.containsKey(deviceType)) { + pluginDAOManagers.put(deviceType, pluginDAOManager); + } + } + } + + @Override + public DeviceTypePluginDAOManager getPluginDAOManager(String deviceType) { + return pluginDAOManagers.get(deviceType); + } +} From a246c16eb616aa2c8339e8037976e851c722c5a8 Mon Sep 17 00:00:00 2001 From: Saad Sahibjan Date: Thu, 8 Aug 2019 16:53:28 +0530 Subject: [PATCH 25/34] Register DeviceTypePluginExtensionService --- .../DeviceTypeExtensionServiceComponent.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/internal/DeviceTypeExtensionServiceComponent.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/internal/DeviceTypeExtensionServiceComponent.java index e29af46f12..36ae9b11dc 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/internal/DeviceTypeExtensionServiceComponent.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/internal/DeviceTypeExtensionServiceComponent.java @@ -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. (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.extensions.internal; @@ -23,6 +40,8 @@ import org.apache.commons.logging.LogFactory; import org.osgi.service.component.ComponentContext; import org.wso2.carbon.device.mgt.common.spi.DeviceTypeGeneratorService; import org.wso2.carbon.device.mgt.extensions.device.type.template.DeviceTypeGeneratorServiceImpl; +import org.wso2.carbon.device.mgt.extensions.device.type.template.DeviceTypePluginExtensionServiceImpl; +import org.wso2.carbon.device.mgt.extensions.spi.DeviceTypePluginExtensionService; import org.wso2.carbon.ndatasource.core.DataSourceService; import org.wso2.carbon.registry.core.service.RegistryService; @@ -50,6 +69,8 @@ public class DeviceTypeExtensionServiceComponent { } ctx.getBundleContext() .registerService(DeviceTypeGeneratorService.class, new DeviceTypeGeneratorServiceImpl(), null); + ctx.getBundleContext().registerService(DeviceTypePluginExtensionService.class, + new DeviceTypePluginExtensionServiceImpl(), null); if (log.isDebugEnabled()) { log.debug("Device Type Extension Service Component successfully activated"); } From d6d91e4bc2f40e95c5055f2fea0b843cf70baa06 Mon Sep 17 00:00:00 2001 From: Saad Sahibjan Date: Sat, 10 Aug 2019 23:11:08 +0530 Subject: [PATCH 26/34] Remove retrieving device type extension class from deployer file --- .../config/DeviceTypeConfiguration.java | 23 ------------------- .../DeviceTypeManagerExtensionConfig.java | 19 --------------- 2 files changed, 42 deletions(-) delete mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/config/DeviceTypeManagerExtensionConfig.java diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/config/DeviceTypeConfiguration.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/config/DeviceTypeConfiguration.java index 568aa5ae73..b1ba2d8fe8 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/config/DeviceTypeConfiguration.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/config/DeviceTypeConfiguration.java @@ -105,8 +105,6 @@ public class DeviceTypeConfiguration { @XmlElementWrapper(name = "StartupOperationConfig") @XmlElement(name = "Operation", required = true) protected List startupOperations; - @XmlElement(name = "DeviceTypeManagerExtensionConfig") - private DeviceTypeManagerExtensionConfig deviceTypeExtensionConfig; public List getOperations() { return operations; @@ -404,25 +402,4 @@ public class DeviceTypeConfiguration { public void setStartupOperations(List startupOperations) { this.startupOperations = startupOperations; } - - /** - * Gets the value of DeviceTypeManagerExtensionConfig - * - * @return possible object is - * {@link DeviceTypeManagerExtensionConfig} - */ - public DeviceTypeManagerExtensionConfig getDeviceTypeExtensionConfig() { - return deviceTypeExtensionConfig; - } - - /** - * Sets the value for DeviceTypeManagerExtensionConfig - * - * @param deviceTypeExtensionConfig possible object is - * {@link DeviceTypeManagerExtensionConfig} - */ - public void setDeviceTypeExtensionConfig( - DeviceTypeManagerExtensionConfig deviceTypeExtensionConfig) { - this.deviceTypeExtensionConfig = deviceTypeExtensionConfig; - } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/config/DeviceTypeManagerExtensionConfig.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/config/DeviceTypeManagerExtensionConfig.java deleted file mode 100644 index 5cd564367a..0000000000 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/config/DeviceTypeManagerExtensionConfig.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.wso2.carbon.device.mgt.extensions.device.type.template.config; - -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; - -@XmlRootElement(name = "DeviceTypeManagerExtensionConfig") -public class DeviceTypeManagerExtensionConfig { - - private String extensionClass; - - @XmlElement(name = "ExtensionClass", required = true) - public String getExtensionClass() { - return extensionClass; - } - - public void setExtensionClass(String extensionClass) { - this.extensionClass = extensionClass; - } -} From 0c7843f2fe8512e6c5c287d2e4c11d4df18b6dc2 Mon Sep 17 00:00:00 2001 From: Saad Sahibjan Date: Tue, 13 Aug 2019 18:40:10 +0530 Subject: [PATCH 27/34] Modify logic of saving DeviceTypePluginDAOManager to support multi tenancy --- .../type/template/DeviceTypeManager.java | 18 +++++++++--- .../DeviceTypePluginExtensionServiceImpl.java | 29 +++++++++++++++++-- .../DeviceTypePluginExtensionException.java | 12 ++++++++ .../spi/DeviceTypePluginExtensionService.java | 4 +-- 4 files changed, 54 insertions(+), 9 deletions(-) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/exception/DeviceTypePluginExtensionException.java diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManager.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManager.java index 1551d302b7..1169d7eebf 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManager.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManager.java @@ -59,6 +59,7 @@ import org.wso2.carbon.device.mgt.extensions.device.type.template.dao.DeviceDAOD import org.wso2.carbon.device.mgt.extensions.device.type.template.dao.DeviceTypePluginDAOManager; import org.wso2.carbon.device.mgt.extensions.device.type.template.exception.DeviceTypeDeployerPayloadException; import org.wso2.carbon.device.mgt.extensions.device.type.template.exception.DeviceTypeMgtPluginException; +import org.wso2.carbon.device.mgt.extensions.device.type.template.exception.DeviceTypePluginExtensionException; import org.wso2.carbon.device.mgt.extensions.device.type.template.feature.ConfigurationBasedFeatureManager; import org.wso2.carbon.device.mgt.extensions.device.type.template.util.DeviceTypePluginConstants; import org.wso2.carbon.device.mgt.extensions.device.type.template.util.DeviceTypeUtils; @@ -223,10 +224,19 @@ public class DeviceTypeManager implements DeviceManager { * device type plugin in working with its DAO components */ private void setDeviceTypePluginManager() { - if (StringUtils.isNotEmpty(deviceType) && deviceTypePluginDAOManager != null) { - DeviceTypePluginExtensionService deviceTypeManagerExtensionService = - new DeviceTypePluginExtensionServiceImpl(); - deviceTypeManagerExtensionService.addPluginDAOManager(deviceType, deviceTypePluginDAOManager); + if (StringUtils.isNotEmpty(deviceType)) { + if (deviceTypePluginDAOManager != null) { + DeviceTypePluginExtensionService deviceTypeManagerExtensionService = + new DeviceTypePluginExtensionServiceImpl(); + deviceTypeManagerExtensionService.addPluginDAOManager(deviceType, deviceTypePluginDAOManager); + } else { + log.warn("Could not save DeviceTypePluginDAOManager for device type: " + deviceType + + " since DeviceTypePluginDAOManager is null."); + } + } else { + String msg = "Could not save DeviceTypePluginDAOManager since device type is null or empty."; + log.error(msg); + throw new DeviceTypePluginExtensionException(msg); } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypePluginExtensionServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypePluginExtensionServiceImpl.java index 4ccaeadb60..bfe01098b6 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypePluginExtensionServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypePluginExtensionServiceImpl.java @@ -17,7 +17,11 @@ */ package org.wso2.carbon.device.mgt.extensions.device.type.template; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.extensions.device.type.template.dao.DeviceTypePluginDAOManager; +import org.wso2.carbon.device.mgt.extensions.device.type.template.exception.DeviceTypePluginExtensionException; import org.wso2.carbon.device.mgt.extensions.spi.DeviceTypePluginExtensionService; import java.util.HashMap; @@ -25,19 +29,38 @@ import java.util.Map; public class DeviceTypePluginExtensionServiceImpl implements DeviceTypePluginExtensionService { + private static final Log log = LogFactory.getLog(DeviceTypePluginExtensionServiceImpl.class); + private static volatile Map pluginDAOManagers = new HashMap<>(); @Override public void addPluginDAOManager(String deviceType, DeviceTypePluginDAOManager pluginDAOManager) { + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); if (pluginDAOManager != null) { - if (!pluginDAOManagers.containsKey(deviceType)) { - pluginDAOManagers.put(deviceType, pluginDAOManager); + if (!pluginDAOManagers.containsKey(tenantId + deviceType)) { + if (log.isDebugEnabled()) { + log.debug("Saving DeviceTypePluginDAOManager against tenant id " + tenantId + + " and device type: " + deviceType); + } + pluginDAOManagers.put(tenantId + deviceType, pluginDAOManager); } } } @Override public DeviceTypePluginDAOManager getPluginDAOManager(String deviceType) { - return pluginDAOManagers.get(deviceType); + int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); + if (pluginDAOManagers.containsKey(tenantId + deviceType)) { + if (log.isDebugEnabled()) { + log.debug("Retrieving DeviceTypePluginDAOManager against tenant id " + tenantId + + " and device type: " + deviceType); + } + return pluginDAOManagers.get(tenantId + deviceType); + } else { + String msg = "DeviceTypePluginDAOManager could not be found against tenant id " + tenantId + + " and device type: " + deviceType; + log.error(msg); + throw new DeviceTypePluginExtensionException(msg); + } } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/exception/DeviceTypePluginExtensionException.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/exception/DeviceTypePluginExtensionException.java new file mode 100644 index 0000000000..7afbd12cd2 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/exception/DeviceTypePluginExtensionException.java @@ -0,0 +1,12 @@ +package org.wso2.carbon.device.mgt.extensions.device.type.template.exception; + +public class DeviceTypePluginExtensionException extends RuntimeException { + + public DeviceTypePluginExtensionException(String msg) { + super(msg); + } + + public DeviceTypePluginExtensionException(String msg, Throwable cause) { + super(msg, cause); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/spi/DeviceTypePluginExtensionService.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/spi/DeviceTypePluginExtensionService.java index 3c57300cec..26aaf481e2 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/spi/DeviceTypePluginExtensionService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/spi/DeviceTypePluginExtensionService.java @@ -26,14 +26,14 @@ import org.wso2.carbon.device.mgt.extensions.device.type.template.dao.DeviceType public interface DeviceTypePluginExtensionService { /** - * Save device type specific pluginDAOManager in a HashMap + * Save device type specific DeviceTypePluginDAOManager in a HashMap againast tenant ID and device type * @param deviceType - Type of the device (i.e; android, ios, windows) * @param pluginDAOManager - Device type plugin DAO manager instance to be saved against device type */ void addPluginDAOManager(String deviceType, DeviceTypePluginDAOManager pluginDAOManager); /** - * Retrieve the DeviceTypePluginDAOManager instance given the device type + * Retrieve the DeviceTypePluginDAOManager instance against tenant ID and given device type * @param deviceType - Type of the device (i.e; android, ios, windows) * @return an Instance of {@link DeviceTypePluginDAOManager} */ From 4a58aea2d05fc738eb9ca96c710889c7fdcb6758 Mon Sep 17 00:00:00 2001 From: Saad Sahibjan Date: Mon, 19 Aug 2019 13:54:19 +0530 Subject: [PATCH 28/34] Handle exception and log error messages related to DeviceTypeDAOHandler --- .../type/template/DeviceTypeManager.java | 11 ++++- .../DeviceTypePluginExtensionServiceImpl.java | 23 ++++++---- .../template/dao/DeviceTypeDAOHandler.java | 46 +++++++++++++------ .../DeviceTypePluginExtensionException.java | 2 +- .../spi/DeviceTypePluginExtensionService.java | 8 +++- 5 files changed, 61 insertions(+), 29 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManager.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManager.java index 1169d7eebf..4e60210424 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManager.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypeManager.java @@ -228,7 +228,14 @@ public class DeviceTypeManager implements DeviceManager { if (deviceTypePluginDAOManager != null) { DeviceTypePluginExtensionService deviceTypeManagerExtensionService = new DeviceTypePluginExtensionServiceImpl(); - deviceTypeManagerExtensionService.addPluginDAOManager(deviceType, deviceTypePluginDAOManager); + try { + deviceTypeManagerExtensionService.addPluginDAOManager(deviceType, deviceTypePluginDAOManager); + } catch (DeviceTypePluginExtensionException e) { + String msg = "Error occurred while saving DeviceTypePluginDAOManager for device type: " + + deviceType; + log.error(msg); + throw new DeviceTypeDeployerPayloadException(msg); + } } else { log.warn("Could not save DeviceTypePluginDAOManager for device type: " + deviceType + " since DeviceTypePluginDAOManager is null."); @@ -236,7 +243,7 @@ public class DeviceTypeManager implements DeviceManager { } else { String msg = "Could not save DeviceTypePluginDAOManager since device type is null or empty."; log.error(msg); - throw new DeviceTypePluginExtensionException(msg); + throw new DeviceTypeDeployerPayloadException(msg); } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypePluginExtensionServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypePluginExtensionServiceImpl.java index bfe01098b6..e32c9e2d57 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypePluginExtensionServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/DeviceTypePluginExtensionServiceImpl.java @@ -34,21 +34,26 @@ public class DeviceTypePluginExtensionServiceImpl implements DeviceTypePluginExt private static volatile Map pluginDAOManagers = new HashMap<>(); @Override - public void addPluginDAOManager(String deviceType, DeviceTypePluginDAOManager pluginDAOManager) { + public void addPluginDAOManager(String deviceType, DeviceTypePluginDAOManager pluginDAOManager) + throws DeviceTypePluginExtensionException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); - if (pluginDAOManager != null) { - if (!pluginDAOManagers.containsKey(tenantId + deviceType)) { - if (log.isDebugEnabled()) { - log.debug("Saving DeviceTypePluginDAOManager against tenant id " + tenantId + - " and device type: " + deviceType); - } - pluginDAOManagers.put(tenantId + deviceType, pluginDAOManager); + if (pluginDAOManager == null) { + String msg = "Cannot save DeviceTypePluginDAOManager against tenant id " + tenantId + + " and device type: " + deviceType + " since DeviceTypePluginDAOManager is null"; + log.error(msg); + throw new DeviceTypePluginExtensionException(msg); + } + if (!pluginDAOManagers.containsKey(tenantId + deviceType)) { + if (log.isDebugEnabled()) { + log.debug("Saving DeviceTypePluginDAOManager against tenant id " + tenantId + + " and device type: " + deviceType); } + pluginDAOManagers.put(tenantId + deviceType, pluginDAOManager); } } @Override - public DeviceTypePluginDAOManager getPluginDAOManager(String deviceType) { + public DeviceTypePluginDAOManager getPluginDAOManager(String deviceType) throws DeviceTypePluginExtensionException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); if (pluginDAOManagers.containsKey(tenantId + deviceType)) { if (log.isDebugEnabled()) { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypeDAOHandler.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypeDAOHandler.java index edbbba52c6..417d078868 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypeDAOHandler.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/dao/DeviceTypeDAOHandler.java @@ -49,7 +49,9 @@ public class DeviceTypeDAOHandler { Context ctx = new InitialContext(); dataSource = (DataSource) ctx.lookup(datasourceName); } catch (NamingException e) { - throw new DeviceTypeDeployerPayloadException("Error while looking up the data source: " + datasourceName, e); + String msg = "Error while looking up the data source: " + datasourceName; + log.error(msg, e); + throw new DeviceTypeDeployerPayloadException(msg, e); } } @@ -57,12 +59,16 @@ public class DeviceTypeDAOHandler { try { Connection conn = currentConnection.get(); if (conn != null) { - throw new IllegalTransactionStateException("Database connection has already been obtained."); + String msg = "Database connection has already been obtained."; + log.error(msg); + throw new IllegalTransactionStateException(msg); } conn = dataSource.getConnection(); currentConnection.set(conn); } catch (SQLException e) { - throw new DeviceTypeMgtPluginException("Failed to get a database connection.", e); + String msg = "Failed to get a database connection."; + log.error(msg, e); + throw new DeviceTypeMgtPluginException(msg, e); } } @@ -72,7 +78,9 @@ public class DeviceTypeDAOHandler { conn.setAutoCommit(false); currentConnection.set(conn); } catch (SQLException e) { - throw new DeviceTypeMgtPluginException("Error occurred while retrieving datasource connection", e); + String msg = "Error occurred while retrieving datasource connection"; + log.error(msg, e); + throw new DeviceTypeMgtPluginException(msg, e); } } @@ -81,7 +89,9 @@ public class DeviceTypeDAOHandler { try { currentConnection.set(dataSource.getConnection()); } catch (SQLException e) { - throw new DeviceTypeMgtPluginException("Error occurred while retrieving data source connection", e); + String msg = "Error occurred while retrieving data source connection"; + log.error(msg, e); + throw new DeviceTypeMgtPluginException(msg, e); } } return currentConnection.get(); @@ -90,25 +100,28 @@ public class DeviceTypeDAOHandler { public void commitTransaction() { Connection conn = currentConnection.get(); if (conn == null) { - throw new IllegalStateException("No connection is associated with the current transaction. " + - "This might have ideally been caused by not properly initiating the " + - "transaction via 'beginTransaction'/'openConnection' methods"); + String msg = "No connection is associated with the current transaction. This might have ideally been " + + "caused by not properly initiating the transaction via " + + "'beginTransaction'/'openConnection' methods"; + log.error(msg); + throw new IllegalStateException(msg); } try { conn.commit(); } catch (SQLException e) { - log.error("Error occurred while committing the transaction.", e); + String msg = "Error occurred while committing the transaction."; + log.error(msg, e); } } public void closeConnection() { - Connection con = currentConnection.get(); if (con != null) { try { con.close(); } catch (SQLException e) { - log.error("Error occurred while close the connection"); + String msg = "Error occurred while close the connection"; + log.error(msg, e); } } currentConnection.remove(); @@ -117,14 +130,17 @@ public class DeviceTypeDAOHandler { public void rollbackTransaction() { Connection conn = currentConnection.get(); if (conn == null) { - throw new IllegalStateException("No connection is associated with the current transaction. " + - "This might have ideally been caused by not properly initiating the " + - "transaction via 'beginTransaction'/'openConnection' methods"); + String msg = "No connection is associated with the current transaction. This might have ideally been " + + "caused by not properly initiating the transaction via " + + "'beginTransaction'/'openConnection' methods"; + log.error(msg); + throw new IllegalStateException(msg); } try { conn.rollback(); } catch (SQLException e) { - log.error("Error occurred while roll-backing the transaction.", e); + String msg = "Error occurred while roll-backing the transaction."; + log.error(msg, e); } } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/exception/DeviceTypePluginExtensionException.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/exception/DeviceTypePluginExtensionException.java index 7afbd12cd2..b0603f43bf 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/exception/DeviceTypePluginExtensionException.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/exception/DeviceTypePluginExtensionException.java @@ -1,6 +1,6 @@ package org.wso2.carbon.device.mgt.extensions.device.type.template.exception; -public class DeviceTypePluginExtensionException extends RuntimeException { +public class DeviceTypePluginExtensionException extends Exception { public DeviceTypePluginExtensionException(String msg) { super(msg); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/spi/DeviceTypePluginExtensionService.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/spi/DeviceTypePluginExtensionService.java index 26aaf481e2..f91ed2e985 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/spi/DeviceTypePluginExtensionService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/spi/DeviceTypePluginExtensionService.java @@ -18,6 +18,7 @@ package org.wso2.carbon.device.mgt.extensions.spi; import org.wso2.carbon.device.mgt.extensions.device.type.template.dao.DeviceTypePluginDAOManager; +import org.wso2.carbon.device.mgt.extensions.device.type.template.exception.DeviceTypePluginExtensionException; /** * This represents the device type plugin extension service which can be used by any device type plugin implementation @@ -29,13 +30,16 @@ public interface DeviceTypePluginExtensionService { * Save device type specific DeviceTypePluginDAOManager in a HashMap againast tenant ID and device type * @param deviceType - Type of the device (i.e; android, ios, windows) * @param pluginDAOManager - Device type plugin DAO manager instance to be saved against device type + * @throws DeviceTypePluginExtensionException when pluginDAOManager is null */ - void addPluginDAOManager(String deviceType, DeviceTypePluginDAOManager pluginDAOManager); + void addPluginDAOManager(String deviceType, DeviceTypePluginDAOManager pluginDAOManager) + throws DeviceTypePluginExtensionException; /** * Retrieve the DeviceTypePluginDAOManager instance against tenant ID and given device type * @param deviceType - Type of the device (i.e; android, ios, windows) * @return an Instance of {@link DeviceTypePluginDAOManager} + * @throws DeviceTypePluginExtensionException when pluginDAOManager cannot be found */ - DeviceTypePluginDAOManager getPluginDAOManager(String deviceType); + DeviceTypePluginDAOManager getPluginDAOManager(String deviceType) throws DeviceTypePluginExtensionException; } From a3f44b43b4cdf54750bb82350d1ea4c92fbab28e Mon Sep 17 00:00:00 2001 From: Pahansith Date: Wed, 7 Aug 2019 10:26:02 +0530 Subject: [PATCH 29/34] Add configuration retrieve endpoint --- .../pom.xml | 277 ++++++++++++++++++ .../mgt/config/jaxrs/ApiOriginFilter.java | 50 ++++ .../mgt/config/jaxrs/beans/ErrorListItem.java | 77 +++++ .../mgt/config/jaxrs/beans/ErrorResponse.java | 150 ++++++++++ .../jaxrs/common/GsonMessageBodyHandler.java | 97 ++++++ .../DeviceManagementConfigService.java | 134 +++++++++ .../DeviceManagementConfigServiceImpl.java | 151 ++++++++++ .../config/jaxrs/util/DeviceMgtAPIUtils.java | 43 +++ .../src/main/webapp/META-INF/permissions.xml | 39 +++ .../webapp/META-INF/webapp-classloading.xml | 35 +++ .../src/main/webapp/WEB-INF/cxf-servlet.xml | 38 +++ .../src/main/webapp/WEB-INF/web.xml | 126 ++++++++ .../src/test/resources/testng.xml | 23 ++ .../common/AppRegistrationCredentials.java | 43 +++ .../mgt/common/ApplicationRegistration.java | 65 ++++ .../ApplicationRegistrationException.java | 46 +++ .../mgt/common/InvalidArgumentException.java | 46 +++ .../mgt/AmbiguousConfigurationException.java | 25 ++ .../mgt/DeviceConfiguration.java | 111 +++++++ .../configuration/mgt/DevicePropertyInfo.java | 63 ++++ .../mgt/core/DeviceManagementConstants.java | 15 + .../carbon/device/mgt/core/dao/DeviceDAO.java | 10 + .../core/dao/DeviceNotFoundDAOException.java | 28 ++ .../core/dao/impl/AbstractDeviceDAOImpl.java | 63 +++- .../DeviceManagementProviderService.java | 20 ++ .../DeviceManagementProviderServiceImpl.java | 88 ++++++ .../mgt/core/util/DeviceManagerUtil.java | 118 ++++++++ components/device-mgt/pom.xml | 1 + .../org.wso2.carbon.policy.mgt.core/pom.xml | 6 +- .../pom.xml | 23 ++ .../src/main/resources/p2.inf | 3 +- 31 files changed, 2011 insertions(+), 3 deletions(-) create mode 100644 components/device-mgt/io.entgra.carbon.device.mgt.config.api/pom.xml create mode 100644 components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/ApiOriginFilter.java create mode 100644 components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/beans/ErrorListItem.java create mode 100644 components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/beans/ErrorResponse.java create mode 100644 components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/common/GsonMessageBodyHandler.java create mode 100644 components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/DeviceManagementConfigService.java create mode 100644 components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/impl/DeviceManagementConfigServiceImpl.java create mode 100644 components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/util/DeviceMgtAPIUtils.java create mode 100644 components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/META-INF/permissions.xml create mode 100644 components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/META-INF/webapp-classloading.xml create mode 100644 components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/WEB-INF/cxf-servlet.xml create mode 100644 components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/WEB-INF/web.xml create mode 100644 components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/test/resources/testng.xml create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/AppRegistrationCredentials.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/ApplicationRegistration.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/ApplicationRegistrationException.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/InvalidArgumentException.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/configuration/mgt/AmbiguousConfigurationException.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/configuration/mgt/DeviceConfiguration.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/configuration/mgt/DevicePropertyInfo.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceNotFoundDAOException.java diff --git a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/pom.xml b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/pom.xml new file mode 100644 index 0000000000..2cbb2505e5 --- /dev/null +++ b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/pom.xml @@ -0,0 +1,277 @@ + + + + + + + device-mgt + org.wso2.carbon.devicemgt + 3.2.9-SNAPSHOT + ../pom.xml + + + 4.0.0 + io.entgra.carbon.device.mgt.config.api + war + Entgra Carbon - Mobile Device Management Configuration API + Entgra Carbon - Mobile Device Management Configuration API + https://entgra.io + + + + + maven-compiler-plugin + + 1.8 + 1.8 + + + + maven-war-plugin + + WEB-INF/lib/*cxf*.jar + api#device-mgt-config#v1.0 + + + + org.jacoco + jacoco-maven-plugin + + ${basedir}/target/coverage-reports/jacoco-unit.exec + + + + jacoco-initialize + + prepare-agent + + + + jacoco-site + test + + report + + + ${basedir}/target/coverage-reports/jacoco-unit.exec + ${basedir}/target/coverage-reports/site + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + file:src/test/resources/log4j.properties + + + src/test/resources/testng.xml + + + + + + + + + deploy + + compile + + + org.apache.maven.plugins + maven-antrun-plugin + 1.7 + + + compile + + run + + + + + + + + + + + + + + + + + + client + + test + + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + + test + + java + + + + + + + + + + + + org.apache.cxf + cxf-rt-frontend-jaxrs + provided + + + org.apache.cxf + cxf-rt-transports-http + provided + + + javax.ws.rs + jsr311-api + provided + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.core + provided + + + org.apache.axis2.wso2 + axis2-client + + + org.mockito + mockito-core + + + javassist + javassist + + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.certificate.mgt.core + provided + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.core + + + org.wso2.carbon.identity.framework + org.wso2.carbon.user.mgt + + + + + io.swagger + swagger-annotations + + + io.swagger + swagger-core + + + com.fasterxml.jackson.module + jackson-module-jaxb-annotations + + + org.slf4j + slf4j-api + + + org.wso2.orbit.com.fasterxml.jackson.core + jackson-core + + + + + io.swagger + swagger-jaxrs + + + com.fasterxml.jackson.module + jackson-module-jaxb-annotations + + + org.slf4j + slf4j-api + + + org.wso2.orbit.com.fasterxml.jackson.core + jackson-core + + + + + javax.servlet + servlet-api + provided + + + org.wso2.carbon.devicemgt + org.wso2.carbon.apimgt.annotations + provided + + + javax.ws.rs + javax.ws.rs-api + + + org.powermock + powermock-module-testng + test + + + org.powermock + powermock-api-mockito + test + + + org.wso2.carbon.devicemgt + org.wso2.carbon.identity.jwt.client.extension + provided + + + org.wso2.tomcat + tomcat + + + org.wso2.tomcat + tomcat-servlet-api + + + + + diff --git a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/ApiOriginFilter.java b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/ApiOriginFilter.java new file mode 100644 index 0000000000..ae3103866f --- /dev/null +++ b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/ApiOriginFilter.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package io.entgra.carbon.device.mgt.config.jaxrs; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class ApiOriginFilter implements Filter { + + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + HttpServletResponse res = (HttpServletResponse) response; + res.addHeader("Access-Control-Allow-Origin", "*"); + res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT"); + res.addHeader("Access-Control-Allow-Headers", "Content-Type"); + chain.doFilter(request, response); + } + + public void destroy() { + //do nothing + } + + public void init(FilterConfig filterConfig) throws ServletException { + //do nothing + } + +} diff --git a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/beans/ErrorListItem.java b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/beans/ErrorListItem.java new file mode 100644 index 0000000000..34939b3859 --- /dev/null +++ b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/beans/ErrorListItem.java @@ -0,0 +1,77 @@ +/* + * 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 io.entgra.carbon.device.mgt.config.jaxrs.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.NotNull; + +@ApiModel(description = "") +public class ErrorListItem { + + @NotNull + private String code = null; + + @NotNull + private String message = null; + + @ApiModelProperty(required = true, value = "") + @JsonProperty("code") + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public ErrorListItem() {} + + public ErrorListItem(String code, String msg) { + this.code = code; + this.message = msg; + } + + /** + * Description about individual errors occurred + **/ + @ApiModelProperty(required = true, value = "Description about individual errors occurred") + @JsonProperty("message") + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("errorItem {\n"); + + sb.append(" code: ").append(code).append("\n"); + sb.append(" message: ").append(message).append("\n"); + sb.append("}\n"); + return sb.toString(); + } + +} diff --git a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/beans/ErrorResponse.java b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/beans/ErrorResponse.java new file mode 100644 index 0000000000..8a6cf834cc --- /dev/null +++ b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/beans/ErrorResponse.java @@ -0,0 +1,150 @@ +/* + * 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 io.entgra.carbon.device.mgt.config.jaxrs.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.ArrayList; +import java.util.List; + +@ApiModel(description = "") +public class ErrorResponse { + + private Long code = null; + private String message = null; + private String description = null; + private String moreInfo = null; + private List errorItems = new ArrayList<>(); + + public ErrorResponse() {} + + @JsonProperty(value = "code") + @ApiModelProperty(required = true, value = "") + public Long getCode() { + return code; + } + + public void setCode(Long code) { + this.code = code; + } + + @JsonProperty(value = "message") + @ApiModelProperty(required = true, value = "ErrorResponse message.") + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + @JsonProperty(value = "description") + @ApiModelProperty(value = "A detail description about the error message.") + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @JsonProperty(value = "moreInfo") + @ApiModelProperty(value = "Preferably an url with more details about the error.") + public String getMoreInfo() { + return moreInfo; + } + + public void setMoreInfo(String moreInfo) { + this.moreInfo = moreInfo; + } + + public void addErrorListItem(ErrorListItem item) { + this.errorItems.add(item); + } + + /** + * If there are more than one error list them out. For example, list out validation errors by each field. + */ + @JsonProperty(value = "errorItems") + @ApiModelProperty(value = "If there are more than one error list them out. \n" + + "For example, list out validation errors by each field.") + public List getErrorItems() { + return errorItems; + } + + public void setErrorItems(List error) { + this.errorItems = error; + } + + public static class ErrorResponseBuilder { + + private Long code = null; + private String message = null; + private String description = null; + private String moreInfo = null; + private List error; + + + public ErrorResponseBuilder() { + this.error = new ArrayList<>(); + } + + public ErrorResponseBuilder setCode(long code) { + this.code = code; + return this; + } + + public ErrorResponseBuilder setMessage(String message) { + this.message = message; + return this; + } + + public ErrorResponseBuilder setDescription(String description) { + this.description = description; + return this; + } + + public ErrorResponseBuilder setMoreInfo(String moreInfo) { + this.moreInfo = moreInfo; + return this; + } + + public ErrorResponseBuilder addErrorItem(String code, String msg) { + ErrorListItem item = new ErrorListItem(); + item.setCode(code); + item.setMessage(msg); + this.error.add(item); + return this; + } + + public ErrorResponse build() { + ErrorResponse errorResponse = new ErrorResponse(); + errorResponse.setCode(code); + errorResponse.setMessage(message); + errorResponse.setErrorItems(error); + errorResponse.setDescription(description); + errorResponse.setMoreInfo(moreInfo); + return errorResponse; + } + } +} + + diff --git a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/common/GsonMessageBodyHandler.java b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/common/GsonMessageBodyHandler.java new file mode 100644 index 0000000000..484c8df866 --- /dev/null +++ b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/common/GsonMessageBodyHandler.java @@ -0,0 +1,97 @@ +/* + * 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 io.entgra.carbon.device.mgt.config.jaxrs.common; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import javax.ws.rs.Consumes; +import javax.ws.rs.Produces; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.ext.MessageBodyReader; +import javax.ws.rs.ext.MessageBodyWriter; +import javax.ws.rs.ext.Provider; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +import static javax.ws.rs.core.MediaType.APPLICATION_JSON; + +@Provider +@Produces(APPLICATION_JSON) +@Consumes(APPLICATION_JSON) +public class GsonMessageBodyHandler implements MessageBodyWriter, MessageBodyReader { + + public static final String DATE_FORMAT = "EEE, d MMM yyyy HH:mm:ss Z"; + private Gson gson; + private static final String UTF_8 = "UTF-8"; + + public boolean isReadable(Class aClass, Type type, Annotation[] annotations, MediaType mediaType) { + return true; + } + + private Gson getGson() { + if (gson == null) { + final GsonBuilder gsonBuilder = new GsonBuilder(); + gson = gsonBuilder.setDateFormat(DATE_FORMAT).create(); + } + return gson; + } + + public Object readFrom(Class objectClass, Type type, Annotation[] annotations, + MediaType mediaType, MultivaluedMap stringStringMultivaluedMap, + InputStream entityStream) + throws IOException, WebApplicationException { + + InputStreamReader reader = new InputStreamReader(entityStream, "UTF-8"); + + try { + return getGson().fromJson(reader, type); + } finally { + reader.close(); + } + } + + public boolean isWriteable(Class aClass, Type type, Annotation[] annotations, MediaType mediaType) { + return true; + } + + public long getSize(Object o, Class aClass, Type type, Annotation[] annotations, MediaType mediaType) { + return -1; + } + + public void writeTo(Object object, Class aClass, Type type, Annotation[] annotations, + MediaType mediaType, MultivaluedMap stringObjectMultivaluedMap, + OutputStream entityStream) + throws IOException, WebApplicationException { + + OutputStreamWriter writer = new OutputStreamWriter(entityStream, UTF_8); + try { + getGson().toJson(object, type, writer); + } finally { + writer.close(); + } + } +} diff --git a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/DeviceManagementConfigService.java b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/DeviceManagementConfigService.java new file mode 100644 index 0000000000..5c53d8129a --- /dev/null +++ b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/DeviceManagementConfigService.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.entgra.carbon.device.mgt.config.jaxrs.service; + +import io.entgra.carbon.device.mgt.config.jaxrs.beans.ErrorResponse; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.Extension; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.Info; +import io.swagger.annotations.ResponseHeader; +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.configuration.mgt.DeviceConfiguration; +import org.wso2.carbon.device.mgt.common.search.PropertyMap; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +@SwaggerDefinition( + info = @Info( + version = "1.0.0", + title = "", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "DeviceManagementConfiguration"), + @ExtensionProperty(name = "context", + value = "/api/device-mgt-config/v1.0/configurations"), + }) + } + ), + tags = { + @Tag(name = "device_management", description = "") + } +) +@Path("/configurations") +@Api(value = "Device Management Configuration") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@Scopes(scopes = { + @Scope( + name = "View configurations", + description = "", + key = "perm:view-configuration", + permissions = {"/device-mgt/platform-configurations/view"} + ) +} +) +public interface DeviceManagementConfigService { + + @GET + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "POST", + value = "Getting General device Configurations", + notes = "This API is responsible for send device configuration data to an IOT device when the " + + "device starts provisioning", + tags = "Device Management Configuration" + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the device configurations.", + response = DeviceConfiguration.class, + responseContainer = "List", + 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 has been modified " + + "the last time.Used by caches, or in " + + "conditional requests."), + } + ), + @ApiResponse( + code = 400, + message = "Bad request.\n The request contains invalid parameters"), + @ApiResponse( + code = 401, + message = "Unauthorized.\n The requested is not authorized"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while " + + "fetching device configurations.", + response = ErrorResponse.class) + }) + Response getConfiguration(@ApiParam( + name = "token", + value = "value for identify an already enrolled and authorized device", + required = true) + @HeaderParam("token") + String token, + @ApiParam( + name = "properties", + value = "The properties list using for query a device", + required = true) + @QueryParam("properties") + String properties); +} diff --git a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/impl/DeviceManagementConfigServiceImpl.java b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/impl/DeviceManagementConfigServiceImpl.java new file mode 100644 index 0000000000..ab00cfcfff --- /dev/null +++ b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/impl/DeviceManagementConfigServiceImpl.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package io.entgra.carbon.device.mgt.config.jaxrs.service.impl; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.entgra.carbon.device.mgt.config.jaxrs.beans.ErrorResponse; +import io.entgra.carbon.device.mgt.config.jaxrs.service.DeviceManagementConfigService; +import io.entgra.carbon.device.mgt.config.jaxrs.util.DeviceMgtAPIUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.common.AppRegistrationCredentials; +import org.wso2.carbon.device.mgt.common.ApplicationRegistrationException; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.DeviceNotFoundException; +import org.wso2.carbon.device.mgt.common.configuration.mgt.AmbiguousConfigurationException; +import org.wso2.carbon.device.mgt.common.configuration.mgt.DeviceConfiguration; +import org.wso2.carbon.device.mgt.core.DeviceManagementConstants; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil; +import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo; +import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.io.IOException; +import java.util.Map; + +@Path("/configurations") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class DeviceManagementConfigServiceImpl implements DeviceManagementConfigService { + + private static final Log log = LogFactory.getLog(DeviceManagementConfigServiceImpl.class); + + @Override + @GET + public Response getConfiguration(@HeaderParam("token") String token, + @QueryParam("properties") String properties) { + DeviceManagementProviderService dms = DeviceMgtAPIUtils.getDeviceManagementService(); + try { + if (token == null || token.isEmpty()) { + String msg = "No valid token property found"; + log.error(msg); + return Response.status(Response.Status.UNAUTHORIZED).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build() + ).build(); + } + + if (properties == null || properties.isEmpty()) { + String msg = "Devices configuration retrieval criteria cannot be null or empty."; + log.error(msg); + return Response.status(Response.Status.BAD_REQUEST).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build() + ).build(); + } + + ObjectMapper mapper = new ObjectMapper(); + properties = parseUriParamsToJSON(properties); + Map deviceProps = mapper.readValue(properties, + new TypeReference>() { + }); + deviceProps.put("token", token); + DeviceConfiguration devicesConfiguration = + dms.getDeviceConfiguration(deviceProps); + setAccessTokenToDeviceConfigurations(devicesConfiguration); + return Response.status(Response.Status.OK).entity(devicesConfiguration).build(); + } catch (DeviceManagementException e) { + String msg = "Error occurred while retrieving configurations"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (DeviceNotFoundException e) { + log.error(e.getMessage(), e); + return Response.status(Response.Status.BAD_REQUEST).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(e.getMessage()).build()).build(); + } catch (AmbiguousConfigurationException e) { + String msg = "Configurations are ambiguous"; + log.error(msg, e); + return Response.status(Response.Status.BAD_REQUEST).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (JsonParseException | JsonMappingException e) { + String msg = "Malformed device property structure"; + log.error(msg.concat(" ").concat(properties), e); + return Response.status(Response.Status.BAD_REQUEST).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } catch (IOException e) { + String msg = "Error occurred while parsing query param JSON data"; + log.error(msg.concat(" ").concat(properties), e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build(); + } + } + + private String parseUriParamsToJSON(String uriParams) { + uriParams = uriParams.replaceAll("=", "\":\""); + uriParams = uriParams.replaceAll("&", "\",\""); + return "{\"" + uriParams + "\"}"; + } + + private void setAccessTokenToDeviceConfigurations(DeviceConfiguration devicesConfiguration) + throws DeviceManagementException { + try { + AppRegistrationCredentials credentials = + DeviceManagerUtil.getApplicationRegistrationCredentials( + System.getProperty(DeviceManagementConstants + .ConfigurationManagement.IOT_GATEWAY_HOST), + System.getProperty(DeviceManagementConstants + .ConfigurationManagement.IOT_GATEWAY_HTTPS_PORT), + DeviceManagementConstants.ConfigurationManagement.ADMIN_CREDENTIALS); + AccessTokenInfo accessTokenForAdmin = DeviceManagerUtil.getAccessTokenForDeviceOwner( + DeviceManagementConstants.ConfigurationManagement.SCOPES_FOR_TOKEN, + credentials.getClient_id(), credentials.getClient_secret(), + devicesConfiguration.getDeviceOwner()); + devicesConfiguration.setAccessToken(accessTokenForAdmin.getAccessToken()); + devicesConfiguration.setRefreshToken(accessTokenForAdmin.getRefreshToken()); + } catch (ApplicationRegistrationException e) { + String msg = "Failure on retrieving application registration"; + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } catch (JWTClientException e) { + String msg = "Error occurred while creating JWT client : " + e.getMessage(); + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } + } + +} diff --git a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/util/DeviceMgtAPIUtils.java b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/util/DeviceMgtAPIUtils.java new file mode 100644 index 0000000000..874a644bba --- /dev/null +++ b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/util/DeviceMgtAPIUtils.java @@ -0,0 +1,43 @@ +/* + * 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 io.entgra.carbon.device.mgt.config.jaxrs.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; + +/** + * MDMAPIUtils class provides utility function used by CDM REST-API classes. + */ +public class DeviceMgtAPIUtils { + private static Log log = LogFactory.getLog(DeviceMgtAPIUtils.class); + + public static DeviceManagementProviderService getDeviceManagementService() { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + DeviceManagementProviderService deviceManagementProviderService = + (DeviceManagementProviderService) ctx.getOSGiService(DeviceManagementProviderService.class, null); + if (deviceManagementProviderService == null) { + String msg = "DeviceImpl Management provider service has not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + return deviceManagementProviderService; + } +} diff --git a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/META-INF/permissions.xml b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/META-INF/permissions.xml new file mode 100644 index 0000000000..8b5c48b01c --- /dev/null +++ b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/META-INF/permissions.xml @@ -0,0 +1,39 @@ + + + + + + + + + Device Management Configuration + /device-mgt-config + / + GET + + diff --git a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/META-INF/webapp-classloading.xml b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/META-INF/webapp-classloading.xml new file mode 100644 index 0000000000..01aceabde5 --- /dev/null +++ b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/META-INF/webapp-classloading.xml @@ -0,0 +1,35 @@ + + + + + + + + + false + + + CXF,Carbon + diff --git a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/WEB-INF/cxf-servlet.xml b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/WEB-INF/cxf-servlet.xml new file mode 100644 index 0000000000..e7426237cb --- /dev/null +++ b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/WEB-INF/cxf-servlet.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/WEB-INF/web.xml b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..0c2afe4a6f --- /dev/null +++ b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,126 @@ + + + + Device-Config-Webapp + + JAX-WS/JAX-RS Device Configuration Endpoint + JAX-WS/JAX-RS Servlet + CXFServlet + + org.apache.cxf.transport.servlet.CXFServlet + + + + swagger.security.filter + ApiAuthorizationFilterImpl + + 1 + + + CXFServlet + /* + + + 60 + + + + doAuthentication + true + + + + nonSecuredEndPoints + + /api/device-mgt-config/v1.0/configurations + + + + + + managed-api-enabled + true + + + managed-api-owner + admin + + + isSharedWithAllTenants + true + + + + + + DeviceMgt-Admin + /* + + + CONFIDENTIAL + + + + + ApiOriginFilter + io.entgra.carbon.device.mgt.config.jaxrs.ApiOriginFilter + + + + HttpHeaderSecurityFilter + org.apache.catalina.filters.HttpHeaderSecurityFilter + + hstsEnabled + false + + + + + ContentTypeBasedCachePreventionFilter + org.wso2.carbon.ui.filters.cache.ContentTypeBasedCachePreventionFilter + + patterns + text/html" ,application/json" ,text/plain + + + filterAction + enforce + + + httpHeaders + Cache-Control: no-store, no-cache, must-revalidate, private + + + + + HttpHeaderSecurityFilter + /* + + + + ContentTypeBasedCachePreventionFilter + /* + + + + ApiOriginFilter + /* + + + \ No newline at end of file diff --git a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/test/resources/testng.xml b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/test/resources/testng.xml new file mode 100644 index 0000000000..5fe82227d3 --- /dev/null +++ b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/test/resources/testng.xml @@ -0,0 +1,23 @@ + + + + + + + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/AppRegistrationCredentials.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/AppRegistrationCredentials.java new file mode 100644 index 0000000000..191ee0d3d4 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/AppRegistrationCredentials.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.common; + +/** + * Wrap application registration response payload + */ +public class AppRegistrationCredentials { + private String client_id; + private String client_secret; + + public String getClient_id() { + return client_id; + } + + public void setClient_id(String client_id) { + this.client_id = client_id; + } + + public String getClient_secret() { + return client_secret; + } + + public void setClient_secret(String client_secret) { + this.client_secret = client_secret; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/ApplicationRegistration.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/ApplicationRegistration.java new file mode 100644 index 0000000000..13d6c9d53c --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/ApplicationRegistration.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.common; + +import java.util.List; + +/** + * This class is use to wrap and send + * Application registration data to the API publisher + * Use only for application registration doing inside the IoTs + */ +public class ApplicationRegistration { + private String applicationName; + private List tags; + private boolean isAllowedToAllDomains; + private long validityPeriod; + + public String getApplicationName() { + return applicationName; + } + + public void setApplicationName(String applicationName) { + this.applicationName = applicationName; + } + + public List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags = tags; + } + + public boolean isAllowedToAllDomains() { + return isAllowedToAllDomains; + } + + public void setAllowedToAllDomains(boolean allowedToAllDomains) { + isAllowedToAllDomains = allowedToAllDomains; + } + + public long getValidityPeriod() { + return validityPeriod; + } + + public void setValidityPeriod(long validityPeriod) { + this.validityPeriod = validityPeriod; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/ApplicationRegistrationException.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/ApplicationRegistrationException.java new file mode 100644 index 0000000000..6ccfe677ef --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/ApplicationRegistrationException.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.common; + +/** + * Throw this if any errors throw when the application registration API calling + */ +public class ApplicationRegistrationException extends Exception { + private static final long serialVersionUID = 4718132518977041928L; + + public ApplicationRegistrationException(String msg, Exception nestedEx) { + super(msg, nestedEx); + } + + public ApplicationRegistrationException(String message, Throwable cause) { + super(message, cause); + } + + public ApplicationRegistrationException(String msg) { + super(msg); + } + + public ApplicationRegistrationException() { + super(); + } + + public ApplicationRegistrationException(Throwable cause) { + super(cause); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/InvalidArgumentException.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/InvalidArgumentException.java new file mode 100644 index 0000000000..194f971318 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/InvalidArgumentException.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.common; + +/** + * Throws if any arguments send to an API is wrong or invalid + */ +public class InvalidArgumentException extends Exception { + private static final long serialVersionUID = -2365244687985953509L; + + public InvalidArgumentException(String msg, Exception nestedEx) { + super(msg, nestedEx); + } + + public InvalidArgumentException(String message, Throwable cause) { + super(message, cause); + } + + public InvalidArgumentException(String msg) { + super(msg); + } + + public InvalidArgumentException() { + super(); + } + + public InvalidArgumentException(Throwable cause) { + super(cause); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/configuration/mgt/AmbiguousConfigurationException.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/configuration/mgt/AmbiguousConfigurationException.java new file mode 100644 index 0000000000..a18f437528 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/configuration/mgt/AmbiguousConfigurationException.java @@ -0,0 +1,25 @@ +package org.wso2.carbon.device.mgt.common.configuration.mgt; + +public class AmbiguousConfigurationException extends Exception{ + private static final long serialVersionUID = 7039039961721642766L; + + public AmbiguousConfigurationException(String msg, Exception nestedEx) { + super(msg, nestedEx); + } + + public AmbiguousConfigurationException(String message, Throwable cause) { + super(message, cause); + } + + public AmbiguousConfigurationException(String msg) { + super(msg); + } + + public AmbiguousConfigurationException() { + super(); + } + + public AmbiguousConfigurationException(Throwable cause) { + super(cause); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/configuration/mgt/DeviceConfiguration.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/configuration/mgt/DeviceConfiguration.java new file mode 100644 index 0000000000..da39516f41 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/configuration/mgt/DeviceConfiguration.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.common.configuration.mgt; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.List; + +/** + * This class is use to wrap and send device configuration data + * to the device + */ +@ApiModel(value = "DeviceConfiguration", description = "This class carries all information related to " + + "Device configurations required to communicate with " + + "the server") +public class DeviceConfiguration { + @ApiModelProperty(name = "deviceId", value = "ID of the device", required = true) + private int deviceId; + + @ApiModelProperty(name = "deviceType", value = "Type of the device", required = true) + private String deviceType; + + @ApiModelProperty(name = "tenantDomain", value = "Tenant which the device owned") + private String tenantDomain; + + @ApiModelProperty(name = "configurationEntries", value = "Platform Configurations", required = true) + private List configurationEntries; + + @ApiModelProperty(name = "accessToken", value = "Token that can be use to communicate with the server") + private String accessToken; + + @ApiModelProperty(name = "refreshToken", value = "Token that can be use to communicate with the server") + private String refreshToken; + + @ApiModelProperty(name = "deviceOwner", value = "Owner of the selected device", required = true) + private String deviceOwner; + + public int getDeviceId() { + return deviceId; + } + + public void setDeviceId(int deviceId) { + this.deviceId = deviceId; + } + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getTenantDomain() { + return tenantDomain; + } + + public void setTenantDomain(String tenantDomain) { + this.tenantDomain = tenantDomain; + } + + public List getConfigurationEntries() { + return configurationEntries; + } + + public void setConfigurationEntries( + List configurationEntries) { + this.configurationEntries = configurationEntries; + } + + public String getAccessToken() { + return accessToken; + } + + public void setAccessToken(String accessToken) { + this.accessToken = accessToken; + } + + public String getDeviceOwner() { + return deviceOwner; + } + + public void setDeviceOwner(String deviceOwner) { + this.deviceOwner = deviceOwner; + } + + public String getRefreshToken() { + return refreshToken; + } + + public void setRefreshToken(String refreshToken) { + this.refreshToken = refreshToken; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/configuration/mgt/DevicePropertyInfo.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/configuration/mgt/DevicePropertyInfo.java new file mode 100644 index 0000000000..1af7982252 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/configuration/mgt/DevicePropertyInfo.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.device.mgt.common.configuration.mgt; + +/** + * This bean is use for retrieve and wrap device property info get from DB + */ +public class DevicePropertyInfo { + private String deviceIdentifier = "default"; + private String deviceTypeName = "default"; + private String tenantId = "default"; + + public String getDeviceIdentifier() { + return deviceIdentifier; + } + + public void setDeviceIdentifier(String deviceIdentifier) { + this.deviceIdentifier = deviceIdentifier; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof DevicePropertyInfo) { + DevicePropertyInfo devicePropertyInfo = (DevicePropertyInfo)obj; + return devicePropertyInfo.getDeviceIdentifier().equals(this.deviceIdentifier) + && devicePropertyInfo.getDeviceTypeName().equals(this.deviceTypeName) + && devicePropertyInfo.getTenantId().equals(this.tenantId); + } + return false; + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java index 57b00cb5a8..7c7f265353 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/DeviceManagementConstants.java @@ -27,6 +27,21 @@ public final class DeviceManagementConstants { public static final String DEVICE_CACHE = "DEVICE_CACHE"; public static final String ENROLLMENT_NOTIFICATION_API_ENDPOINT = "/api/device-mgt/enrollment-notification"; + public static final class ConfigurationManagement { + private ConfigurationManagement(){ + throw new AssertionError(); + } + public static final String ADMIN_CREDENTIALS = "admin:admin"; + public static final String SCOPES_FOR_TOKEN = "perm:device:operations perm:device:publish-event"; + public static final String IOT_GATEWAY_HOST = "iot.gateway.host"; + public static final String IOT_GATEWAY_HTTPS_PORT = "iot.gateway.https.port"; + public static final String MQTT_ENDPOINTS = "mqttEndpoints"; + public static final String APPLICATION_REGISTRATION_API_ENDPOINT = + "/api-application-registration/register"; + public static final String AUTHORIZATION_HEADER = "authorization"; + public static final String BASIC_AUTH = "Basic"; + + } public static final class Common { private Common() { throw new AssertionError(); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java index f62d915d1b..f824a2255b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceDAO.java @@ -40,6 +40,7 @@ import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.EnrolmentInfo; import org.wso2.carbon.device.mgt.common.EnrolmentInfo.Status; import org.wso2.carbon.device.mgt.common.PaginationRequest; +import org.wso2.carbon.device.mgt.common.configuration.mgt.DevicePropertyInfo; import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.geo.GeoCluster; import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate; @@ -190,6 +191,15 @@ public interface DeviceDAO { */ List getDeviceBasedOnDeviceProperties(Map deviceProps, int tenantId) throws DeviceManagementDAOException; + /** + * Retrieves a list of devices based on a given criteria of properties + * This will ignores the tenant and it will return devices registered under every tenants + * @param deviceProps properties by which devices need to be filtered + * @return list of devices with properties + * @throws DeviceManagementDAOException if the SQL query has failed to be executed + */ + List getDeviceBasedOnDeviceProperties(Map deviceProps) + throws DeviceManagementDAOException; /** * Retrieves properties of given device identifier diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceNotFoundDAOException.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceNotFoundDAOException.java new file mode 100644 index 0000000000..b4479ed20a --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceNotFoundDAOException.java @@ -0,0 +1,28 @@ +package org.wso2.carbon.device.mgt.core.dao; + +/** + * Throws if the querying device is not found in the DB + */ +public class DeviceNotFoundDAOException extends Exception { + private static final long serialVersionUID = 2126172787830234694L; + + public DeviceNotFoundDAOException(String msg, Exception nestedEx) { + super(msg, nestedEx); + } + + public DeviceNotFoundDAOException(String message, Throwable cause) { + super(message, cause); + } + + public DeviceNotFoundDAOException(String msg) { + super(msg); + } + + public DeviceNotFoundDAOException() { + super(); + } + + public DeviceNotFoundDAOException(Throwable cause) { + super(cause); + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java index 413e9bc56c..588f2ebd4a 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java @@ -42,6 +42,7 @@ import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.EnrolmentInfo; import org.wso2.carbon.device.mgt.common.EnrolmentInfo.Status; import org.wso2.carbon.device.mgt.common.PaginationRequest; +import org.wso2.carbon.device.mgt.common.configuration.mgt.DevicePropertyInfo; import org.wso2.carbon.device.mgt.core.dao.DeviceDAO; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory; @@ -62,6 +63,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.StringJoiner; +import java.util.concurrent.atomic.AtomicInteger; public abstract class AbstractDeviceDAOImpl implements DeviceDAO { @@ -71,6 +73,7 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { private static final String PROPERTY_VALUE_COLUMN_NAME = "PROPERTY_VALUE"; private static final String PROPERTY_DEVICE_TYPE_NAME = "DEVICE_TYPE_NAME"; private static final String PROPERTY_DEVICE_IDENTIFICATION = "DEVICE_IDENTIFICATION"; + private static final String PROPERTY_TENANT_ID = "TENANT_ID"; @Override public int addDevice(int typeId, Device device, int tenantId) throws DeviceManagementDAOException { @@ -330,6 +333,65 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { return devices; } + @Override + public List getDeviceBasedOnDeviceProperties(Map deviceProps) + throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet resultSet = null; + List deviceProperties = new ArrayList<>(); + try { + conn = this.getConnection(); + List> outputLists = new ArrayList<>(); + String sql = "SELECT " + + "p.DEVICE_IDENTIFICATION, " + + "p.DEVICE_TYPE_NAME, " + + "p.TENANT_ID FROM " + + "DM_DEVICE_PROPERTIES p "; + + String groupByClause = "GROUP BY " + + "p.DEVICE_IDENTIFICATION, " + + "p.DEVICE_TYPE_NAME, " + + "p.TENANT_ID"; + + AtomicInteger iterationCount = new AtomicInteger(0); + StringBuilder propertyQuery = new StringBuilder(" "); + for (Map.Entry stringStringEntry : deviceProps.entrySet()) { + String tempTableId = "t".concat(Integer.toString(iterationCount.getAndIncrement())); + propertyQuery.append("JOIN DM_DEVICE_PROPERTIES ") + .append(tempTableId).append(" ").append("ON p.DEVICE_IDENTIFICATION = ") + .append(tempTableId).append(".DEVICE_IDENTIFICATION ") + .append("AND ") + .append(tempTableId).append(".PROPERTY_NAME = ? ") + .append("AND ") + .append(tempTableId).append(".PROPERTY_VALUE = ? "); + } + sql = sql.concat(propertyQuery.toString()).concat(groupByClause); + stmt = conn.prepareStatement(sql); + int index = 1; + for (Map.Entry entry : deviceProps.entrySet()) { + stmt.setString(index++, entry.getKey()); + stmt.setString(index++, entry.getValue()); + } + resultSet = stmt.executeQuery(); + while (resultSet.next()) { + DevicePropertyInfo devicePropertyInfo = new DevicePropertyInfo(); + devicePropertyInfo + .setDeviceIdentifier(resultSet.getString(PROPERTY_DEVICE_IDENTIFICATION)); + devicePropertyInfo.setTenantId(resultSet.getString(PROPERTY_TENANT_ID)); + devicePropertyInfo.setDeviceTypeName(resultSet.getString(PROPERTY_DEVICE_TYPE_NAME)); + deviceProperties.add(devicePropertyInfo); + } + return deviceProperties; + } catch (SQLException e) { + String msg = "Error occurred while fetching devices against criteria : '" + deviceProps; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, resultSet); + } + } + @Override public Device getDeviceProps(String deviceId, int tenantId) throws DeviceManagementDAOException { Connection conn = null; @@ -385,7 +447,6 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { return intersectedResult; } - @Override public Device getDevice(String deviceIdentifier, Date since, int tenantId) throws DeviceManagementDAOException { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java index b32ed7ed12..8aa8f71626 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderService.java @@ -38,17 +38,22 @@ 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.DeviceNotFoundException; 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.InvalidArgumentException; import org.wso2.carbon.device.mgt.common.InvalidDeviceException; import org.wso2.carbon.device.mgt.common.MonitoringOperation; import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig; import org.wso2.carbon.device.mgt.common.PaginationRequest; import org.wso2.carbon.device.mgt.common.PaginationResult; import org.wso2.carbon.device.mgt.common.StartupOperationConfig; +import org.wso2.carbon.device.mgt.common.UnauthorizedDeviceAccessException; import org.wso2.carbon.device.mgt.common.UserNotFoundException; +import org.wso2.carbon.device.mgt.common.configuration.mgt.AmbiguousConfigurationException; import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException; +import org.wso2.carbon.device.mgt.common.configuration.mgt.DeviceConfiguration; import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration; import org.wso2.carbon.device.mgt.common.license.mgt.License; import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; @@ -729,4 +734,19 @@ public interface DeviceManagementProviderService { boolean updateEnrollment(String owner, List deviceIdentifiers) throws DeviceManagementException, UserNotFoundException, InvalidDeviceException; + + /** + * Retrieves a list of configurations of a specific device + * using the device's properties + * @param propertyMap properties by which devices need to be drawn + * @return list of device configuration + * @throws DeviceManagementException if any service level or DAO level error occurs + * @throws DeviceNotFoundException if there is no any device can found for specified properties + * @throws UnauthorizedDeviceAccessException if the required token property is not found on + * @throws AmbiguousConfigurationException if configuration is ambiguous + * the property payload + */ + DeviceConfiguration getDeviceConfiguration(Map propertyMap) + throws DeviceManagementException, DeviceNotFoundException, UnauthorizedDeviceAccessException, + AmbiguousConfigurationException; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java index dcf34c0e27..8aa8d5e2d8 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java @@ -60,6 +60,7 @@ 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; +import org.wso2.carbon.device.mgt.common.InvalidArgumentException; import org.wso2.carbon.device.mgt.common.InvalidDeviceException; import org.wso2.carbon.device.mgt.common.MonitoringOperation; import org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig; @@ -67,9 +68,14 @@ import org.wso2.carbon.device.mgt.common.PaginationRequest; import org.wso2.carbon.device.mgt.common.PaginationResult; import org.wso2.carbon.device.mgt.common.StartupOperationConfig; import org.wso2.carbon.device.mgt.common.TransactionManagementException; +import org.wso2.carbon.device.mgt.common.UnauthorizedDeviceAccessException; import org.wso2.carbon.device.mgt.common.UserNotFoundException; import org.wso2.carbon.device.mgt.common.app.mgt.Application; +import org.wso2.carbon.device.mgt.common.configuration.mgt.AmbiguousConfigurationException; +import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry; import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationManagementException; +import org.wso2.carbon.device.mgt.common.configuration.mgt.DeviceConfiguration; +import org.wso2.carbon.device.mgt.common.configuration.mgt.DevicePropertyInfo; import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration; import org.wso2.carbon.device.mgt.common.device.details.DeviceInfo; import org.wso2.carbon.device.mgt.common.device.details.DeviceLocation; @@ -3273,4 +3279,86 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv + "constructing is failed", e); } } + + @Override + public DeviceConfiguration getDeviceConfiguration(Map deviceProps) + throws DeviceManagementException, DeviceNotFoundException, UnauthorizedDeviceAccessException, + AmbiguousConfigurationException { + + if (log.isDebugEnabled()) { + log.debug("Attempting to get device configurations based on properties."); + } + + DevicePropertyInfo deviceProperties; + List devicePropertyList; + try { + DeviceManagementDAOFactory.openConnection(); + devicePropertyList = deviceDAO.getDeviceBasedOnDeviceProperties(deviceProps); + if (devicePropertyList == null || devicePropertyList.isEmpty()) { + String msg = "Cannot find device for specified properties"; + log.info(msg); + throw new DeviceNotFoundException(msg); + } + //In this service, there should be only one device for the specified property values + //If multiple values retrieved, It'll be marked as ambiguous. + if (devicePropertyList.size() > 1) { + String msg = "Device property list contains more than one element"; + log.error(msg); + throw new AmbiguousConfigurationException(msg); + } + //Get the only existing value of the list + deviceProperties = devicePropertyList.get(0); + + } catch (SQLException e) { + String msg = "Error occurred while opening a connection to the data source"; + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } catch (DeviceManagementDAOException e) { + String msg = "Devices configuration retrieval criteria cannot be null or empty."; + log.error(msg); + throw new DeviceManagementException(msg, e); + } finally { + DeviceManagementDAOFactory.closeConnection(); + } + + try { + Device device = this.getDevice(new DeviceIdentifier(deviceProperties.getDeviceIdentifier(), + deviceProperties.getDeviceTypeName()), false); + String owner = device.getEnrolmentInfo().getOwner(); + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + ctx.setTenantId(Integer.parseInt(deviceProperties.getTenantId()), true); + PlatformConfiguration configuration = this.getConfiguration(device.getType()); + List configurationEntries = new ArrayList<>(); + if (configuration != null) { + configurationEntries = configuration.getConfiguration(); + } + return wrapConfigurations(device, ctx.getTenantDomain(), configurationEntries, owner); + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + } + + /** + * Wrap the device configuration data into DeviceConfiguration bean + * @param device Device queried using the properties + * @param tenantDomain tenant domain + * @param configurationEntries platformConfiguration list + * @param deviceOwner name of the device owner + * @return Wrapped {@link DeviceConfiguration} object with data + */ + private DeviceConfiguration wrapConfigurations(Device device, + String tenantDomain, + List configurationEntries, + String deviceOwner) { + DeviceConfiguration deviceConfiguration = new DeviceConfiguration(); + deviceConfiguration.setDeviceId(device.getId()); + deviceConfiguration.setDeviceType(device.getType()); + deviceConfiguration.setTenantDomain(tenantDomain); + deviceConfiguration.setConfigurationEntries(configurationEntries); + deviceConfiguration.setDeviceOwner(deviceOwner); + return deviceConfiguration; + } + + } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java index 44d8814fcd..ccf6091d8c 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceManagerUtil.java @@ -17,13 +17,25 @@ */ package org.wso2.carbon.device.mgt.core.util; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.protocol.HTTP; import org.w3c.dom.Document; import org.wso2.carbon.base.MultitenantConstants; import org.wso2.carbon.caching.impl.CacheImpl; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherService; +import org.wso2.carbon.device.mgt.common.AppRegistrationCredentials; +import org.wso2.carbon.device.mgt.common.ApplicationRegistration; +import org.wso2.carbon.device.mgt.common.ApplicationRegistrationException; import org.wso2.carbon.device.mgt.common.Device; import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.DeviceManagementException; @@ -49,6 +61,10 @@ import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder; import org.wso2.carbon.device.mgt.core.operation.mgt.OperationMgtConstants; import org.wso2.carbon.device.mgt.core.operation.mgt.util.DeviceIDHolder; +import org.wso2.carbon.identity.jwt.client.extension.JWTClient; +import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo; +import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; +import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; import org.wso2.carbon.user.api.TenantManager; import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.utils.CarbonUtils; @@ -63,9 +79,13 @@ import javax.sql.DataSource; import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; +import java.io.BufferedReader; import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Base64; import java.util.HashMap; import java.util.Hashtable; import java.util.List; @@ -588,4 +608,102 @@ public final class DeviceManagerUtil { } return deviceCache; } + + /** + * Create an app and get app registration token from the application registration endpoint + * + * @return AppRegistrationToken object which contains access and refresh tokens + * @throws ApplicationRegistrationException when application fails to connect with the app registration + * endpoint + */ + @SuppressWarnings("PackageAccessibility") + public static AppRegistrationCredentials getApplicationRegistrationCredentials(String host, String port, + String credentials) + throws ApplicationRegistrationException { + if (host == null || port == null) { + String msg = "Required gatewayHost or gatewayPort system property is null"; + log.error(msg); + throw new ApplicationRegistrationException(msg); + } + String internalServerAddr = "https://".concat(host).concat(":").concat(port); + try (CloseableHttpClient client = HttpClients.createDefault()) { + HttpPost apiEndpoint = new HttpPost( + internalServerAddr + DeviceManagementConstants.ConfigurationManagement + .APPLICATION_REGISTRATION_API_ENDPOINT); + + apiEndpoint.setHeader(HTTP.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString()); + apiEndpoint.setHeader(DeviceManagementConstants.ConfigurationManagement.AUTHORIZATION_HEADER, + DeviceManagementConstants.ConfigurationManagement.BASIC_AUTH.concat(" ") + .concat(getBase64EncodedCredentials(credentials))); + apiEndpoint.setEntity(constructApplicationRegistrationPayload()); + HttpResponse response = client.execute(apiEndpoint); + if (response != null) { + log.info("Obtained client credentials: " + response.getStatusLine().getStatusCode()); + BufferedReader rd = new BufferedReader( + new InputStreamReader(response.getEntity().getContent())); + StringBuilder result = new StringBuilder(); + String line; + while ((line = rd.readLine()) != null) { + result.append(line); + } + return new ObjectMapper().readValue(result.toString(), AppRegistrationCredentials.class); + } else { + String msg = "Response is 'NUll' for the Application Registration API call."; + log.error(msg); + throw new ApplicationRegistrationException(msg); + } + } catch (IOException e) { + throw new ApplicationRegistrationException( + "Error occurred when invoking API. API endpoint: " + + internalServerAddr + DeviceManagementConstants.ConfigurationManagement + .APPLICATION_REGISTRATION_API_ENDPOINT, e); + } + } + + /** + * Use default admin credentials and encode them in Base64 + * + * @return Base64 encoded client credentials + */ + private static String getBase64EncodedCredentials(String credentials) { + return Base64.getEncoder().encodeToString(credentials.getBytes()); + } + + /** + * Create a JSON payload for application registration + * + * @return Generated JSON payload + */ + @SuppressWarnings("PackageAccessibility") + private static StringEntity constructApplicationRegistrationPayload() { + ApplicationRegistration applicationRegistration = new ApplicationRegistration(); + applicationRegistration.setApplicationName("MyApp"); + applicationRegistration.setAllowedToAllDomains(false); + List tags = new ArrayList<>(); + tags.add("device_management"); + applicationRegistration.setTags(tags); + applicationRegistration.setValidityPeriod(3600); + Gson gson = new Gson(); + String payload = gson.toJson(applicationRegistration); + return new StringEntity(payload, ContentType.APPLICATION_JSON); + } + + /** + * Retrieves access token for a given device + * @param scopes scopes for token + * @param clientId clientId + * @param clientSecret clientSecret + * @param deviceOwner owner of the device that is going to generate token + * @return @{@link AccessTokenInfo} wrapped object of retrieved access token and refresh token + * @throws JWTClientException if an error occurs when the jwt client creation or token retrieval + */ + public static AccessTokenInfo getAccessTokenForDeviceOwner(String scopes, String clientId, + String clientSecret, String deviceOwner) + throws JWTClientException { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + JWTClientManagerService jwtClientManagerService = (JWTClientManagerService) ctx + .getOSGiService(JWTClientManagerService.class, null); + JWTClient jwtClient = jwtClientManagerService.getJWTClient(); + return jwtClient.getAccessToken(clientId, clientSecret, deviceOwner, scopes); + } } diff --git a/components/device-mgt/pom.xml b/components/device-mgt/pom.xml index 1b6c693058..c0647a04f4 100644 --- a/components/device-mgt/pom.xml +++ b/components/device-mgt/pom.xml @@ -42,6 +42,7 @@ org.wso2.carbon.device.mgt.analytics.data.publisher org.wso2.carbon.device.mgt.url.printer org.wso2.carbon.device.mgt.analytics.wsproxy + io.entgra.carbon.device.mgt.config.api diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/pom.xml b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/pom.xml index 8bf4cde0e6..d38319a04c 100644 --- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/pom.xml +++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/pom.xml @@ -232,7 +232,11 @@ powermock-module-testng test - + + org.wso2.carbon.devicemgt + org.wso2.carbon.identity.jwt.client.extension + test + diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.api.feature/pom.xml b/features/device-mgt/org.wso2.carbon.device.mgt.api.feature/pom.xml index e1fc7e9d8a..5b602cf81e 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.api.feature/pom.xml +++ b/features/device-mgt/org.wso2.carbon.device.mgt.api.feature/pom.xml @@ -85,6 +85,29 @@ + + copy config api + package + + copy + + + + + org.wso2.carbon.devicemgt + io.entgra.carbon.device.mgt.config.api + + ${project.version} + war + true + + ${project.build.directory}/maven-shared-archive-resources/webapps + + api#device-mgt-config#v1.0.war + + + + diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.api.feature/src/main/resources/p2.inf b/features/device-mgt/org.wso2.carbon.device.mgt.api.feature/src/main/resources/p2.inf index fea8965f73..66e6d1f6de 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.api.feature/src/main/resources/p2.inf +++ b/features/device-mgt/org.wso2.carbon.device.mgt.api.feature/src/main/resources/p2.inf @@ -1,4 +1,5 @@ instructions.configure = \ org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/server/webapps/);\ org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.api_${feature.version}/webapps/api#device-mgt#v1.0.war,target:${installFolder}/../../deployment/server/webapps/api#device-mgt#v1.0.war,overwrite:true);\ -org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.api_${feature.version}/webapps/api#device-mgt#v0.9.war,target:${installFolder}/../../deployment/server/webapps/api#device-mgt#v0.9.war,overwrite:true);\ \ No newline at end of file +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.api_${feature.version}/webapps/api#device-mgt#v0.9.war,target:${installFolder}/../../deployment/server/webapps/api#device-mgt#v0.9.war,overwrite:true);\ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.api_${feature.version}/webapps/api#device-mgt-config#v1.0.war,target:${installFolder}/../../deployment/server/webapps/api#device-mgt-config#v1.0.war,overwrite:true);\ \ No newline at end of file From f01448d39635208aaacf749316b3db2875e2f2cd Mon Sep 17 00:00:00 2001 From: Pahansith Date: Tue, 27 Aug 2019 23:16:43 +0530 Subject: [PATCH 30/34] Change http method to get --- .../config/jaxrs/service/DeviceManagementConfigService.java | 2 +- .../device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/DeviceManagementConfigService.java b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/DeviceManagementConfigService.java index 5c53d8129a..4742548f66 100644 --- a/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/DeviceManagementConfigService.java +++ b/components/device-mgt/io.entgra.carbon.device.mgt.config.api/src/main/java/io/entgra/carbon/device/mgt/config/jaxrs/service/DeviceManagementConfigService.java @@ -79,7 +79,7 @@ public interface DeviceManagementConfigService { @GET @ApiOperation( produces = MediaType.APPLICATION_JSON, - httpMethod = "POST", + httpMethod = "GET", value = "Getting General device Configurations", notes = "This API is responsible for send device configuration data to an IOT device when the " + "device starts provisioning", diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java index 588f2ebd4a..6e5ef3a586 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractDeviceDAOImpl.java @@ -354,10 +354,10 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { "p.DEVICE_TYPE_NAME, " + "p.TENANT_ID"; - AtomicInteger iterationCount = new AtomicInteger(0); + int iterationCount = 0; StringBuilder propertyQuery = new StringBuilder(" "); for (Map.Entry stringStringEntry : deviceProps.entrySet()) { - String tempTableId = "t".concat(Integer.toString(iterationCount.getAndIncrement())); + String tempTableId = "t".concat(Integer.toString(iterationCount++)); propertyQuery.append("JOIN DM_DEVICE_PROPERTIES ") .append(tempTableId).append(" ").append("ON p.DEVICE_IDENTIFICATION = ") .append(tempTableId).append(".DEVICE_IDENTIFICATION ") From 5421c1c38b84fef8e399b6953ee5876fd8763696 Mon Sep 17 00:00:00 2001 From: lasanthaDLPDS Date: Wed, 28 Aug 2019 13:16:54 +0530 Subject: [PATCH 31/34] Fix operation DTO initializing issue --- .../mgt/core/operation/mgt/dao/util/OperationDAOUtil.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/dao/util/OperationDAOUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/dao/util/OperationDAOUtil.java index ff402f7e97..efabf9bee6 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/dao/util/OperationDAOUtil.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/dao/util/OperationDAOUtil.java @@ -79,6 +79,10 @@ public class OperationDAOUtil { dtoOperation.setControl(Operation.Control.valueOf(operation.getControl().toString())); } + if (operation.getInitiatedBy() != null) { + dtoOperation.setInitiatedBy(operation.getInitiatedBy()); + } + return dtoOperation; } From 3ae5339effd6a5a6922394ce5d81ce304dad244d Mon Sep 17 00:00:00 2001 From: Pahansith Date: Thu, 29 Aug 2019 10:51:49 +0530 Subject: [PATCH 32/34] Add device identifier for configuration retrieval endpoint --- .../mgt/common/configuration/mgt/DeviceConfiguration.java | 6 +++--- .../core/service/DeviceManagementProviderServiceImpl.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/configuration/mgt/DeviceConfiguration.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/configuration/mgt/DeviceConfiguration.java index da39516f41..c3020098e7 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/configuration/mgt/DeviceConfiguration.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/configuration/mgt/DeviceConfiguration.java @@ -32,7 +32,7 @@ import java.util.List; "the server") public class DeviceConfiguration { @ApiModelProperty(name = "deviceId", value = "ID of the device", required = true) - private int deviceId; + private String deviceId; @ApiModelProperty(name = "deviceType", value = "Type of the device", required = true) private String deviceType; @@ -52,11 +52,11 @@ public class DeviceConfiguration { @ApiModelProperty(name = "deviceOwner", value = "Owner of the selected device", required = true) private String deviceOwner; - public int getDeviceId() { + public String getDeviceId() { return deviceId; } - public void setDeviceId(int deviceId) { + public void setDeviceId(String deviceId) { this.deviceId = deviceId; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java index 8aa8d5e2d8..b590d18564 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/service/DeviceManagementProviderServiceImpl.java @@ -3352,7 +3352,7 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv List configurationEntries, String deviceOwner) { DeviceConfiguration deviceConfiguration = new DeviceConfiguration(); - deviceConfiguration.setDeviceId(device.getId()); + deviceConfiguration.setDeviceId(device.getDeviceIdentifier()); deviceConfiguration.setDeviceType(device.getType()); deviceConfiguration.setTenantDomain(tenantDomain); deviceConfiguration.setConfigurationEntries(configurationEntries); From ff7ec02bcbee83fa19db25366fc9f2c6288ce16d Mon Sep 17 00:00:00 2001 From: Ruwan Yatawara Date: Thu, 29 Aug 2019 08:00:32 +0000 Subject: [PATCH 33/34] removing font-wso2 and adding font-entgra --- .../public/css/custom-desktop.css | 8 +- .../uuf.unit.theme/public/css/theme-wso2.css | 4 +- .../css/font-entgra.css} | 108 +- .../font-entgra-1.4.0/css/font-entgra.min.css | 15 + .../font-entgra-1.4.0/fonts/font-entgra.eot | Bin 0 -> 120940 bytes .../font-entgra-1.4.0/fonts/font-entgra.svg | 1162 ++++++++ .../font-entgra-1.4.0/fonts/font-entgra.ttf | Bin 0 -> 120752 bytes .../font-entgra-1.4.0/fonts/font-entgra.woff | Bin 0 -> 77332 bytes .../font-entgra-1.4.0/fonts/font-entgra.woff2 | Bin 0 -> 65052 bytes .../icons.json | 35 +- .../scss/_mixin.scss | 2586 +++++++++-------- .../lib/font-wso2-1.3.0/css/font-wso2.min.css | 15 - .../lib/font-wso2-1.3.0/fonts/font-wso2.svg | 2326 --------------- .../lib/font-wso2-1.3.0/fonts/font-wso2.ttf | Bin 71828 -> 0 bytes .../lib/font-wso2-1.3.0/fonts/font-wso2.woff | Bin 142064 -> 0 bytes .../lib/font-wso2-1.3.0/fonts/font-wso2.woff2 | Bin 38672 -> 0 bytes .../lib/theme-wso2_1.0/less/theme-wso2.less | 2 +- .../app/units/uuf.unit.theme/theme.hbs | 2 +- 18 files changed, 2644 insertions(+), 3619 deletions(-) rename components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/{font-wso2-1.3.0/css/font-wso2.css => font-entgra-1.4.0/css/font-entgra.css} (91%) mode change 100644 => 100755 create mode 100755 components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/css/font-entgra.min.css create mode 100755 components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/fonts/font-entgra.eot create mode 100755 components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/fonts/font-entgra.svg create mode 100755 components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/fonts/font-entgra.ttf create mode 100755 components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/fonts/font-entgra.woff create mode 100755 components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/fonts/font-entgra.woff2 rename components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/{font-wso2-1.3.0 => font-entgra-1.4.0}/icons.json (92%) mode change 100644 => 100755 rename components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/{font-wso2-1.3.0 => font-entgra-1.4.0}/scss/_mixin.scss (92%) mode change 100644 => 100755 delete mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/css/font-wso2.min.css delete mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/fonts/font-wso2.svg delete mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/fonts/font-wso2.ttf delete mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/fonts/font-wso2.woff delete mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/fonts/font-wso2.woff2 diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.theme/public/css/custom-desktop.css b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.theme/public/css/custom-desktop.css index 27a469d35f..97d9bfbce4 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.theme/public/css/custom-desktop.css +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.ui.theme/public/css/custom-desktop.css @@ -2401,7 +2401,7 @@ a.list-group-item:hover { } .tree-view li > .icon { - font-family: "font-wso2"; + font-family: "font-entgra"; font-style: normal; background: #2c313b; color: #ffffff; @@ -2686,7 +2686,7 @@ a.list-group-item:hover { text-align: center; background: #2c313b; color: #fff; - font-family: font-wso2; + font-family: font-entgra; } .checkbox > input[type=checkbox]:not(:checked) + .helper:after { @@ -4433,7 +4433,7 @@ a.wr-side-panel-toggle-btn.selected { text-align: center; background: #008cc4; color: #fff; - font-family: font-wso2; + font-family: font-entgra; } .wr-input-control.checkbox input[type="checkbox"]:not(:checked) + .helper:after { @@ -6624,7 +6624,7 @@ ul.tiles .icon { } .tree-view li > .icon { - font-family: 'font-wso2'; + font-family: 'font-entgra'; font-style: normal; background: #2c313b; color: #ffffff; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/css/theme-wso2.css b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/css/theme-wso2.css index cbff8ffd9c..bf28c543e5 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/css/theme-wso2.css +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/css/theme-wso2.css @@ -8053,7 +8053,7 @@ a.list-group-item:hover { } .tree-view li > .icon { - font-family: "font-wso2"; + font-family: "font-entgra"; font-style: normal; background: #008cc4; color: #ffffff; @@ -8295,7 +8295,7 @@ a.list-group-item:hover { text-align: center; background: #004675; color: #fff; - font-family: font-wso2; + font-family: font-entgra; } .checkbox > input[type=checkbox]:not(:checked) + .helper:after { display: none; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/css/font-wso2.css b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/css/font-entgra.css old mode 100644 new mode 100755 similarity index 91% rename from components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/css/font-wso2.css rename to components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/css/font-entgra.css index c6544d6f2e..1665602d06 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/css/font-wso2.css +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/css/font-entgra.css @@ -1,5 +1,5 @@ /*! -~ Copyright (c) WSO2 Inc. (http://wso2.com) All Rights Reserved. +~ Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); ~ you may not use this file except in compliance with the License. @@ -16,20 +16,20 @@ @font-face { - font-family:"font-wso2"; - src:local("font-wso2"), url("../fonts/font-wso2.eot?6563fa91278f239ef8c827d90a165223"); - src:local("font-wso2"), - url("../fonts/font-wso2.eot?#iefix") format("embedded-opentype"), - url("../fonts/font-wso2.woff2?6563fa91278f239ef8c827d90a165223") format("woff2"), - url("../fonts/font-wso2.woff?6563fa91278f239ef8c827d90a165223") format("woff"), - url("../fonts/font-wso2.ttf?6563fa91278f239ef8c827d90a165223") format("truetype"), - url("../fonts/font-wso2.svg?6563fa91278f239ef8c827d90a165223#font-wso2") format("svg"); + font-family:"font-entgra"; + src:local("font-entgra"), url("../fonts/font-entgra.eot?3990d6a2bf7b820a842f9dc0774c990e"); + src:local("font-entgra"), + url("../fonts/font-entgra.eot?3990d6a2bf7b820a842f9dc0774c990e#iefix") format("embedded-opentype"), + url("../fonts/font-entgra.woff2?3990d6a2bf7b820a842f9dc0774c990e") format("woff2"), + url("../fonts/font-entgra.woff?3990d6a2bf7b820a842f9dc0774c990e") format("woff"), + url("../fonts/font-entgra.ttf?3990d6a2bf7b820a842f9dc0774c990e") format("truetype"), + url("../fonts/font-entgra.svg?3990d6a2bf7b820a842f9dc0774c990e#font-entgra") format("svg"); font-weight:normal; font-style:normal; } .fw, [class^="fw-"], [class*=" fw-"] { - font: normal normal normal 14px/1 font-wso2; + font: normal normal normal 14px/1 font-entgra; display: inline-block; font-weight: normal; font-style: normal; @@ -304,10 +304,18 @@ content:"\e6cf"; } +.fw-activesync:before { + content:"\e745"; +} + .fw-add:before { content:"\e615"; } +.fw-aggregate:before { + content:"\e742"; +} + .fw-airplay:before { content:"\e600"; } @@ -348,7 +356,7 @@ content:"\e602"; } -.fw-ios:before { +.fw-apple:before { content:"\e604"; } @@ -380,6 +388,10 @@ content:"\e60a"; } +.fw-bean:before { + content:"\e743"; +} + .fw-blank-document:before { content:"\e60c"; } @@ -416,6 +428,10 @@ content:"\e612"; } +.fw-call-mediator:before { + content:"\e736"; +} + .fw-camera:before { content:"\e613"; } @@ -480,7 +496,7 @@ content:"\e653"; } -.fw-configarations:before { +.fw-configurations:before { content:"\e609"; } @@ -500,6 +516,10 @@ content:"\e620"; } +.fw-continue:before { + content:"\e73e"; +} + .fw-contract:before { content:"\e614"; } @@ -516,6 +536,10 @@ content:"\e622"; } +.fw-data-mapper:before { + content:"\e735"; +} + .fw-database:before { content:"\e623"; } @@ -628,6 +652,10 @@ content:"\e628"; } +.fw-dollar:before { + content:"\e741"; +} + .fw-down-arrow:before { content:"\e689"; } @@ -672,6 +700,10 @@ content:"\e6e3"; } +.fw-event-simulator:before { + content:"\e744"; +} + .fw-expand:before { content:"\e61c"; } @@ -716,6 +748,10 @@ content:"\e62e"; } +.fw-foreach:before { + content:"\e73ab"; +} + .fw-fork-join:before { content:"\e720"; } @@ -764,6 +800,10 @@ content:"\e6da"; } +.fw-google-glass:before { + content:"\e732"; +} + .fw-google-plus:before { content:"\e6d9"; } @@ -800,6 +840,10 @@ content:"\e639"; } +.fw-header:before { + content:"\e734"; +} + .fw-heart:before { content:"\e6c3"; } @@ -832,6 +876,10 @@ content:"\e63c"; } +.fw-in-sequence:before { + content:"\e739"; +} + .fw-incoming-call:before { content:"\e63d"; } @@ -844,6 +892,10 @@ content:"\e6db"; } +.fw-integration:before { + content:"\e73f"; +} + .fw-invitation:before { content:"\e63f"; } @@ -896,6 +948,10 @@ content:"\e647"; } +.fw-kiosk:before { + content:"\e746"; +} + .fw-laptop:before { content:"\e648"; } @@ -960,6 +1016,10 @@ content:"\e64e"; } +.fw-log:before { + content:"\e738"; +} + .fw-logical:before { content:"\e702"; } @@ -976,6 +1036,10 @@ content:"\e650"; } +.fw-mapping:before { + content:"\e73c"; +} + .fw-menu:before { content:"\e651"; } @@ -1004,6 +1068,10 @@ content:"\e655"; } +.fw-namespace:before { + content:"\e740"; +} + .fw-nodejs:before { content:"\e656"; } @@ -1016,6 +1084,10 @@ content:"\e6ac"; } +.fw-out-sequence:before { + content:"\e73a"; +} + .fw-own:before { content:"\e6c8"; } @@ -1032,6 +1104,10 @@ content:"\e658"; } +.fw-payload-factory:before { + content:"\e733"; +} + .fw-pdf:before { content:"\e659"; } @@ -1060,6 +1136,10 @@ content:"\e70d"; } +.fw-property:before { + content:"\e737"; +} + .fw-prototype:before { content:"\e6cc"; } @@ -1088,6 +1168,10 @@ content:"\e65d"; } +.fw-reduce:before { + content:"\e73d"; +} + .fw-refresh:before { content:"\e692"; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/css/font-entgra.min.css b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/css/font-entgra.min.css new file mode 100755 index 0000000000..6ecdc54720 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/css/font-entgra.min.css @@ -0,0 +1,15 @@ +/*! +~ Copyright (c) WSO2 Inc. (http://wso2.com) All Rights Reserved. +~ +~ Licensed 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. +*/@font-face{font-family:font-entgra;src:local("font-entgra"),url(../fonts/font-entgra.eot?3990d6a2bf7b820a842f9dc0774c990e);src:local("font-entgra"),url(../fonts/font-entgra.eot?3990d6a2bf7b820a842f9dc0774c990e#iefix) format("embedded-opentype"),url(../fonts/font-entgra.woff2?3990d6a2bf7b820a842f9dc0774c990e) format("woff2"),url(../fonts/font-entgra.woff?3990d6a2bf7b820a842f9dc0774c990e) format("woff"),url(../fonts/font-entgra.ttf?3990d6a2bf7b820a842f9dc0774c990e) format("truetype"),url(../fonts/font-entgra.svg?3990d6a2bf7b820a842f9dc0774c990e#font-entgra) format("svg");font-weight:400;font-style:normal}.fw,[class*=" fw-"],[class^=fw-]{font:normal normal normal 14px/1 font-entgra;display:inline-block;font-weight:400;font-style:normal;font-size:inherit;font-variant:normal;speak:none;text-decoration:inherit;text-transform:none;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fw-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fw-2x{font-size:2em}.fw-3x{font-size:3em}.fw-4x{font-size:4em}.fw-5x{font-size:5em}.fw-fw{width:1.28571429em;text-align:center}.fw-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fw-ul>li{position:relative}.fw-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fw-li.fw-lg{left:-1.85714286em}.fw-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fw-background{background:#888;border-radius:.3em;padding:.4em .5em .45em}.fw-pull-left{float:left}.fw-pull-right{float:right}.fw.fw-pull-left{margin-right:.3em}.fw.fw-pull-right{margin-left:.3em}.fw-spin{-webkit-animation:fw-spin 2s infinite linear;animation:fw-spin 2s infinite linear}@-webkit-keyframes fw-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fw-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fw-pulse{-webkit-animation:fw-pulse 2s ease-out infinite;animation:fw-pulse 2s ease-out infinite}@-webkit-keyframes fw-pulse{0%,30%{opacity:.3}40%{opacity:1}100%{opacity:.3}}@keyframes fw-pulse{0%,30%{opacity:.3}40%{opacity:1}100%{opacity:.3}}.fw-rotate-90{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fw-rotate-180{-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fw-rotate-270{-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fw-flip-horizontal{-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.fw-flip-vertical{-webkit-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scale(1,-1)}:root .fw-flip-horizontal,:root .fw-flip-vertical,:root .fw-rotate-180,:root .fw-rotate-270,:root .fw-rotate-90{filter:none}.fw-helper,.fw-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:1.85em;vertical-align:middle}.fw-helper:after,.fw-helper:before,.fw-stack-1x,.fw-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fw-helper:before,.fw-stack-1x{line-height:inherit}.fw-helper:after,.fw-stack-2x{font-size:1.9em}.fw-helper-slash:before{font-size:1.4em}.fw-helper-circle:before,.fw-helper-square:before{z-index:1}.fw-helper-circle-outline:after{content:"\e61f"}.fw-helper-circle:after{content:"\e61a"}.fw-helper-square-outline:after{content:"\e6b2"}.fw-helper-square:after{content:"\e6b1"}.fw-helper-slash:after{content:"\e6e1"}.fw-stack>.fw-stack{position:absolute;font-size:.5em}.fw-stack>.fw-stack.fw-move-top{top:-.2em}.fw-stack>.fw-stack.fw-move-bottom{bottom:-.2em}.fw-stack>.fw.stack.fw-move-left{left:-.5em}.fw-stack>.fw-stack.fw-move-right{right:-.5em}.fw-helper-inverse:after,.fw-inverse:before,.fw-number{color:#fff}.fw-helper-shadow:after,.fw-shadow:before{text-shadow:#fff 1px 1px 0}.fw-helper-stroke:after,.fw-stroke:before{text-shadow:-2px -2px 0 #fff,2px -2px 0 #fff,-2px 2px 0 #fff,2px 2px 0 #fff}.fw-number{line-height:2em;font-family:Arial,Helvetica,sans-serif}.fw-abort:before{content:"\e72a"}.fw-action-invoke:before{content:"\e6fe"}.fw-action:before{content:"\e709"}.fw-activate:before{content:"\e6cf"}.fw-activesync:before{content:"\e745"}.fw-add:before{content:"\e615"}.fw-aggregate:before{content:"\e742"}.fw-airplay:before{content:"\e600"}.fw-alarm:before{content:"\e6c2"}.fw-alert:before{content:"\e6be"}.fw-analytics-extensions:before{content:"\e6e2"}.fw-android-logcat:before{content:"\e72c"}.fw-android-sense:before{content:"\e72d"}.fw-android:before{content:"\e606"}.fw-annotation:before{content:"\e6e6"}.fw-api:before{content:"\e601"}.fw-apn:before{content:"\e602"}.fw-apple:before{content:"\e604"}.fw-application:before{content:"\e608"}.fw-arduino:before{content:"\e6ab"}.fw-assign:before{content:"\e6ff"}.fw-ballerina-service:before{content:"\e729"}.fw-ballerina:before{content:"\e728"}.fw-bar-chart:before{content:"\e690"}.fw-battery:before{content:"\e60a"}.fw-bean:before{content:"\e743"}.fw-blank-document:before{content:"\e60c"}.fw-block:before{content:"\e695"}.fw-bookmark:before{content:"\e60d"}.fw-bpel:before{content:"\e60e"}.fw-bpmn:before{content:"\e60f"}.fw-break:before{content:"\e721"}.fw-bug:before{content:"\e611"}.fw-build:before{content:"\e6c1"}.fw-calendar:before{content:"\e612"}.fw-call-mediator:before{content:"\e736"}.fw-camera:before{content:"\e613"}.fw-cancel:before{content:"\e618"}.fw-carbon:before{content:"\e6c5"}.fw-chat:before{content:"\e65b"}.fw-check:before{content:"\e617"}.fw-checklist:before{content:"\e619"}.fw-circle-outline:before{content:"\e61f"}.fw-circle:before{content:"\e61a"}.fw-clear:before{content:"\e61b"}.fw-clock:before{content:"\e61d"}.fw-cloud:before{content:"\e61e"}.fw-code-view:before{content:"\e70e"}.fw-code:before{content:"\e6f1"}.fw-comment:before{content:"\e710"}.fw-compare:before{content:"\e610"}.fw-computer:before{content:"\e653"}.fw-configurations:before{content:"\e609"}.fw-connector:before{content:"\e700"}.fw-console:before{content:"\e71d"}.fw-constant:before{content:"\e701"}.fw-contact:before{content:"\e620"}.fw-continue:before{content:"\e73e"}.fw-contract:before{content:"\e614"}.fw-copy:before{content:"\e621"}.fw-cut:before{content:"\e6f2"}.fw-dashboard:before{content:"\e622"}.fw-data-mapper:before{content:"\e735"}.fw-database:before{content:"\e623"}.fw-delete:before{content:"\e624"}.fw-depend:before{content:"\e6c6"}.fw-deploy:before{content:"\e625"}.fw-deprecate:before{content:"\e6cb"}.fw-design-view:before{content:"\e70f"}.fw-devices:before{content:"\e704"}.fw-dgm-action-invoke:before{content:"\e712"}.fw-dgm-action:before{content:"\e711"}.fw-dgm-connector:before{content:"\e6f4"}.fw-dgm-constant-definition:before{content:"\e6f5"}.fw-dgm-fork:before{content:"\e6e7"}.fw-dgm-header:before{content:"\e6e8"}.fw-dgm-if-else:before{content:"\e6e9"}.fw-dgm-import:before{content:"\e717"}.fw-dgm-lifeline:before{content:"\e6ea"}.fw-dgm-logger:before{content:"\e6eb"}.fw-dgm-resource:before{content:"\e6f6"}.fw-dgm-service:before{content:"\e6f7"}.fw-dgm-try-catch:before{content:"\e6ec"}.fw-dgm-type-convertor:before{content:"\e6f8"}.fw-dgm-type:before{content:"\e6f9"}.fw-dgm-while:before{content:"\e707"}.fw-dial-up:before{content:"\e627"}.fw-disabled:before{content:"\e6d1"}.fw-display:before{content:"\e626"}.fw-docker:before{content:"\e70c"}.fw-document:before{content:"\e628"}.fw-dollar:before{content:"\e741"}.fw-down-arrow:before{content:"\e689"}.fw-down:before{content:"\e685"}.fw-download:before{content:"\e65f"}.fw-dss:before{content:"\e62a"}.fw-ebook:before{content:"\e62b"}.fw-edit:before{content:"\e62c"}.fw-ellipsis:before{content:"\e629"}.fw-endpoint:before{content:"\e62d"}.fw-enterprise:before{content:"\e6b6"}.fw-error:before{content:"\e630"}.fw-esb-connector:before{content:"\e6e3"}.fw-event-simulator:before{content:"\e744"}.fw-expand:before{content:"\e61c"}.fw-export:before{content:"\e631"}.fw-extensions:before{content:"\e6e4"}.fw-facebook:before{content:"\e6d3"}.fw-factory-reset:before{content:"\e632"}.fw-fan:before{content:"\e678"}.fw-faq:before{content:"\e62f"}.fw-file-browse:before{content:"\e633"}.fw-filter:before{content:"\e634"}.fw-folder-open:before{content:"\e70b"}.fw-folder:before{content:"\e62e"}.fw-foreach:before{content:"\e73ab"}.fw-fork-join:before{content:"\e720"}.fw-format:before{content:"\e6fa"}.fw-forum:before{content:"\e636"}.fw-function-invoke:before{content:"\e713"}.fw-function:before{content:"\e6fb"}.fw-gadget:before{content:"\e637"}.fw-geo-fence-inbound:before{content:"\e72e"}.fw-geo-fence-outbound:before{content:"\e72f"}.fw-github:before{content:"\e6d4"}.fw-globe:before{content:"\e697"}.fw-google-docs:before{content:"\e6d6"}.fw-google-drive:before{content:"\e6da"}.fw-google-glass:before{content:"\e732"}.fw-google-plus:before{content:"\e6d9"}.fw-google-sheets:before{content:"\e6d7"}.fw-google-slides:before{content:"\e6d8"}.fw-google:before{content:"\e6d5"}.fw-grid:before{content:"\e638"}.fw-grip:before{content:"\e6b7"}.fw-group:before{content:"\e6af"}.fw-hardware:before{content:"\e6a9"}.fw-hdd:before{content:"\e639"}.fw-header:before{content:"\e734"}.fw-heart:before{content:"\e6c3"}.fw-hide:before{content:"\e6d2"}.fw-home:before{content:"\e63a"}.fw-hour-glass:before{content:"\e63b"}.fw-html:before{content:"\e69d"}.fw-http:before{content:"\e705"}.fw-image:before{content:"\e70a"}.fw-import:before{content:"\e63c"}.fw-in-sequence:before{content:"\e739"}.fw-incoming-call:before{content:"\e63d"}.fw-info:before{content:"\e63e"}.fw-instagram:before{content:"\e6db"}.fw-integration:before{content:"\e73f"}.fw-invitation:before{content:"\e63f"}.fw-invoke:before{content:"\e6ed"}.fw-is-connector:before{content:"\e6e5"}.fw-iterate:before{content:"\e71f"}.fw-jaggery:before{content:"\e640"}.fw-java-spring:before{content:"\e644"}.fw-java:before{content:"\e641"}.fw-javaee:before{content:"\e642"}.fw-javascript:before{content:"\e643"}.fw-jaxrs:before{content:"\e645"}.fw-jaxws:before{content:"\e6c7"}.fw-jquery:before{content:"\e646"}.fw-key:before{content:"\e647"}.fw-kiosk:before{content:"\e746"}.fw-laptop:before{content:"\e648"}.fw-layout:before{content:"\e6bf"}.fw-ldap:before{content:"\e649"}.fw-left-arrow:before{content:"\e68a"}.fw-left:before{content:"\e686"}.fw-lifecycle:before{content:"\e64a"}.fw-light:before{content:"\e680"}.fw-linkedin:before{content:"\e6dc"}.fw-list-sort:before{content:"\e64d"}.fw-list:before{content:"\e64c"}.fw-loader:before{content:"\e6b4"}.fw-loader2:before{content:"\e6ba"}.fw-loader3:before{content:"\e6bb"}.fw-loader4:before{content:"\e6bc"}.fw-loader5:before{content:"\e6bd"}.fw-lock:before{content:"\e64e"}.fw-log:before{content:"\e738"}.fw-logical:before{content:"\e702"}.fw-mail:before{content:"\e64f"}.fw-main-function:before{content:"\e706"}.fw-map-location:before{content:"\e650"}.fw-mapping:before{content:"\e73c"}.fw-menu:before{content:"\e651"}.fw-message:before{content:"\e635"}.fw-micro-services:before{content:"\e6ce"}.fw-dash:before,.fw-hyphen:before,.fw-minus:before{content:"\e616"}.fw-mobile:before{content:"\e652"}.fw-ms-document:before{content:"\e654"}.fw-mute:before{content:"\e655"}.fw-namespace:before{content:"\e740"}.fw-nodejs:before{content:"\e656"}.fw-notification:before{content:"\e60b"}.fw-organization:before{content:"\e6ac"}.fw-out-sequence:before{content:"\e73a"}.fw-own:before{content:"\e6c8"}.fw-package:before{content:"\e6fd"}.fw-pages:before{content:"\e6c0"}.fw-paste:before{content:"\e658"}.fw-payload-factory:before{content:"\e733"}.fw-pdf:before{content:"\e659"}.fw-pending:before{content:"\e727"}.fw-php:before{content:"\e6c9"}.fw-pie-chart:before{content:"\e65a"}.fw-pinterest:before{content:"\e6dd"}.fw-policy:before{content:"\e67d"}.fw-polygon:before{content:"\e70d"}.fw-property:before{content:"\e737"}.fw-prototype:before{content:"\e6cc"}.fw-proxy:before{content:"\e699"}.fw-public:before{content:"\e6ad"}.fw-publish:before{content:"\e65c"}.fw-question:before{content:"\e6b0"}.fw-raspberry:before{content:"\e6aa"}.fw-redo:before{content:"\e65d"}.fw-reduce:before{content:"\e73d"}.fw-refresh:before{content:"\e692"}.fw-register:before{content:"\e65e"}.fw-rename:before{content:"\e6fc"}.fw-reply:before{content:"\e714"}.fw-resource:before{content:"\e660"}.fw-rest-api:before{content:"\e661"}.fw-rest-service:before{content:"\e662"}.fw-resume:before{content:"\e71e"}.fw-retire:before{content:"\e6cd"}.fw-return:before{content:"\e715"}.fw-retweet:before{content:"\e6b9"}.fw-right-arrow:before{content:"\e68b"}.fw-right:before{content:"\e687"}.fw-ringing:before{content:"\e694"}.fw-rules:before{content:"\e664"}.fw-run:before{content:"\e708"}.fw-save:before{content:"\e665"}.fw-scep:before{content:"\e666"}.fw-schema:before{content:"\e667"}.fw-search:before{content:"\e668"}.fw-security-policy:before{content:"\e67e"}.fw-security:before{content:"\e669"}.fw-paper-rocket:before,.fw-send:before{content:"\e66a"}.fw-sequence:before{content:"\e66b"}.fw-server:before{content:"\e66c"}.fw-service-provider:before{content:"\e66e"}.fw-cogwheels:before,.fw-gears:before,.fw-service:before,.fw-sprockets:before{content:"\e66d"}.fw-cogwheel:before,.fw-gear:before,.fw-settings:before,.fw-sprocket:before{content:"\e66f"}.fw-share:before{content:"\e670"}.fw-shell:before{content:"\e730"}.fw-shortcut:before{content:"\e725"}.fw-sign-in:before{content:"\e671"}.fw-sign-out:before{content:"\e6b8"}.fw-skype:before{content:"\e6de"}.fw-slash:before{content:"\e6e1"}.fw-soap:before{content:"\e672"}.fw-sort-down:before{content:"\e663"}.fw-sort-up:before{content:"\e64b"}.fw-sort:before{content:"\e673"}.fw-speed-alert:before{content:"\e731"}.fw-square-outline:before{content:"\e6b2"}.fw-square:before{content:"\e6b1"}.fw-star:before{content:"\e674"}.fw-start:before{content:"\e718"}.fw-statistics:before{content:"\e675"}.fw-stepin:before{content:"\e719"}.fw-stepout:before{content:"\e71a"}.fw-stepover:before{content:"\e71b"}.fw-stop:before{content:"\e71c"}.fw-cart:before,.fw-store:before{content:"\e676"}.fw-struct:before{content:"\e716"}.fw-subscribe:before{content:"\e677"}.fw-success:before{content:"\e657"}.fw-swagger:before{content:"\e679"}.fw-sync:before{content:"\e6b3"}.fw-table:before{content:"\e6c4"}.fw-tag:before{content:"\e67a"}.fw-task:before{content:"\e67b"}.fw-text:before{content:"\e67c"}.fw-theme:before{content:"\e726"}.fw-throttling-policy:before{content:"\e67f"}.fw-throw:before{content:"\e722"}.fw-tiles:before{content:"\e681"}.fw-transaction:before{content:"\e72b"}.fw-try-catch:before{content:"\e703"}.fw-twitter:before{content:"\e6df"}.fw-type-converter:before{content:"\e6f3"}.fw-uncheck:before{content:"\e682"}.fw-undo:before{content:"\e683"}.fw-ungroup:before{content:"\e6b5"}.fw-unmute:before{content:"\e6ae"}.fw-up-arrow:before{content:"\e688"}.fw-up:before{content:"\e684"}.fw-upload:before{content:"\e68c"}.fw-uri:before{content:"\e68d"}.fw-usb-drive:before{content:"\e68e"}.fw-use:before{content:"\e6ca"}.fw-user:before{content:"\e68f"}.fw-variable:before{content:"\e6ee"}.fw-view:before{content:"\e691"}.fw-vpn:before{content:"\e603"}.fw-wadl:before{content:"\e6a1"}.fw-war:before{content:"\e69e"}.fw-warning:before{content:"\e693"}.fw-web-app:before{content:"\e696"}.fw-web-clip:before{content:"\e698"}.fw-web-service:before{content:"\e69a"}.fw-website:before{content:"\e69b"}.fw-wifi:before{content:"\e607"}.fw-windows:before{content:"\e605"}.fw-worker-invoke:before{content:"\e723"}.fw-worker-reply:before{content:"\e724"}.fw-worker:before{content:"\e6ef"}.fw-wsdl:before{content:"\e6a0"}.fw-wso2-logo:before{content:"\e6a7"}.fw-wso2:before{content:"\e6a8"}.fw-xacml:before{content:"\e69f"}.fw-xml:before{content:"\e69c"}.fw-xq:before{content:"\e6a2"}.fw-xsd:before{content:"\e6a3"}.fw-xslt:before{content:"\e6a4"}.fw-youtube:before{content:"\e6e0"}.fw-zoom-in:before{content:"\e6a5"}.fw-zoom-out:before{content:"\e6a6"} \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/fonts/font-entgra.eot b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/fonts/font-entgra.eot new file mode 100755 index 0000000000000000000000000000000000000000..0f604db5fe863d58dce40fb2537520d6796c13a6 GIT binary patch literal 120940 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 literal 0 HcmV?d00001 diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/fonts/font-entgra.svg b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/fonts/font-entgra.svg new file mode 100755 index 0000000000..9a249e0d16 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/fonts/font-entgra.svg @@ -0,0 +1,1162 @@ + + + + +Created by FontForge 20190801 at Wed Aug 28 15:47:29 2019 + By Ruwan Yatawara + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/fonts/font-entgra.ttf b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/fonts/font-entgra.ttf new file mode 100755 index 0000000000000000000000000000000000000000..1f5109266ca38e06054c28e48dc2d23ee61c9967 GIT binary patch literal 120752 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 CrA|-) literal 0 HcmV?d00001 diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/fonts/font-entgra.woff b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/fonts/font-entgra.woff new file mode 100755 index 0000000000000000000000000000000000000000..ca3c31d05393deaa776ab40225faacdb7d80879c GIT binary patch literal 77332 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 literal 0 HcmV?d00001 diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/fonts/font-entgra.woff2 b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/fonts/font-entgra.woff2 new file mode 100755 index 0000000000000000000000000000000000000000..6f1ff3a522de868bda74bb22a53e40532e138acf GIT binary patch literal 65052 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 q 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 Z?gxlT&x6AqvxtXIKp=DwISmCuY5=75Ah-Yk literal 0 HcmV?d00001 diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/icons.json b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/icons.json old mode 100644 new mode 100755 similarity index 92% rename from components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/icons.json rename to components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/icons.json index 0bd52ef51e..df9ca28553 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/icons.json +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/icons.json @@ -8,7 +8,7 @@ "android": "", "wifi": "", "application": "", - "configarations": "", + "configurations": "", "battery": "", "notification": "", "blank-document": "", @@ -156,7 +156,7 @@ "web-service": "", "website": "", "xml": "", - "html": "\t\t\t\t", + "html": "", "war": "", "xacml": "", "wsdl": "", @@ -236,7 +236,7 @@ "dgm-logger": "\t", "dgm-try-catch": "", "invoke": "", - "variable": "", + "variable": "", "worker": "", "code": "", "cut": "", @@ -276,11 +276,11 @@ "reply": "", "return": "", "struct": "", - "dgm-import": "", + "dgm-import": "", "start": "", "stepin": "", "stepout": "", - "stepover": "", + "stepover": "", "stop": "", "console": "", "resume": "", @@ -297,10 +297,31 @@ "ballerina-service": "", "abort": "", "transaction": "", - "android-logcat": "", + "android-logcat": "", "android-sense": "", "geo-fence-inbound": "", "geo-fence-outbound": "", "shell": "", - "speed-alert": "" + "speed-alert": "", + "google-glass": "", + "payload-factory": "", + "header": "", + "data-mapper": "", + "call-mediator": "", + "property": "", + "log": "", + "in-sequence": "", + "out-sequence": "", + "foreach": "", + "mapping": "", + "reduce": "", + "continue": "", + "integration": "", + "namespace": "", + "dollar": "", + "aggregate": "", + "bean": "", + "event-simulator": "", + "activesync": " ", + "kiosk": " " } \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/scss/_mixin.scss b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/scss/_mixin.scss old mode 100644 new mode 100755 similarity index 92% rename from components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/scss/_mixin.scss rename to components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/scss/_mixin.scss index fb6ac90f8b..56ac8bba23 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/scss/_mixin.scss +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-entgra-1.4.0/scss/_mixin.scss @@ -1,1252 +1,1336 @@ -/*! -~ Copyright (c) WSO2 Inc. (http://wso2.com) All Rights Reserved. -~ -~ Licensed 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. -*/ - -%icon-base { - &:before { - font-family: "font-wso2"; - -webkit-font-smoothing: antialiased; - } - b { - // hide text - height: 0; - display: block; - text-indent: 100%; - white-space: nowrap; - overflow: hidden; - } -} - -@mixin font-wso2($icon) { - @extend %icon-base; - - - @if ($icon == "abort") { - content:"\e72a"; - } - - @else if ($icon == "action-invoke") { - content:"\e6fe"; - } - - @else if ($icon == "action") { - content:"\e709"; - } - - @else if ($icon == "activate") { - content:"\e6cf"; - } - - @else if ($icon == "add") { - content:"\e615"; - } - - @else if ($icon == "airplay") { - content:"\e600"; - } - - @else if ($icon == "alarm") { - content:"\e6c2"; - } - - @else if ($icon == "alert") { - content:"\e6be"; - } - - @else if ($icon == "analytics-extensions") { - content:"\e6e2"; - } - - @else if ($icon == "android-logcat") { - content:"\e72c"; - } - - @else if ($icon == "android-sense") { - content:"\e72d"; - } - - @else if ($icon == "android") { - content:"\e606"; - } - - @else if ($icon == "annotation") { - content:"\e6e6"; - } - - @else if ($icon == "api") { - content:"\e601"; - } - - @else if ($icon == "apn") { - content:"\e602"; - } - - @else if ($icon == "apple") { - content:"\e604"; - } - - @else if ($icon == "application") { - content:"\e608"; - } - - @else if ($icon == "arduino") { - content:"\e6ab"; - } - - @else if ($icon == "assign") { - content:"\e6ff"; - } - - @else if ($icon == "ballerina-service") { - content:"\e729"; - } - - @else if ($icon == "ballerina") { - content:"\e728"; - } - - @else if ($icon == "bar-chart") { - content:"\e690"; - } - - @else if ($icon == "battery") { - content:"\e60a"; - } - - @else if ($icon == "blank-document") { - content:"\e60c"; - } - - @else if ($icon == "block") { - content:"\e695"; - } - - @else if ($icon == "bookmark") { - content:"\e60d"; - } - - @else if ($icon == "bpel") { - content:"\e60e"; - } - - @else if ($icon == "bpmn") { - content:"\e60f"; - } - - @else if ($icon == "break") { - content:"\e721"; - } - - @else if ($icon == "bug") { - content:"\e611"; - } - - @else if ($icon == "build") { - content:"\e6c1"; - } - - @else if ($icon == "calendar") { - content:"\e612"; - } - - @else if ($icon == "camera") { - content:"\e613"; - } - - @else if ($icon == "cancel") { - content:"\e618"; - } - - @else if ($icon == "carbon") { - content:"\e6c5"; - } - - @else if ($icon == "chat") { - content:"\e65b"; - } - - @else if ($icon == "check") { - content:"\e617"; - } - - @else if ($icon == "checklist") { - content:"\e619"; - } - - @else if ($icon == "circle-outline") { - content:"\e61f"; - } - - @else if ($icon == "circle") { - content:"\e61a"; - } - - @else if ($icon == "clear") { - content:"\e61b"; - } - - @else if ($icon == "clock") { - content:"\e61d"; - } - - @else if ($icon == "cloud") { - content:"\e61e"; - } - - @else if ($icon == "code-view") { - content:"\e70e"; - } - - @else if ($icon == "code") { - content:"\e6f1"; - } - - @else if ($icon == "comment") { - content:"\e710"; - } - - @else if ($icon == "compare") { - content:"\e610"; - } - - @else if ($icon == "computer") { - content:"\e653"; - } - - @else if ($icon == "configarations") { - content:"\e609"; - } - - @else if ($icon == "connector") { - content:"\e700"; - } - - @else if ($icon == "console") { - content:"\e71d"; - } - - @else if ($icon == "constant") { - content:"\e701"; - } - - @else if ($icon == "contact") { - content:"\e620"; - } - - @else if ($icon == "contract") { - content:"\e614"; - } - - @else if ($icon == "copy") { - content:"\e621"; - } - - @else if ($icon == "cut") { - content:"\e6f2"; - } - - @else if ($icon == "dashboard") { - content:"\e622"; - } - - @else if ($icon == "database") { - content:"\e623"; - } - - @else if ($icon == "delete") { - content:"\e624"; - } - - @else if ($icon == "depend") { - content:"\e6c6"; - } - - @else if ($icon == "deploy") { - content:"\e625"; - } - - @else if ($icon == "deprecate") { - content:"\e6cb"; - } - - @else if ($icon == "design-view") { - content:"\e70f"; - } - - @else if ($icon == "devices") { - content:"\e704"; - } - - @else if ($icon == "dgm-action-invoke") { - content:"\e712"; - } - - @else if ($icon == "dgm-action") { - content:"\e711"; - } - - @else if ($icon == "dgm-connector") { - content:"\e6f4"; - } - - @else if ($icon == "dgm-constant-definition") { - content:"\e6f5"; - } - - @else if ($icon == "dgm-fork") { - content:"\e6e7"; - } - - @else if ($icon == "dgm-header") { - content:"\e6e8"; - } - - @else if ($icon == "dgm-if-else") { - content:"\e6e9"; - } - - @else if ($icon == "dgm-import") { - content:"\e717"; - } - - @else if ($icon == "dgm-lifeline") { - content:"\e6ea"; - } - - @else if ($icon == "dgm-logger") { - content:"\e6eb"; - } - - @else if ($icon == "dgm-resource") { - content:"\e6f6"; - } - - @else if ($icon == "dgm-service") { - content:"\e6f7"; - } - - @else if ($icon == "dgm-try-catch") { - content:"\e6ec"; - } - - @else if ($icon == "dgm-type-convertor") { - content:"\e6f8"; - } - - @else if ($icon == "dgm-type") { - content:"\e6f9"; - } - - @else if ($icon == "dgm-while") { - content:"\e707"; - } - - @else if ($icon == "dial-up") { - content:"\e627"; - } - - @else if ($icon == "disabled") { - content:"\e6d1"; - } - - @else if ($icon == "display") { - content:"\e626"; - } - - @else if ($icon == "docker") { - content:"\e70c"; - } - - @else if ($icon == "document") { - content:"\e628"; - } - - @else if ($icon == "down-arrow") { - content:"\e689"; - } - - @else if ($icon == "down") { - content:"\e685"; - } - - @else if ($icon == "download") { - content:"\e65f"; - } - - @else if ($icon == "dss") { - content:"\e62a"; - } - - @else if ($icon == "ebook") { - content:"\e62b"; - } - - @else if ($icon == "edit") { - content:"\e62c"; - } - - @else if ($icon == "ellipsis") { - content:"\e629"; - } - - @else if ($icon == "endpoint") { - content:"\e62d"; - } - - @else if ($icon == "enterprise") { - content:"\e6b6"; - } - - @else if ($icon == "error") { - content:"\e630"; - } - - @else if ($icon == "esb-connector") { - content:"\e6e3"; - } - - @else if ($icon == "expand") { - content:"\e61c"; - } - - @else if ($icon == "export") { - content:"\e631"; - } - - @else if ($icon == "extensions") { - content:"\e6e4"; - } - - @else if ($icon == "facebook") { - content:"\e6d3"; - } - - @else if ($icon == "factory-reset") { - content:"\e632"; - } - - @else if ($icon == "fan") { - content:"\e678"; - } - - @else if ($icon == "faq") { - content:"\e62f"; - } - - @else if ($icon == "file-browse") { - content:"\e633"; - } - - @else if ($icon == "filter") { - content:"\e634"; - } - - @else if ($icon == "folder-open") { - content:"\e70b"; - } - - @else if ($icon == "folder") { - content:"\e62e"; - } - - @else if ($icon == "fork-join") { - content:"\e720"; - } - - @else if ($icon == "format") { - content:"\e6fa"; - } - - @else if ($icon == "forum") { - content:"\e636"; - } - - @else if ($icon == "function-invoke") { - content:"\e713"; - } - - @else if ($icon == "function") { - content:"\e6fb"; - } - - @else if ($icon == "gadget") { - content:"\e637"; - } - - @else if ($icon == "geo-fence-inbound") { - content:"\e72e"; - } - - @else if ($icon == "geo-fence-outbound") { - content:"\e72f"; - } - - @else if ($icon == "github") { - content:"\e6d4"; - } - - @else if ($icon == "globe") { - content:"\e697"; - } - - @else if ($icon == "google-docs") { - content:"\e6d6"; - } - - @else if ($icon == "google-drive") { - content:"\e6da"; - } - - @else if ($icon == "google-plus") { - content:"\e6d9"; - } - - @else if ($icon == "google-sheets") { - content:"\e6d7"; - } - - @else if ($icon == "google-slides") { - content:"\e6d8"; - } - - @else if ($icon == "google") { - content:"\e6d5"; - } - - @else if ($icon == "grid") { - content:"\e638"; - } - - @else if ($icon == "grip") { - content:"\e6b7"; - } - - @else if ($icon == "group") { - content:"\e6af"; - } - - @else if ($icon == "hardware") { - content:"\e6a9"; - } - - @else if ($icon == "hdd") { - content:"\e639"; - } - - @else if ($icon == "heart") { - content:"\e6c3"; - } - - @else if ($icon == "hide") { - content:"\e6d2"; - } - - @else if ($icon == "home") { - content:"\e63a"; - } - - @else if ($icon == "hour-glass") { - content:"\e63b"; - } - - @else if ($icon == "html") { - content:"\e69d"; - } - - @else if ($icon == "http") { - content:"\e705"; - } - - @else if ($icon == "image") { - content:"\e70a"; - } - - @else if ($icon == "import") { - content:"\e63c"; - } - - @else if ($icon == "incoming-call") { - content:"\e63d"; - } - - @else if ($icon == "info") { - content:"\e63e"; - } - - @else if ($icon == "instagram") { - content:"\e6db"; - } - - @else if ($icon == "invitation") { - content:"\e63f"; - } - - @else if ($icon == "invoke") { - content:"\e6ed"; - } - - @else if ($icon == "is-connector") { - content:"\e6e5"; - } - - @else if ($icon == "iterate") { - content:"\e71f"; - } - - @else if ($icon == "jaggery") { - content:"\e640"; - } - - @else if ($icon == "java-spring") { - content:"\e644"; - } - - @else if ($icon == "java") { - content:"\e641"; - } - - @else if ($icon == "javaee") { - content:"\e642"; - } - - @else if ($icon == "javascript") { - content:"\e643"; - } - - @else if ($icon == "jaxrs") { - content:"\e645"; - } - - @else if ($icon == "jaxws") { - content:"\e6c7"; - } - - @else if ($icon == "jquery") { - content:"\e646"; - } - - @else if ($icon == "key") { - content:"\e647"; - } - - @else if ($icon == "laptop") { - content:"\e648"; - } - - @else if ($icon == "layout") { - content:"\e6bf"; - } - - @else if ($icon == "ldap") { - content:"\e649"; - } - - @else if ($icon == "left-arrow") { - content:"\e68a"; - } - - @else if ($icon == "left") { - content:"\e686"; - } - - @else if ($icon == "lifecycle") { - content:"\e64a"; - } - - @else if ($icon == "light") { - content:"\e680"; - } - - @else if ($icon == "linkedin") { - content:"\e6dc"; - } - - @else if ($icon == "list-sort") { - content:"\e64d"; - } - - @else if ($icon == "list") { - content:"\e64c"; - } - - @else if ($icon == "loader") { - content:"\e6b4"; - } - - @else if ($icon == "loader2") { - content:"\e6ba"; - } - - @else if ($icon == "loader3") { - content:"\e6bb"; - } - - @else if ($icon == "loader4") { - content:"\e6bc"; - } - - @else if ($icon == "loader5") { - content:"\e6bd"; - } - - @else if ($icon == "lock") { - content:"\e64e"; - } - - @else if ($icon == "logical") { - content:"\e702"; - } - - @else if ($icon == "mail") { - content:"\e64f"; - } - - @else if ($icon == "main-function") { - content:"\e706"; - } - - @else if ($icon == "map-location") { - content:"\e650"; - } - - @else if ($icon == "menu") { - content:"\e651"; - } - - @else if ($icon == "message") { - content:"\e635"; - } - - @else if ($icon == "micro-services") { - content:"\e6ce"; - } - - @else if ($icon == "minus") { - content:"\e616"; - } - - @else if ($icon == "mobile") { - content:"\e652"; - } - - @else if ($icon == "ms-document") { - content:"\e654"; - } - - @else if ($icon == "mute") { - content:"\e655"; - } - - @else if ($icon == "nodejs") { - content:"\e656"; - } - - @else if ($icon == "notification") { - content:"\e60b"; - } - - @else if ($icon == "organization") { - content:"\e6ac"; - } - - @else if ($icon == "own") { - content:"\e6c8"; - } - - @else if ($icon == "package") { - content:"\e6fd"; - } - - @else if ($icon == "pages") { - content:"\e6c0"; - } - - @else if ($icon == "paste") { - content:"\e658"; - } - - @else if ($icon == "pdf") { - content:"\e659"; - } - - @else if ($icon == "pending") { - content:"\e727"; - } - - @else if ($icon == "php") { - content:"\e6c9"; - } - - @else if ($icon == "pie-chart") { - content:"\e65a"; - } - - @else if ($icon == "pinterest") { - content:"\e6dd"; - } - - @else if ($icon == "policy") { - content:"\e67d"; - } - - @else if ($icon == "polygon") { - content:"\e70d"; - } - - @else if ($icon == "prototype") { - content:"\e6cc"; - } - - @else if ($icon == "proxy") { - content:"\e699"; - } - - @else if ($icon == "public") { - content:"\e6ad"; - } - - @else if ($icon == "publish") { - content:"\e65c"; - } - - @else if ($icon == "question") { - content:"\e6b0"; - } - - @else if ($icon == "raspberry") { - content:"\e6aa"; - } - - @else if ($icon == "redo") { - content:"\e65d"; - } - - @else if ($icon == "refresh") { - content:"\e692"; - } - - @else if ($icon == "register") { - content:"\e65e"; - } - - @else if ($icon == "rename") { - content:"\e6fc"; - } - - @else if ($icon == "reply") { - content:"\e714"; - } - - @else if ($icon == "resource") { - content:"\e660"; - } - - @else if ($icon == "rest-api") { - content:"\e661"; - } - - @else if ($icon == "rest-service") { - content:"\e662"; - } - - @else if ($icon == "resume") { - content:"\e71e"; - } - - @else if ($icon == "retire") { - content:"\e6cd"; - } - - @else if ($icon == "return") { - content:"\e715"; - } - - @else if ($icon == "retweet") { - content:"\e6b9"; - } - - @else if ($icon == "right-arrow") { - content:"\e68b"; - } - - @else if ($icon == "right") { - content:"\e687"; - } - - @else if ($icon == "ringing") { - content:"\e694"; - } - - @else if ($icon == "rules") { - content:"\e664"; - } - - @else if ($icon == "run") { - content:"\e708"; - } - - @else if ($icon == "save") { - content:"\e665"; - } - - @else if ($icon == "scep") { - content:"\e666"; - } - - @else if ($icon == "schema") { - content:"\e667"; - } - - @else if ($icon == "search") { - content:"\e668"; - } - - @else if ($icon == "security-policy") { - content:"\e67e"; - } - - @else if ($icon == "security") { - content:"\e669"; - } - - @else if ($icon == "send") { - content:"\e66a"; - } - - @else if ($icon == "sequence") { - content:"\e66b"; - } - - @else if ($icon == "server") { - content:"\e66c"; - } - - @else if ($icon == "service-provider") { - content:"\e66e"; - } - - @else if ($icon == "service") { - content:"\e66d"; - } - - @else if ($icon == "settings") { - content:"\e66f"; - } - - @else if ($icon == "share") { - content:"\e670"; - } - - @else if ($icon == "shell") { - content:"\e730"; - } - - @else if ($icon == "shortcut") { - content:"\e725"; - } - - @else if ($icon == "sign-in") { - content:"\e671"; - } - - @else if ($icon == "sign-out") { - content:"\e6b8"; - } - - @else if ($icon == "skype") { - content:"\e6de"; - } - - @else if ($icon == "slash") { - content:"\e6e1"; - } - - @else if ($icon == "soap") { - content:"\e672"; - } - - @else if ($icon == "sort-down") { - content:"\e663"; - } - - @else if ($icon == "sort-up") { - content:"\e64b"; - } - - @else if ($icon == "sort") { - content:"\e673"; - } - - @else if ($icon == "speed-alert") { - content:"\e731"; - } - - @else if ($icon == "square-outline") { - content:"\e6b2"; - } - - @else if ($icon == "square") { - content:"\e6b1"; - } - - @else if ($icon == "star") { - content:"\e674"; - } - - @else if ($icon == "start") { - content:"\e718"; - } - - @else if ($icon == "statistics") { - content:"\e675"; - } - - @else if ($icon == "stepin") { - content:"\e719"; - } - - @else if ($icon == "stepout") { - content:"\e71a"; - } - - @else if ($icon == "stepover") { - content:"\e71b"; - } - - @else if ($icon == "stop") { - content:"\e71c"; - } - - @else if ($icon == "store") { - content:"\e676"; - } - - @else if ($icon == "struct") { - content:"\e716"; - } - - @else if ($icon == "subscribe") { - content:"\e677"; - } - - @else if ($icon == "success") { - content:"\e657"; - } - - @else if ($icon == "swagger") { - content:"\e679"; - } - - @else if ($icon == "sync") { - content:"\e6b3"; - } - - @else if ($icon == "table") { - content:"\e6c4"; - } - - @else if ($icon == "tag") { - content:"\e67a"; - } - - @else if ($icon == "task") { - content:"\e67b"; - } - - @else if ($icon == "text") { - content:"\e67c"; - } - - @else if ($icon == "theme") { - content:"\e726"; - } - - @else if ($icon == "throttling-policy") { - content:"\e67f"; - } - - @else if ($icon == "throw") { - content:"\e722"; - } - - @else if ($icon == "tiles") { - content:"\e681"; - } - - @else if ($icon == "transaction") { - content:"\e72b"; - } - - @else if ($icon == "try-catch") { - content:"\e703"; - } - - @else if ($icon == "twitter") { - content:"\e6df"; - } - - @else if ($icon == "type-converter") { - content:"\e6f3"; - } - - @else if ($icon == "uncheck") { - content:"\e682"; - } - - @else if ($icon == "undo") { - content:"\e683"; - } - - @else if ($icon == "ungroup") { - content:"\e6b5"; - } - - @else if ($icon == "unmute") { - content:"\e6ae"; - } - - @else if ($icon == "up-arrow") { - content:"\e688"; - } - - @else if ($icon == "up") { - content:"\e684"; - } - - @else if ($icon == "upload") { - content:"\e68c"; - } - - @else if ($icon == "uri") { - content:"\e68d"; - } - - @else if ($icon == "usb-drive") { - content:"\e68e"; - } - - @else if ($icon == "use") { - content:"\e6ca"; - } - - @else if ($icon == "user") { - content:"\e68f"; - } - - @else if ($icon == "variable") { - content:"\e6ee"; - } - - @else if ($icon == "view") { - content:"\e691"; - } - - @else if ($icon == "vpn") { - content:"\e603"; - } - - @else if ($icon == "wadl") { - content:"\e6a1"; - } - - @else if ($icon == "war") { - content:"\e69e"; - } - - @else if ($icon == "warning") { - content:"\e693"; - } - - @else if ($icon == "web-app") { - content:"\e696"; - } - - @else if ($icon == "web-clip") { - content:"\e698"; - } - - @else if ($icon == "web-service") { - content:"\e69a"; - } - - @else if ($icon == "website") { - content:"\e69b"; - } - - @else if ($icon == "wifi") { - content:"\e607"; - } - - @else if ($icon == "windows") { - content:"\e605"; - } - - @else if ($icon == "worker-invoke") { - content:"\e723"; - } - - @else if ($icon == "worker-reply") { - content:"\e724"; - } - - @else if ($icon == "worker") { - content:"\e6ef"; - } - - @else if ($icon == "wsdl") { - content:"\e6a0"; - } - - @else if ($icon == "wso2-logo") { - content:"\e6a7"; - } - - @else if ($icon == "wso2") { - content:"\e6a8"; - } - - @else if ($icon == "xacml") { - content:"\e69f"; - } - - @else if ($icon == "xml") { - content:"\e69c"; - } - - @else if ($icon == "xq") { - content:"\e6a2"; - } - - @else if ($icon == "xsd") { - content:"\e6a3"; - } - - @else if ($icon == "xslt") { - content:"\e6a4"; - } - - @else if ($icon == "youtube") { - content:"\e6e0"; - } - - @else if ($icon == "zoom-in") { - content:"\e6a5"; - } - - @else if ($icon == "zoom-out") { - content:"\e6a6"; - } - +/*! +~ Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved. +~ +~ Licensed 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. +*/ + +%icon-base { + &:before { + font-family: "font-entgra"; + -webkit-font-smoothing: antialiased; + } + b { + // hide text + height: 0; + display: block; + text-indent: 100%; + white-space: nowrap; + overflow: hidden; + } +} + +@mixin font-entgra($icon) { + @extend %icon-base; + + + @if ($icon == "abort") { + content:"\e72a"; + } + + @else if ($icon == "action-invoke") { + content:"\e6fe"; + } + + @else if ($icon == "action") { + content:"\e709"; + } + + @else if ($icon == "activate") { + content:"\e6cf"; + } + + @else if ($icon == "activesync") { + content:"\e745"; + } + + @else if ($icon == "add") { + content:"\e615"; + } + + @else if ($icon == "aggregate") { + content:"\e742"; + } + + @else if ($icon == "airplay") { + content:"\e600"; + } + + @else if ($icon == "alarm") { + content:"\e6c2"; + } + + @else if ($icon == "alert") { + content:"\e6be"; + } + + @else if ($icon == "analytics-extensions") { + content:"\e6e2"; + } + + @else if ($icon == "android-logcat") { + content:"\e72c"; + } + + @else if ($icon == "android-sense") { + content:"\e72d"; + } + + @else if ($icon == "android") { + content:"\e606"; + } + + @else if ($icon == "annotation") { + content:"\e6e6"; + } + + @else if ($icon == "api") { + content:"\e601"; + } + + @else if ($icon == "apn") { + content:"\e602"; + } + + @else if ($icon == "apple") { + content:"\e604"; + } + + @else if ($icon == "application") { + content:"\e608"; + } + + @else if ($icon == "arduino") { + content:"\e6ab"; + } + + @else if ($icon == "assign") { + content:"\e6ff"; + } + + @else if ($icon == "ballerina-service") { + content:"\e729"; + } + + @else if ($icon == "ballerina") { + content:"\e728"; + } + + @else if ($icon == "bar-chart") { + content:"\e690"; + } + + @else if ($icon == "battery") { + content:"\e60a"; + } + + @else if ($icon == "bean") { + content:"\e743"; + } + + @else if ($icon == "blank-document") { + content:"\e60c"; + } + + @else if ($icon == "block") { + content:"\e695"; + } + + @else if ($icon == "bookmark") { + content:"\e60d"; + } + + @else if ($icon == "bpel") { + content:"\e60e"; + } + + @else if ($icon == "bpmn") { + content:"\e60f"; + } + + @else if ($icon == "break") { + content:"\e721"; + } + + @else if ($icon == "bug") { + content:"\e611"; + } + + @else if ($icon == "build") { + content:"\e6c1"; + } + + @else if ($icon == "calendar") { + content:"\e612"; + } + + @else if ($icon == "call-mediator") { + content:"\e736"; + } + + @else if ($icon == "camera") { + content:"\e613"; + } + + @else if ($icon == "cancel") { + content:"\e618"; + } + + @else if ($icon == "carbon") { + content:"\e6c5"; + } + + @else if ($icon == "chat") { + content:"\e65b"; + } + + @else if ($icon == "check") { + content:"\e617"; + } + + @else if ($icon == "checklist") { + content:"\e619"; + } + + @else if ($icon == "circle-outline") { + content:"\e61f"; + } + + @else if ($icon == "circle") { + content:"\e61a"; + } + + @else if ($icon == "clear") { + content:"\e61b"; + } + + @else if ($icon == "clock") { + content:"\e61d"; + } + + @else if ($icon == "cloud") { + content:"\e61e"; + } + + @else if ($icon == "code-view") { + content:"\e70e"; + } + + @else if ($icon == "code") { + content:"\e6f1"; + } + + @else if ($icon == "comment") { + content:"\e710"; + } + + @else if ($icon == "compare") { + content:"\e610"; + } + + @else if ($icon == "computer") { + content:"\e653"; + } + + @else if ($icon == "configurations") { + content:"\e609"; + } + + @else if ($icon == "connector") { + content:"\e700"; + } + + @else if ($icon == "console") { + content:"\e71d"; + } + + @else if ($icon == "constant") { + content:"\e701"; + } + + @else if ($icon == "contact") { + content:"\e620"; + } + + @else if ($icon == "continue") { + content:"\e73e"; + } + + @else if ($icon == "contract") { + content:"\e614"; + } + + @else if ($icon == "copy") { + content:"\e621"; + } + + @else if ($icon == "cut") { + content:"\e6f2"; + } + + @else if ($icon == "dashboard") { + content:"\e622"; + } + + @else if ($icon == "data-mapper") { + content:"\e735"; + } + + @else if ($icon == "database") { + content:"\e623"; + } + + @else if ($icon == "delete") { + content:"\e624"; + } + + @else if ($icon == "depend") { + content:"\e6c6"; + } + + @else if ($icon == "deploy") { + content:"\e625"; + } + + @else if ($icon == "deprecate") { + content:"\e6cb"; + } + + @else if ($icon == "design-view") { + content:"\e70f"; + } + + @else if ($icon == "devices") { + content:"\e704"; + } + + @else if ($icon == "dgm-action-invoke") { + content:"\e712"; + } + + @else if ($icon == "dgm-action") { + content:"\e711"; + } + + @else if ($icon == "dgm-connector") { + content:"\e6f4"; + } + + @else if ($icon == "dgm-constant-definition") { + content:"\e6f5"; + } + + @else if ($icon == "dgm-fork") { + content:"\e6e7"; + } + + @else if ($icon == "dgm-header") { + content:"\e6e8"; + } + + @else if ($icon == "dgm-if-else") { + content:"\e6e9"; + } + + @else if ($icon == "dgm-import") { + content:"\e717"; + } + + @else if ($icon == "dgm-lifeline") { + content:"\e6ea"; + } + + @else if ($icon == "dgm-logger") { + content:"\e6eb"; + } + + @else if ($icon == "dgm-resource") { + content:"\e6f6"; + } + + @else if ($icon == "dgm-service") { + content:"\e6f7"; + } + + @else if ($icon == "dgm-try-catch") { + content:"\e6ec"; + } + + @else if ($icon == "dgm-type-convertor") { + content:"\e6f8"; + } + + @else if ($icon == "dgm-type") { + content:"\e6f9"; + } + + @else if ($icon == "dgm-while") { + content:"\e707"; + } + + @else if ($icon == "dial-up") { + content:"\e627"; + } + + @else if ($icon == "disabled") { + content:"\e6d1"; + } + + @else if ($icon == "display") { + content:"\e626"; + } + + @else if ($icon == "docker") { + content:"\e70c"; + } + + @else if ($icon == "document") { + content:"\e628"; + } + + @else if ($icon == "dollar") { + content:"\e741"; + } + + @else if ($icon == "down-arrow") { + content:"\e689"; + } + + @else if ($icon == "down") { + content:"\e685"; + } + + @else if ($icon == "download") { + content:"\e65f"; + } + + @else if ($icon == "dss") { + content:"\e62a"; + } + + @else if ($icon == "ebook") { + content:"\e62b"; + } + + @else if ($icon == "edit") { + content:"\e62c"; + } + + @else if ($icon == "ellipsis") { + content:"\e629"; + } + + @else if ($icon == "endpoint") { + content:"\e62d"; + } + + @else if ($icon == "enterprise") { + content:"\e6b6"; + } + + @else if ($icon == "error") { + content:"\e630"; + } + + @else if ($icon == "esb-connector") { + content:"\e6e3"; + } + + @else if ($icon == "event-simulator") { + content:"\e744"; + } + + @else if ($icon == "expand") { + content:"\e61c"; + } + + @else if ($icon == "export") { + content:"\e631"; + } + + @else if ($icon == "extensions") { + content:"\e6e4"; + } + + @else if ($icon == "facebook") { + content:"\e6d3"; + } + + @else if ($icon == "factory-reset") { + content:"\e632"; + } + + @else if ($icon == "fan") { + content:"\e678"; + } + + @else if ($icon == "faq") { + content:"\e62f"; + } + + @else if ($icon == "file-browse") { + content:"\e633"; + } + + @else if ($icon == "filter") { + content:"\e634"; + } + + @else if ($icon == "folder-open") { + content:"\e70b"; + } + + @else if ($icon == "folder") { + content:"\e62e"; + } + + @else if ($icon == "foreach") { + content:"\e73ab"; + } + + @else if ($icon == "fork-join") { + content:"\e720"; + } + + @else if ($icon == "format") { + content:"\e6fa"; + } + + @else if ($icon == "forum") { + content:"\e636"; + } + + @else if ($icon == "function-invoke") { + content:"\e713"; + } + + @else if ($icon == "function") { + content:"\e6fb"; + } + + @else if ($icon == "gadget") { + content:"\e637"; + } + + @else if ($icon == "geo-fence-inbound") { + content:"\e72e"; + } + + @else if ($icon == "geo-fence-outbound") { + content:"\e72f"; + } + + @else if ($icon == "github") { + content:"\e6d4"; + } + + @else if ($icon == "globe") { + content:"\e697"; + } + + @else if ($icon == "google-docs") { + content:"\e6d6"; + } + + @else if ($icon == "google-drive") { + content:"\e6da"; + } + + @else if ($icon == "google-glass") { + content:"\e732"; + } + + @else if ($icon == "google-plus") { + content:"\e6d9"; + } + + @else if ($icon == "google-sheets") { + content:"\e6d7"; + } + + @else if ($icon == "google-slides") { + content:"\e6d8"; + } + + @else if ($icon == "google") { + content:"\e6d5"; + } + + @else if ($icon == "grid") { + content:"\e638"; + } + + @else if ($icon == "grip") { + content:"\e6b7"; + } + + @else if ($icon == "group") { + content:"\e6af"; + } + + @else if ($icon == "hardware") { + content:"\e6a9"; + } + + @else if ($icon == "hdd") { + content:"\e639"; + } + + @else if ($icon == "header") { + content:"\e734"; + } + + @else if ($icon == "heart") { + content:"\e6c3"; + } + + @else if ($icon == "hide") { + content:"\e6d2"; + } + + @else if ($icon == "home") { + content:"\e63a"; + } + + @else if ($icon == "hour-glass") { + content:"\e63b"; + } + + @else if ($icon == "html") { + content:"\e69d"; + } + + @else if ($icon == "http") { + content:"\e705"; + } + + @else if ($icon == "image") { + content:"\e70a"; + } + + @else if ($icon == "import") { + content:"\e63c"; + } + + @else if ($icon == "in-sequence") { + content:"\e739"; + } + + @else if ($icon == "incoming-call") { + content:"\e63d"; + } + + @else if ($icon == "info") { + content:"\e63e"; + } + + @else if ($icon == "instagram") { + content:"\e6db"; + } + + @else if ($icon == "integration") { + content:"\e73f"; + } + + @else if ($icon == "invitation") { + content:"\e63f"; + } + + @else if ($icon == "invoke") { + content:"\e6ed"; + } + + @else if ($icon == "is-connector") { + content:"\e6e5"; + } + + @else if ($icon == "iterate") { + content:"\e71f"; + } + + @else if ($icon == "jaggery") { + content:"\e640"; + } + + @else if ($icon == "java-spring") { + content:"\e644"; + } + + @else if ($icon == "java") { + content:"\e641"; + } + + @else if ($icon == "javaee") { + content:"\e642"; + } + + @else if ($icon == "javascript") { + content:"\e643"; + } + + @else if ($icon == "jaxrs") { + content:"\e645"; + } + + @else if ($icon == "jaxws") { + content:"\e6c7"; + } + + @else if ($icon == "jquery") { + content:"\e646"; + } + + @else if ($icon == "key") { + content:"\e647"; + } + + @else if ($icon == "kiosk") { + content:"\e746"; + } + + @else if ($icon == "laptop") { + content:"\e648"; + } + + @else if ($icon == "layout") { + content:"\e6bf"; + } + + @else if ($icon == "ldap") { + content:"\e649"; + } + + @else if ($icon == "left-arrow") { + content:"\e68a"; + } + + @else if ($icon == "left") { + content:"\e686"; + } + + @else if ($icon == "lifecycle") { + content:"\e64a"; + } + + @else if ($icon == "light") { + content:"\e680"; + } + + @else if ($icon == "linkedin") { + content:"\e6dc"; + } + + @else if ($icon == "list-sort") { + content:"\e64d"; + } + + @else if ($icon == "list") { + content:"\e64c"; + } + + @else if ($icon == "loader") { + content:"\e6b4"; + } + + @else if ($icon == "loader2") { + content:"\e6ba"; + } + + @else if ($icon == "loader3") { + content:"\e6bb"; + } + + @else if ($icon == "loader4") { + content:"\e6bc"; + } + + @else if ($icon == "loader5") { + content:"\e6bd"; + } + + @else if ($icon == "lock") { + content:"\e64e"; + } + + @else if ($icon == "log") { + content:"\e738"; + } + + @else if ($icon == "logical") { + content:"\e702"; + } + + @else if ($icon == "mail") { + content:"\e64f"; + } + + @else if ($icon == "main-function") { + content:"\e706"; + } + + @else if ($icon == "map-location") { + content:"\e650"; + } + + @else if ($icon == "mapping") { + content:"\e73c"; + } + + @else if ($icon == "menu") { + content:"\e651"; + } + + @else if ($icon == "message") { + content:"\e635"; + } + + @else if ($icon == "micro-services") { + content:"\e6ce"; + } + + @else if ($icon == "minus") { + content:"\e616"; + } + + @else if ($icon == "mobile") { + content:"\e652"; + } + + @else if ($icon == "ms-document") { + content:"\e654"; + } + + @else if ($icon == "mute") { + content:"\e655"; + } + + @else if ($icon == "namespace") { + content:"\e740"; + } + + @else if ($icon == "nodejs") { + content:"\e656"; + } + + @else if ($icon == "notification") { + content:"\e60b"; + } + + @else if ($icon == "organization") { + content:"\e6ac"; + } + + @else if ($icon == "out-sequence") { + content:"\e73a"; + } + + @else if ($icon == "own") { + content:"\e6c8"; + } + + @else if ($icon == "package") { + content:"\e6fd"; + } + + @else if ($icon == "pages") { + content:"\e6c0"; + } + + @else if ($icon == "paste") { + content:"\e658"; + } + + @else if ($icon == "payload-factory") { + content:"\e733"; + } + + @else if ($icon == "pdf") { + content:"\e659"; + } + + @else if ($icon == "pending") { + content:"\e727"; + } + + @else if ($icon == "php") { + content:"\e6c9"; + } + + @else if ($icon == "pie-chart") { + content:"\e65a"; + } + + @else if ($icon == "pinterest") { + content:"\e6dd"; + } + + @else if ($icon == "policy") { + content:"\e67d"; + } + + @else if ($icon == "polygon") { + content:"\e70d"; + } + + @else if ($icon == "property") { + content:"\e737"; + } + + @else if ($icon == "prototype") { + content:"\e6cc"; + } + + @else if ($icon == "proxy") { + content:"\e699"; + } + + @else if ($icon == "public") { + content:"\e6ad"; + } + + @else if ($icon == "publish") { + content:"\e65c"; + } + + @else if ($icon == "question") { + content:"\e6b0"; + } + + @else if ($icon == "raspberry") { + content:"\e6aa"; + } + + @else if ($icon == "redo") { + content:"\e65d"; + } + + @else if ($icon == "reduce") { + content:"\e73d"; + } + + @else if ($icon == "refresh") { + content:"\e692"; + } + + @else if ($icon == "register") { + content:"\e65e"; + } + + @else if ($icon == "rename") { + content:"\e6fc"; + } + + @else if ($icon == "reply") { + content:"\e714"; + } + + @else if ($icon == "resource") { + content:"\e660"; + } + + @else if ($icon == "rest-api") { + content:"\e661"; + } + + @else if ($icon == "rest-service") { + content:"\e662"; + } + + @else if ($icon == "resume") { + content:"\e71e"; + } + + @else if ($icon == "retire") { + content:"\e6cd"; + } + + @else if ($icon == "return") { + content:"\e715"; + } + + @else if ($icon == "retweet") { + content:"\e6b9"; + } + + @else if ($icon == "right-arrow") { + content:"\e68b"; + } + + @else if ($icon == "right") { + content:"\e687"; + } + + @else if ($icon == "ringing") { + content:"\e694"; + } + + @else if ($icon == "rules") { + content:"\e664"; + } + + @else if ($icon == "run") { + content:"\e708"; + } + + @else if ($icon == "save") { + content:"\e665"; + } + + @else if ($icon == "scep") { + content:"\e666"; + } + + @else if ($icon == "schema") { + content:"\e667"; + } + + @else if ($icon == "search") { + content:"\e668"; + } + + @else if ($icon == "security-policy") { + content:"\e67e"; + } + + @else if ($icon == "security") { + content:"\e669"; + } + + @else if ($icon == "send") { + content:"\e66a"; + } + + @else if ($icon == "sequence") { + content:"\e66b"; + } + + @else if ($icon == "server") { + content:"\e66c"; + } + + @else if ($icon == "service-provider") { + content:"\e66e"; + } + + @else if ($icon == "service") { + content:"\e66d"; + } + + @else if ($icon == "settings") { + content:"\e66f"; + } + + @else if ($icon == "share") { + content:"\e670"; + } + + @else if ($icon == "shell") { + content:"\e730"; + } + + @else if ($icon == "shortcut") { + content:"\e725"; + } + + @else if ($icon == "sign-in") { + content:"\e671"; + } + + @else if ($icon == "sign-out") { + content:"\e6b8"; + } + + @else if ($icon == "skype") { + content:"\e6de"; + } + + @else if ($icon == "slash") { + content:"\e6e1"; + } + + @else if ($icon == "soap") { + content:"\e672"; + } + + @else if ($icon == "sort-down") { + content:"\e663"; + } + + @else if ($icon == "sort-up") { + content:"\e64b"; + } + + @else if ($icon == "sort") { + content:"\e673"; + } + + @else if ($icon == "speed-alert") { + content:"\e731"; + } + + @else if ($icon == "square-outline") { + content:"\e6b2"; + } + + @else if ($icon == "square") { + content:"\e6b1"; + } + + @else if ($icon == "star") { + content:"\e674"; + } + + @else if ($icon == "start") { + content:"\e718"; + } + + @else if ($icon == "statistics") { + content:"\e675"; + } + + @else if ($icon == "stepin") { + content:"\e719"; + } + + @else if ($icon == "stepout") { + content:"\e71a"; + } + + @else if ($icon == "stepover") { + content:"\e71b"; + } + + @else if ($icon == "stop") { + content:"\e71c"; + } + + @else if ($icon == "store") { + content:"\e676"; + } + + @else if ($icon == "struct") { + content:"\e716"; + } + + @else if ($icon == "subscribe") { + content:"\e677"; + } + + @else if ($icon == "success") { + content:"\e657"; + } + + @else if ($icon == "swagger") { + content:"\e679"; + } + + @else if ($icon == "sync") { + content:"\e6b3"; + } + + @else if ($icon == "table") { + content:"\e6c4"; + } + + @else if ($icon == "tag") { + content:"\e67a"; + } + + @else if ($icon == "task") { + content:"\e67b"; + } + + @else if ($icon == "text") { + content:"\e67c"; + } + + @else if ($icon == "theme") { + content:"\e726"; + } + + @else if ($icon == "throttling-policy") { + content:"\e67f"; + } + + @else if ($icon == "throw") { + content:"\e722"; + } + + @else if ($icon == "tiles") { + content:"\e681"; + } + + @else if ($icon == "transaction") { + content:"\e72b"; + } + + @else if ($icon == "try-catch") { + content:"\e703"; + } + + @else if ($icon == "twitter") { + content:"\e6df"; + } + + @else if ($icon == "type-converter") { + content:"\e6f3"; + } + + @else if ($icon == "uncheck") { + content:"\e682"; + } + + @else if ($icon == "undo") { + content:"\e683"; + } + + @else if ($icon == "ungroup") { + content:"\e6b5"; + } + + @else if ($icon == "unmute") { + content:"\e6ae"; + } + + @else if ($icon == "up-arrow") { + content:"\e688"; + } + + @else if ($icon == "up") { + content:"\e684"; + } + + @else if ($icon == "upload") { + content:"\e68c"; + } + + @else if ($icon == "uri") { + content:"\e68d"; + } + + @else if ($icon == "usb-drive") { + content:"\e68e"; + } + + @else if ($icon == "use") { + content:"\e6ca"; + } + + @else if ($icon == "user") { + content:"\e68f"; + } + + @else if ($icon == "variable") { + content:"\e6ee"; + } + + @else if ($icon == "view") { + content:"\e691"; + } + + @else if ($icon == "vpn") { + content:"\e603"; + } + + @else if ($icon == "wadl") { + content:"\e6a1"; + } + + @else if ($icon == "war") { + content:"\e69e"; + } + + @else if ($icon == "warning") { + content:"\e693"; + } + + @else if ($icon == "web-app") { + content:"\e696"; + } + + @else if ($icon == "web-clip") { + content:"\e698"; + } + + @else if ($icon == "web-service") { + content:"\e69a"; + } + + @else if ($icon == "website") { + content:"\e69b"; + } + + @else if ($icon == "wifi") { + content:"\e607"; + } + + @else if ($icon == "windows") { + content:"\e605"; + } + + @else if ($icon == "worker-invoke") { + content:"\e723"; + } + + @else if ($icon == "worker-reply") { + content:"\e724"; + } + + @else if ($icon == "worker") { + content:"\e6ef"; + } + + @else if ($icon == "wsdl") { + content:"\e6a0"; + } + + @else if ($icon == "wso2-logo") { + content:"\e6a7"; + } + + @else if ($icon == "wso2") { + content:"\e6a8"; + } + + @else if ($icon == "xacml") { + content:"\e69f"; + } + + @else if ($icon == "xml") { + content:"\e69c"; + } + + @else if ($icon == "xq") { + content:"\e6a2"; + } + + @else if ($icon == "xsd") { + content:"\e6a3"; + } + + @else if ($icon == "xslt") { + content:"\e6a4"; + } + + @else if ($icon == "youtube") { + content:"\e6e0"; + } + + @else if ($icon == "zoom-in") { + content:"\e6a5"; + } + + @else if ($icon == "zoom-out") { + content:"\e6a6"; + } + } \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/css/font-wso2.min.css b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/css/font-wso2.min.css deleted file mode 100644 index 8d2a487bef..0000000000 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/css/font-wso2.min.css +++ /dev/null @@ -1,15 +0,0 @@ -/*! -~ Copyright (c) WSO2 Inc. (http://wso2.com) All Rights Reserved. -~ -~ Licensed 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. -*/.fw-fw,.fw-li{text-align:center}@font-face{font-family:font-wso2;src:local("font-wso2"),url(../fonts/font-wso2.eot?6563fa91278f239ef8c827d90a165223);src:local("font-wso2"),url(../fonts/font-wso2.eot?#iefix) format("embedded-opentype"),url(../fonts/font-wso2.woff2?6563fa91278f239ef8c827d90a165223) format("woff2"),url(../fonts/font-wso2.woff?6563fa91278f239ef8c827d90a165223) format("woff"),url(../fonts/font-wso2.ttf?6563fa91278f239ef8c827d90a165223) format("truetype"),url(../fonts/font-wso2.svg?6563fa91278f239ef8c827d90a165223#font-wso2) format("svg");font-weight:400;font-style:normal}.fw,[class*=" fw-"],[class^=fw-]{font:normal normal normal 14px/1 font-wso2;display:inline-block;font-weight:400;font-style:normal;font-size:inherit;font-variant:normal;speak:none;text-decoration:inherit;text-transform:none;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fw-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fw-2x{font-size:2em}.fw-3x{font-size:3em}.fw-4x{font-size:4em}.fw-5x{font-size:5em}.fw-fw{width:1.28571429em}.fw-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fw-ul>li{position:relative}.fw-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em}.fw-li.fw-lg{left:-1.85714286em}.fw-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fw-background{background:#888;border-radius:.3em;padding:.4em .5em .45em}.fw-pull-left{float:left}.fw-pull-right{float:right}.fw.fw-pull-left{margin-right:.3em}.fw.fw-pull-right{margin-left:.3em}.fw-spin{-webkit-animation:fw-spin 2s infinite linear;animation:fw-spin 2s infinite linear}@-webkit-keyframes fw-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fw-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fw-pulse{-webkit-animation:fw-pulse 2s ease-out infinite;animation:fw-pulse 2s ease-out infinite}@-webkit-keyframes fw-pulse{0%,100%,30%{opacity:.3}40%{opacity:1}}@keyframes fw-pulse{0%,100%,30%{opacity:.3}40%{opacity:1}}.fw-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fw-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fw-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fw-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.fw-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scale(1,-1)}:root .fw-flip-horizontal,:root .fw-flip-vertical,:root .fw-rotate-180,:root .fw-rotate-270,:root .fw-rotate-90{filter:none}.fw-helper,.fw-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:1.85em;vertical-align:middle}.fw-helper:after,.fw-helper:before,.fw-stack-1x,.fw-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fw-helper:before,.fw-stack-1x{line-height:inherit}.fw-helper:after,.fw-stack-2x{font-size:1.9em}.fw-helper-slash:before{font-size:1.4em}.fw-helper-circle:before,.fw-helper-square:before{z-index:1}.fw-helper-circle-outline:after{content:"\e61f"}.fw-helper-circle:after{content:"\e61a"}.fw-helper-square-outline:after{content:"\e6b2"}.fw-helper-square:after{content:"\e6b1"}.fw-helper-slash:after{content:"\e6e1"}.fw-stack>.fw-stack{position:absolute;font-size:.5em}.fw-stack>.fw-stack.fw-move-top{top:-.2em}.fw-stack>.fw-stack.fw-move-bottom{bottom:-.2em}.fw-stack>.fw.stack.fw-move-left{left:-.5em}.fw-stack>.fw-stack.fw-move-right{right:-.5em}.fw-helper-inverse:after,.fw-inverse:before,.fw-number{color:#fff}.fw-helper-shadow:after,.fw-shadow:before{text-shadow:#fff 1px 1px 0}.fw-helper-stroke:after,.fw-stroke:before{text-shadow:-2px -2px 0 #fff,2px -2px 0 #fff,-2px 2px 0 #fff,2px 2px 0 #fff}.fw-number{line-height:2em;font-family:Arial,Helvetica,sans-serif}.fw-abort:before{content:"\e72a"}.fw-action-invoke:before{content:"\e6fe"}.fw-action:before{content:"\e709"}.fw-activate:before{content:"\e6cf"}.fw-add:before{content:"\e615"}.fw-airplay:before{content:"\e600"}.fw-alarm:before{content:"\e6c2"}.fw-alert:before{content:"\e6be"}.fw-analytics-extensions:before{content:"\e6e2"}.fw-android-logcat:before{content:"\e72c"}.fw-android-sense:before{content:"\e72d"}.fw-android:before{content:"\e606"}.fw-annotation:before{content:"\e6e6"}.fw-api:before{content:"\e601"}.fw-apn:before{content:"\e602"}.fw-ios:before{content:"\e604"}.fw-application:before{content:"\e608"}.fw-arduino:before{content:"\e6ab"}.fw-assign:before{content:"\e6ff"}.fw-ballerina-service:before{content:"\e729"}.fw-ballerina:before{content:"\e728"}.fw-bar-chart:before{content:"\e690"}.fw-battery:before{content:"\e60a"}.fw-blank-document:before{content:"\e60c"}.fw-block:before{content:"\e695"}.fw-bookmark:before{content:"\e60d"}.fw-bpel:before{content:"\e60e"}.fw-bpmn:before{content:"\e60f"}.fw-break:before{content:"\e721"}.fw-bug:before{content:"\e611"}.fw-build:before{content:"\e6c1"}.fw-calendar:before{content:"\e612"}.fw-camera:before{content:"\e613"}.fw-cancel:before{content:"\e618"}.fw-carbon:before{content:"\e6c5"}.fw-chat:before{content:"\e65b"}.fw-check:before{content:"\e617"}.fw-checklist:before{content:"\e619"}.fw-circle-outline:before{content:"\e61f"}.fw-circle:before{content:"\e61a"}.fw-clear:before{content:"\e61b"}.fw-clock:before{content:"\e61d"}.fw-cloud:before{content:"\e61e"}.fw-code-view:before{content:"\e70e"}.fw-code:before{content:"\e6f1"}.fw-comment:before{content:"\e710"}.fw-compare:before{content:"\e610"}.fw-computer:before{content:"\e653"}.fw-configarations:before{content:"\e609"}.fw-connector:before{content:"\e700"}.fw-console:before{content:"\e71d"}.fw-constant:before{content:"\e701"}.fw-contact:before{content:"\e620"}.fw-contract:before{content:"\e614"}.fw-copy:before{content:"\e621"}.fw-cut:before{content:"\e6f2"}.fw-dashboard:before{content:"\e622"}.fw-database:before{content:"\e623"}.fw-delete:before{content:"\e624"}.fw-depend:before{content:"\e6c6"}.fw-deploy:before{content:"\e625"}.fw-deprecate:before{content:"\e6cb"}.fw-design-view:before{content:"\e70f"}.fw-devices:before{content:"\e704"}.fw-dgm-action-invoke:before{content:"\e712"}.fw-dgm-action:before{content:"\e711"}.fw-dgm-connector:before{content:"\e6f4"}.fw-dgm-constant-definition:before{content:"\e6f5"}.fw-dgm-fork:before{content:"\e6e7"}.fw-dgm-header:before{content:"\e6e8"}.fw-dgm-if-else:before{content:"\e6e9"}.fw-dgm-import:before{content:"\e717"}.fw-dgm-lifeline:before{content:"\e6ea"}.fw-dgm-logger:before{content:"\e6eb"}.fw-dgm-resource:before{content:"\e6f6"}.fw-dgm-service:before{content:"\e6f7"}.fw-dgm-try-catch:before{content:"\e6ec"}.fw-dgm-type-convertor:before{content:"\e6f8"}.fw-dgm-type:before{content:"\e6f9"}.fw-dgm-while:before{content:"\e707"}.fw-dial-up:before{content:"\e627"}.fw-disabled:before{content:"\e6d1"}.fw-display:before{content:"\e626"}.fw-docker:before{content:"\e70c"}.fw-document:before{content:"\e628"}.fw-down-arrow:before{content:"\e689"}.fw-down:before{content:"\e685"}.fw-download:before{content:"\e65f"}.fw-dss:before{content:"\e62a"}.fw-ebook:before{content:"\e62b"}.fw-edit:before{content:"\e62c"}.fw-ellipsis:before{content:"\e629"}.fw-endpoint:before{content:"\e62d"}.fw-enterprise:before{content:"\e6b6"}.fw-error:before{content:"\e630"}.fw-esb-connector:before{content:"\e6e3"}.fw-expand:before{content:"\e61c"}.fw-export:before{content:"\e631"}.fw-extensions:before{content:"\e6e4"}.fw-facebook:before{content:"\e6d3"}.fw-factory-reset:before{content:"\e632"}.fw-fan:before{content:"\e678"}.fw-faq:before{content:"\e62f"}.fw-file-browse:before{content:"\e633"}.fw-filter:before{content:"\e634"}.fw-folder-open:before{content:"\e70b"}.fw-folder:before{content:"\e62e"}.fw-fork-join:before{content:"\e720"}.fw-format:before{content:"\e6fa"}.fw-forum:before{content:"\e636"}.fw-function-invoke:before{content:"\e713"}.fw-function:before{content:"\e6fb"}.fw-gadget:before{content:"\e637"}.fw-geo-fence-inbound:before{content:"\e72e"}.fw-geo-fence-outbound:before{content:"\e72f"}.fw-github:before{content:"\e6d4"}.fw-globe:before{content:"\e697"}.fw-google-docs:before{content:"\e6d6"}.fw-google-drive:before{content:"\e6da"}.fw-google-plus:before{content:"\e6d9"}.fw-google-sheets:before{content:"\e6d7"}.fw-google-slides:before{content:"\e6d8"}.fw-google:before{content:"\e6d5"}.fw-grid:before{content:"\e638"}.fw-grip:before{content:"\e6b7"}.fw-group:before{content:"\e6af"}.fw-hardware:before{content:"\e6a9"}.fw-hdd:before{content:"\e639"}.fw-heart:before{content:"\e6c3"}.fw-hide:before{content:"\e6d2"}.fw-home:before{content:"\e63a"}.fw-hour-glass:before{content:"\e63b"}.fw-html:before{content:"\e69d"}.fw-http:before{content:"\e705"}.fw-image:before{content:"\e70a"}.fw-import:before{content:"\e63c"}.fw-incoming-call:before{content:"\e63d"}.fw-info:before{content:"\e63e"}.fw-instagram:before{content:"\e6db"}.fw-invitation:before{content:"\e63f"}.fw-invoke:before{content:"\e6ed"}.fw-is-connector:before{content:"\e6e5"}.fw-iterate:before{content:"\e71f"}.fw-jaggery:before{content:"\e640"}.fw-java-spring:before{content:"\e644"}.fw-java:before{content:"\e641"}.fw-javaee:before{content:"\e642"}.fw-javascript:before{content:"\e643"}.fw-jaxrs:before{content:"\e645"}.fw-jaxws:before{content:"\e6c7"}.fw-jquery:before{content:"\e646"}.fw-key:before{content:"\e647"}.fw-laptop:before{content:"\e648"}.fw-layout:before{content:"\e6bf"}.fw-ldap:before{content:"\e649"}.fw-left-arrow:before{content:"\e68a"}.fw-left:before{content:"\e686"}.fw-lifecycle:before{content:"\e64a"}.fw-light:before{content:"\e680"}.fw-linkedin:before{content:"\e6dc"}.fw-list-sort:before{content:"\e64d"}.fw-list:before{content:"\e64c"}.fw-loader:before{content:"\e6b4"}.fw-loader2:before{content:"\e6ba"}.fw-loader3:before{content:"\e6bb"}.fw-loader4:before{content:"\e6bc"}.fw-loader5:before{content:"\e6bd"}.fw-lock:before{content:"\e64e"}.fw-logical:before{content:"\e702"}.fw-mail:before{content:"\e64f"}.fw-main-function:before{content:"\e706"}.fw-map-location:before{content:"\e650"}.fw-menu:before{content:"\e651"}.fw-message:before{content:"\e635"}.fw-micro-services:before{content:"\e6ce"}.fw-dash:before,.fw-hyphen:before,.fw-minus:before{content:"\e616"}.fw-mobile:before{content:"\e652"}.fw-ms-document:before{content:"\e654"}.fw-mute:before{content:"\e655"}.fw-nodejs:before{content:"\e656"}.fw-notification:before{content:"\e60b"}.fw-organization:before{content:"\e6ac"}.fw-own:before{content:"\e6c8"}.fw-package:before{content:"\e6fd"}.fw-pages:before{content:"\e6c0"}.fw-paste:before{content:"\e658"}.fw-pdf:before{content:"\e659"}.fw-pending:before{content:"\e727"}.fw-php:before{content:"\e6c9"}.fw-pie-chart:before{content:"\e65a"}.fw-pinterest:before{content:"\e6dd"}.fw-policy:before{content:"\e67d"}.fw-polygon:before{content:"\e70d"}.fw-prototype:before{content:"\e6cc"}.fw-proxy:before{content:"\e699"}.fw-public:before{content:"\e6ad"}.fw-publish:before{content:"\e65c"}.fw-question:before{content:"\e6b0"}.fw-raspberry:before{content:"\e6aa"}.fw-redo:before{content:"\e65d"}.fw-refresh:before{content:"\e692"}.fw-register:before{content:"\e65e"}.fw-rename:before{content:"\e6fc"}.fw-reply:before{content:"\e714"}.fw-resource:before{content:"\e660"}.fw-rest-api:before{content:"\e661"}.fw-rest-service:before{content:"\e662"}.fw-resume:before{content:"\e71e"}.fw-retire:before{content:"\e6cd"}.fw-return:before{content:"\e715"}.fw-retweet:before{content:"\e6b9"}.fw-right-arrow:before{content:"\e68b"}.fw-right:before{content:"\e687"}.fw-ringing:before{content:"\e694"}.fw-rules:before{content:"\e664"}.fw-run:before{content:"\e708"}.fw-save:before{content:"\e665"}.fw-scep:before{content:"\e666"}.fw-schema:before{content:"\e667"}.fw-search:before{content:"\e668"}.fw-security-policy:before{content:"\e67e"}.fw-security:before{content:"\e669"}.fw-paper-rocket:before,.fw-send:before{content:"\e66a"}.fw-sequence:before{content:"\e66b"}.fw-server:before{content:"\e66c"}.fw-service-provider:before{content:"\e66e"}.fw-cogwheels:before,.fw-gears:before,.fw-service:before,.fw-sprockets:before{content:"\e66d"}.fw-cogwheel:before,.fw-gear:before,.fw-settings:before,.fw-sprocket:before{content:"\e66f"}.fw-share:before{content:"\e670"}.fw-shell:before{content:"\e730"}.fw-shortcut:before{content:"\e725"}.fw-sign-in:before{content:"\e671"}.fw-sign-out:before{content:"\e6b8"}.fw-skype:before{content:"\e6de"}.fw-slash:before{content:"\e6e1"}.fw-soap:before{content:"\e672"}.fw-sort-down:before{content:"\e663"}.fw-sort-up:before{content:"\e64b"}.fw-sort:before{content:"\e673"}.fw-speed-alert:before{content:"\e731"}.fw-square-outline:before{content:"\e6b2"}.fw-square:before{content:"\e6b1"}.fw-star:before{content:"\e674"}.fw-start:before{content:"\e718"}.fw-statistics:before{content:"\e675"}.fw-stepin:before{content:"\e719"}.fw-stepout:before{content:"\e71a"}.fw-stepover:before{content:"\e71b"}.fw-stop:before{content:"\e71c"}.fw-cart:before,.fw-store:before{content:"\e676"}.fw-struct:before{content:"\e716"}.fw-subscribe:before{content:"\e677"}.fw-success:before{content:"\e657"}.fw-swagger:before{content:"\e679"}.fw-sync:before{content:"\e6b3"}.fw-table:before{content:"\e6c4"}.fw-tag:before{content:"\e67a"}.fw-task:before{content:"\e67b"}.fw-text:before{content:"\e67c"}.fw-theme:before{content:"\e726"}.fw-throttling-policy:before{content:"\e67f"}.fw-throw:before{content:"\e722"}.fw-tiles:before{content:"\e681"}.fw-transaction:before{content:"\e72b"}.fw-try-catch:before{content:"\e703"}.fw-twitter:before{content:"\e6df"}.fw-type-converter:before{content:"\e6f3"}.fw-uncheck:before{content:"\e682"}.fw-undo:before{content:"\e683"}.fw-ungroup:before{content:"\e6b5"}.fw-unmute:before{content:"\e6ae"}.fw-up-arrow:before{content:"\e688"}.fw-up:before{content:"\e684"}.fw-upload:before{content:"\e68c"}.fw-uri:before{content:"\e68d"}.fw-usb-drive:before{content:"\e68e"}.fw-use:before{content:"\e6ca"}.fw-user:before{content:"\e68f"}.fw-variable:before{content:"\e6ee"}.fw-view:before{content:"\e691"}.fw-vpn:before{content:"\e603"}.fw-wadl:before{content:"\e6a1"}.fw-war:before{content:"\e69e"}.fw-warning:before{content:"\e693"}.fw-web-app:before{content:"\e696"}.fw-web-clip:before{content:"\e698"}.fw-web-service:before{content:"\e69a"}.fw-website:before{content:"\e69b"}.fw-wifi:before{content:"\e607"}.fw-windows:before{content:"\e605"}.fw-worker-invoke:before{content:"\e723"}.fw-worker-reply:before{content:"\e724"}.fw-worker:before{content:"\e6ef"}.fw-wsdl:before{content:"\e6a0"}.fw-wso2-logo:before{content:"\e6a7"}.fw-wso2:before{content:"\e6a8"}.fw-xacml:before{content:"\e69f"}.fw-xml:before{content:"\e69c"}.fw-xq:before{content:"\e6a2"}.fw-xsd:before{content:"\e6a3"}.fw-xslt:before{content:"\e6a4"}.fw-youtube:before{content:"\e6e0"}.fw-zoom-in:before{content:"\e6a5"}.fw-zoom-out:before{content:"\e6a6"} \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/fonts/font-wso2.svg b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/fonts/font-wso2.svg deleted file mode 100644 index 6c7c5e7066..0000000000 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/fonts/font-wso2.svg +++ /dev/null @@ -1,2326 +0,0 @@ - - - - - -Created by FontForge 20161004 at Wed Jun 21 08:31:03 2017 - By dimal - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/fonts/font-wso2.ttf b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/uuf-template-app/app/units/uuf.unit.theme/public/lib/font-wso2-1.3.0/fonts/font-wso2.ttf deleted file mode 100644 index 27735b282033fea62db07bd8c5db09efed8ccee1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 71828 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 i`XGri6=I0Zr%6ub=T@$>(lQ3cGa%x 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

    xUt{hQlxlt&k8yf`;-KL>tz^T| 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

    NJF}mr0Zb_Fb|IrZgq|+9A6HtsQ#z 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 {{~css "lib/font-awesome_4.3.0/css/font-awesome.min.css" combine=false}} - {{~css "lib/font-wso2-1.3.0/css/font-wso2.css" combine=false}} + {{~css "lib/font-entgra-1.4.0/css/font-entgra.css" combine=false}} {{~css "less/theme.less" combine=false}} {{~css "css/theme-wso2.css" combine=false}} From 5c9c0d3ddf3874d06d55250df725e5500fcdce53 Mon Sep 17 00:00:00 2001 From: charitha Date: Fri, 30 Aug 2019 10:57:37 +0530 Subject: [PATCH 34/34] Fix missing operation id in mqtt operation topic --- .../device/mgt/core/operation/mgt/OperationManagerImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/OperationManagerImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/OperationManagerImpl.java index 3a9db4f4c0..a6bc22a46d 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/OperationManagerImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/OperationManagerImpl.java @@ -237,6 +237,7 @@ public class OperationManagerImpl implements OperationManager { } int operationId = this.lookupOperationDAO(operation).addOperation(operationDto); + operation.setId(operationId); boolean isScheduled = false; NotificationStrategy notificationStrategy = getNotificationStrategy();