diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/GeoCluster.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/GeoCluster.java new file mode 100644 index 0000000000..4316e35b51 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/GeoCluster.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2018-2021, 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.jaxrs.beans; + +import org.wso2.carbon.device.mgt.common.geo.service.GeoCoordinate; + +public class GeoCluster { + private final GeoCoordinate coordinates; + private final GeoCoordinate southWestBound; + private final GeoCoordinate northEastBound; + private final long count; + private final String geohashPrefix; + private final String deviceIdentification; + private final String deviceName; + private final String deviceType; + private final String lastSeen; + + public GeoCluster(GeoCoordinate coordinates, GeoCoordinate southWestBound, GeoCoordinate northEastBound, + long count, String geohashPrefix, String deviceIdentification, String deviceName, + String deviceType, String lastSeen) { + this.coordinates = coordinates; + this.southWestBound = southWestBound; + this.northEastBound = northEastBound; + this.count = count; + this.geohashPrefix = geohashPrefix; + this.deviceIdentification = deviceIdentification; + this.deviceName = deviceName; + this.deviceType = deviceType; + this.lastSeen = lastSeen; + } + + public String getGeohashPrefix() { + return geohashPrefix; + } + + public long getCount() { + return count; + } + + public GeoCoordinate getCoordinates() { + return coordinates; + } + + public GeoCoordinate getSouthWestBound() { + return southWestBound; + } + + public GeoCoordinate getNorthEastBound() { + return northEastBound; + } + + public String getDeviceIdentification() { + return deviceIdentification; + } + + public String getDeviceName() { + return deviceName; + } + + public String getDeviceType() { + return deviceType; + } + + public String getLastSeen() { + return lastSeen; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GeoLocationBasedService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GeoLocationBasedService.java index 4a3e994f70..a0cd0854c4 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GeoLocationBasedService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/GeoLocationBasedService.java @@ -16,7 +16,6 @@ * under the License. */ - package org.wso2.carbon.device.mgt.jaxrs.service.api; import io.swagger.annotations.Api; @@ -32,6 +31,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.EnrolmentInfo; import org.wso2.carbon.device.mgt.common.geo.service.Alert; import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; import org.wso2.carbon.device.mgt.jaxrs.beans.GeofenceWrapper; @@ -41,7 +41,6 @@ import javax.validation.Valid; import javax.validation.constraints.Size; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; -import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; @@ -51,7 +50,7 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import java.util.ArrayList; +import java.util.List; @SwaggerDefinition( info = @Info( @@ -209,6 +208,7 @@ public interface GeoLocationBasedService { message = "Internal Server Error. \n Error on retrieving stats", response = Response.class) }) + @Deprecated Response getGeoDeviceLocations( @ApiParam( name = "deviceType", @@ -245,6 +245,124 @@ public interface GeoLocationBasedService { defaultValue ="2") @QueryParam("zoom") int zoom); + @Path("stats/geo-view") + @GET + @Consumes("application/json") + @Produces("application/json") + @ApiOperation( + consumes = "application/json", + produces = "application/json", + httpMethod = "GET", + value = "Getting geo view of devices", + notes = "Get the details of the devices that are within the map. The map area is enclosed with four " + + "coordinates in the shape of a square or rectangle. This is done by defining two points of the " + + "map. The other two points are automatically created using the given points. " + + "You can define the zoom level or scale of the map too.", + response = Response.class, + tags = "Geo Service Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:geo-service:analytics-view") + }) + } + ) + @ApiResponses(value = { + @ApiResponse( + code = 200, + message = "OK.", + response = Response.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid parameters found.", + response = Response.class), + @ApiResponse( + code = 401, + message = "Unauthorized. \n Unauthorized request."), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Error on retrieving stats", + response = Response.class) + }) + Response getGeoDeviceView( + @ApiParam( + name = "minLat", + value = "Define the minimum latitude of the geofence.", + required = true, + defaultValue ="79.85213577747345") + @QueryParam("minLat") double minLat, + @ApiParam( + name = "maxLat", + value = "Define the maximum latitude of the geofence.", + required = true, + defaultValue ="79.85266149044037") + @QueryParam("maxLat") double maxLat, + @ApiParam( + name = "minLong", + value = "Define the minimum longitude of the geofence.", + required = true, + defaultValue ="6.909673257977737") + @QueryParam("minLong") double minLong, + @ApiParam( + name = "maxLong", + value = "Define the maximum longitude of the geofence", + required = true, + defaultValue ="6.909673257977737") + @QueryParam("maxLong") double maxLong, + @ApiParam( + name = "zoom", + value = "Define the level to zoom or scale the map. You can define any value between 1 to 14.", + required = true, + defaultValue ="2") + @QueryParam("zoom") int zoom, + @ApiParam( + name = "deviceType", + value = "Optional Device type name.") + @QueryParam("deviceType") List deviceTypes, + @ApiParam( + name = "deviceIdentifier", + value = "Optional Device Identifier.") + @QueryParam("deviceIdentifier") List deviceIdentifiers, + @ApiParam( + name = "status", + value = "Optional Device status.") + @QueryParam("status") List statuses, + @ApiParam( + name = "ownership", + value = "Optional Device ownership.") + @QueryParam("ownership") List ownerships, + @ApiParam( + name = "owner", + value = "Optional Device owner.") + @QueryParam("owner") List owners, + @ApiParam( + name = "noClusters", + value = "Optional include devices only.") + @QueryParam("noClusters") boolean noClusters, + @ApiParam( + name = "createdBefore", + value = "Optional Device created before timestamp.") + @QueryParam("createdBefore") long createdBefore, + @ApiParam( + name = "createdAfter", + value = "Optional Device created after timestamp..") + @QueryParam("createdAfter") long createdAfter, + @ApiParam( + name = "updatedBefore", + value = "Optional Device updated before timestamp.") + @QueryParam("updatedBefore") long updatedBefore, + @ApiParam( + name = "updatedAfter", + value = "Optional Device updated after timestamp.") + @QueryParam("updatedAfter") long updatedAfter); /** * Create Geo alerts diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GeoLocationBasedServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GeoLocationBasedServiceImpl.java index 30ea94954c..bafe13d742 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GeoLocationBasedServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/GeoLocationBasedServiceImpl.java @@ -25,10 +25,20 @@ import com.google.gson.Gson; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpStatus; +import org.wso2.carbon.analytics.api.AnalyticsDataAPI; +import org.wso2.carbon.analytics.api.AnalyticsDataAPIUtil; +import org.wso2.carbon.analytics.dataservice.commons.AnalyticsDataResponse; +import org.wso2.carbon.analytics.dataservice.commons.SearchResultEntry; +import org.wso2.carbon.analytics.dataservice.commons.SortByField; +import org.wso2.carbon.analytics.dataservice.commons.SortType; +import org.wso2.carbon.analytics.datasource.commons.Record; +import org.wso2.carbon.analytics.datasource.commons.exception.AnalyticsException; +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.DeviceManagementConstants; import org.wso2.carbon.device.mgt.common.DeviceManagementConstants.GeoServices; +import org.wso2.carbon.device.mgt.common.EnrolmentInfo; import org.wso2.carbon.device.mgt.common.PaginationRequest; import org.wso2.carbon.device.mgt.common.PaginationResult; import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationException; @@ -37,23 +47,30 @@ import org.wso2.carbon.device.mgt.common.event.config.EventConfigurationExceptio import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; import org.wso2.carbon.device.mgt.common.geo.service.Alert; import org.wso2.carbon.device.mgt.common.geo.service.AlertAlreadyExistException; +import org.wso2.carbon.device.mgt.common.geo.service.Event; +import org.wso2.carbon.device.mgt.common.geo.service.GeoCluster; +import org.wso2.carbon.device.mgt.common.geo.service.GeoCoordinate; import org.wso2.carbon.device.mgt.common.geo.service.GeoFence; import org.wso2.carbon.device.mgt.common.geo.service.GeoLocationBasedServiceException; import org.wso2.carbon.device.mgt.common.geo.service.GeoLocationProviderService; +import org.wso2.carbon.device.mgt.common.geo.service.GeoQuery; import org.wso2.carbon.device.mgt.common.geo.service.GeofenceData; import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants; -import org.wso2.carbon.device.mgt.core.geo.GeoCluster; -import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate; import org.wso2.carbon.device.mgt.core.geo.geoHash.geoHashStrategy.GeoHashLengthStrategy; import org.wso2.carbon.device.mgt.core.geo.geoHash.geoHashStrategy.ZoomGeoHashLengthStrategy; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil; import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; import org.wso2.carbon.device.mgt.jaxrs.beans.EventAction; import org.wso2.carbon.device.mgt.jaxrs.beans.GeofenceWrapper; import org.wso2.carbon.device.mgt.jaxrs.service.api.GeoLocationBasedService; import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.InputValidationException; import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtUtil; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.utils.multitenancy.MultitenantUtils; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; @@ -66,79 +83,84 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Response; import java.io.IOException; +import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * The api for */ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService { - private static Log log = LogFactory.getLog(GeoLocationBasedServiceImpl.class); - - //todo:amalka -// @Path("stats/{deviceType}/{deviceId}") -// @GET -// @Consumes("application/json") -// @Produces("application/json") -// public Response getGeoDeviceStats(@PathParam("deviceId") String deviceId, -// @PathParam("deviceType") String deviceType, -// @QueryParam("from") long from, @QueryParam("to") long to) { -// try { -// if (!DeviceManagerUtil.isPublishLocationResponseEnabled()) { -// return Response.status(Response.Status.BAD_REQUEST.getStatusCode()) -// .entity("Unable to retrive Geo Device stats. Geo Data publishing does not enabled.").build(); -// } -// } catch (DeviceManagementException e) { -// return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).entity(e.getMessage()).build(); -// } -// String tableName = "IOT_PER_DEVICE_STREAM_GEO_FUSEDSPATIALEVENT"; -// String fromDate = String.valueOf(from); -// String toDate = String.valueOf(to); -// String query = "id:" + deviceId + " AND type:" + deviceType; -// if (from != 0 || to != 0) { -// query += " AND timeStamp : [" + fromDate + " TO " + toDate + "]"; -// } -// try { -// if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized( -// new DeviceIdentifier(deviceId, deviceType), -// DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) { -// return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); -// } -// List sortByFields = new ArrayList<>(); -// SortByField sortByField = new SortByField("timeStamp", SortType.ASC); -// sortByFields.add(sortByField); -// -// // this is the user who initiates the request -// String authorizedUser = MultitenantUtils.getTenantAwareUsername( -// CarbonContext.getThreadLocalCarbonContext().getUsername()); -// -// try { -// String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); -// int tenantId = DeviceMgtAPIUtils.getRealmService().getTenantManager().getTenantId(tenantDomain); -// AnalyticsDataAPI analyticsDataAPI = DeviceMgtAPIUtils.getAnalyticsDataAPI(); -// List searchResults = analyticsDataAPI.search(tenantId, tableName, query, -// 0, -// 100, -// sortByFields); -// List events = getEventBeans(analyticsDataAPI, tenantId, tableName, new ArrayList(), -// searchResults); -// return Response.ok().entity(null).build(); -// } catch (AnalyticsException| UserStoreException e) { -// log.error("Failed to perform search on table: " + tableName + " : " + e.getMessage(), e); -// throw DeviceMgtUtil.buildBadRequestException( -// Constants.ErrorMessages.STATUS_BAD_REQUEST_MESSAGE_DEFAULT); -// } -// } catch (DeviceAccessAuthorizationException e) { -// log.error(e.getErrorMessage()); -// return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build(); -// } -// } + private static final Log log = LogFactory.getLog(GeoLocationBasedServiceImpl.class); + + @Path("stats/{deviceType}/{deviceId}") + @GET + @Consumes("application/json") + @Produces("application/json") + public Response getGeoDeviceStats(@PathParam("deviceId") String deviceId, + @PathParam("deviceType") String deviceType, + @QueryParam("from") long from, @QueryParam("to") long to) { + try { + if (!DeviceManagerUtil.isPublishLocationResponseEnabled()) { + return Response.status(Response.Status.BAD_REQUEST.getStatusCode()) + .entity("Unable to retrive Geo Device stats. Geo Data publishing does not enabled.").build(); + } + } catch (DeviceManagementException e) { + return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).entity(e.getMessage()).build(); + } + String tableName = "IOT_PER_DEVICE_STREAM_GEO_FUSEDSPATIALEVENT"; + String fromDate = String.valueOf(from); + String toDate = String.valueOf(to); + String query = "id:" + deviceId + " AND type:" + deviceType; + if (from != 0 || to != 0) { + query += " AND timeStamp : [" + fromDate + " TO " + toDate + "]"; + } + try { + if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized( + new DeviceIdentifier(deviceId, deviceType), + DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) { + return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); + } + List sortByFields = new ArrayList<>(); + SortByField sortByField = new SortByField("timeStamp", SortType.ASC); + sortByFields.add(sortByField); + + // this is the user who initiates the request + String authorizedUser = MultitenantUtils.getTenantAwareUsername( + CarbonContext.getThreadLocalCarbonContext().getUsername()); + + try { + String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + int tenantId = DeviceMgtAPIUtils.getRealmService().getTenantManager().getTenantId(tenantDomain); + AnalyticsDataAPI analyticsDataAPI = DeviceMgtAPIUtils.getAnalyticsDataAPI(); + List searchResults = analyticsDataAPI.search(tenantId, tableName, query, + 0, + 100, + sortByFields); + List events = getEventBeans(analyticsDataAPI, tenantId, tableName, new ArrayList(), + searchResults); + return Response.ok().entity(events).build(); + } catch (AnalyticsException | UserStoreException e) { + log.error("Failed to perform search on table: " + tableName + " : " + e.getMessage(), e); + throw DeviceMgtUtil.buildBadRequestException( + Constants.ErrorMessages.STATUS_BAD_REQUEST_MESSAGE_DEFAULT); + } + } catch (DeviceAccessAuthorizationException e) { + log.error(e.getErrorMessage()); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build(); + } + } @Path("stats/device-locations") @GET @Consumes("application/json") @Produces("application/json") + @Deprecated public Response getGeoDeviceLocations( @QueryParam("deviceType") String deviceType, @QueryParam("minLat") double minLat, @@ -146,6 +168,64 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService { @QueryParam("minLong") double minLong, @QueryParam("maxLong") double maxLong, @QueryParam("zoom") int zoom) { + GeoHashLengthStrategy geoHashLengthStrategy = new ZoomGeoHashLengthStrategy(); + GeoCoordinate southWest = new GeoCoordinate(minLat, minLong); + GeoCoordinate northEast = new GeoCoordinate(maxLat, maxLong); + int geohashLength = geoHashLengthStrategy.getGeohashLength(southWest, northEast, zoom); + DeviceManagementProviderService deviceManagementService = DeviceMgtAPIUtils.getDeviceManagementService(); + GeoQuery geoQuery = new GeoQuery(southWest, northEast, geohashLength); + if (deviceType != null) { + geoQuery.setDeviceTypes(Collections.singletonList(deviceType)); + } + List geoClusters = new ArrayList<>(); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S"); + try { + List newClusters = deviceManagementService.findGeoClusters(geoQuery); + org.wso2.carbon.device.mgt.jaxrs.beans.GeoCluster geoCluster; + String deviceIdentification = null; + String deviceName = null; + String lastSeen = null; + for (GeoCluster gc : newClusters) { + if (gc.getDevice() != null) { + deviceIdentification = gc.getDevice().getDeviceIdentifier(); + deviceName = gc.getDevice().getName(); + deviceType = gc.getDevice().getType(); + lastSeen = simpleDateFormat.format(new Date(gc.getDevice() + .getEnrolmentInfo().getDateOfLastUpdate())); + } + geoCluster = new org.wso2.carbon.device.mgt.jaxrs.beans.GeoCluster(gc.getCoordinates(), + gc.getSouthWestBound(), gc.getNorthEastBound(), gc.getCount(), gc.getGeohashPrefix(), + deviceIdentification, deviceName, deviceType, lastSeen); + geoClusters.add(geoCluster); + } + } catch (DeviceManagementException e) { + String msg = "Error occurred while retrieving geo clusters query: " + new Gson().toJson(geoQuery); + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build(); + } + return Response.ok().entity(geoClusters).build(); + } + + @Path("stats/geo-view") + @GET + @Consumes("application/json") + @Produces("application/json") + public Response getGeoDeviceView( + @QueryParam("minLat") double minLat, + @QueryParam("maxLat") double maxLat, + @QueryParam("minLong") double minLong, + @QueryParam("maxLong") double maxLong, + @QueryParam("zoom") int zoom, + @QueryParam("deviceType") List deviceTypes, + @QueryParam("deviceIdentifier") List deviceIdentifiers, + @QueryParam("status") List statuses, + @QueryParam("ownership") List ownerships, + @QueryParam("owner") List owners, + @QueryParam("noClusters") boolean noClusters, + @QueryParam("createdBefore") long createdBefore, + @QueryParam("createdAfter") long createdAfter, + @QueryParam("updatedBefore") long updatedBefore, + @QueryParam("updatedAfter") long updatedAfter) { GeoHashLengthStrategy geoHashLengthStrategy = new ZoomGeoHashLengthStrategy(); GeoCoordinate southWest = new GeoCoordinate(minLat, minLong); @@ -153,15 +233,25 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService { int geohashLength = geoHashLengthStrategy.getGeohashLength(southWest, northEast, zoom); DeviceManagementProviderService deviceManagementService = DeviceMgtAPIUtils.getDeviceManagementService(); List geoClusters; + GeoQuery geoQuery = new GeoQuery(southWest, northEast, geohashLength); + geoQuery.setDeviceTypes(deviceTypes); + geoQuery.setDeviceIdentifiers(deviceIdentifiers); + geoQuery.setStatuses(statuses); + geoQuery.setOwners(owners); + geoQuery.setOwnerships(ownerships); + geoQuery.setNoClusters(noClusters); + geoQuery.setCreatedBefore(createdBefore); + geoQuery.setCreatedAfter(createdAfter); + geoQuery.setUpdatedBefore(updatedBefore); + geoQuery.setUpdatedAfter(updatedAfter); try { - geoClusters = deviceManagementService.findGeoClusters(deviceType, southWest, northEast, geohashLength); + geoClusters = deviceManagementService.findGeoClusters(geoQuery); } catch (DeviceManagementException e) { - String msg = "Error occurred while retrieving geo clusters "; + String msg = "Error occurred while retrieving geo clusters for query: " + new Gson().toJson(geoQuery); log.error(msg, e); return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build(); } return Response.ok().entity(geoClusters).build(); - } @Path("alerts/{alertType}/{deviceType}/{deviceId}") @@ -169,8 +259,8 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService { @Consumes("application/json") @Produces("application/json") public Response createGeoAlerts(Alert alert, @PathParam("deviceId") String deviceId, - @PathParam("deviceType") String deviceType, - @PathParam("alertType") String alertType) { + @PathParam("deviceType") String deviceType, + @PathParam("alertType") String alertType) { try { if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized( new DeviceIdentifier(deviceId, deviceType), @@ -236,8 +326,8 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService { @Consumes("application/json") @Produces("application/json") public Response updateGeoAlerts(Alert alert, @PathParam("deviceId") String deviceId, - @PathParam("deviceType") String deviceType, - @PathParam("alertType") String alertType) { + @PathParam("deviceType") String deviceType, + @PathParam("alertType") String alertType) { try { if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized( new DeviceIdentifier(deviceId, deviceType), @@ -301,9 +391,9 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService { @Consumes("application/json") @Produces("application/json") public Response removeGeoAlerts(@PathParam("deviceId") String deviceId, - @PathParam("deviceType") String deviceType, - @PathParam("alertType") String alertType, - @QueryParam("queryName") String queryName) { + @PathParam("deviceType") String deviceType, + @PathParam("alertType") String alertType, + @QueryParam("queryName") String queryName) { try { if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized( new DeviceIdentifier(deviceId, deviceType), @@ -359,8 +449,8 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService { @Consumes("application/json") @Produces("application/json") public Response getGeoAlerts(@PathParam("deviceId") String deviceId, - @PathParam("deviceType") String deviceType, - @PathParam("alertType") String alertType) { + @PathParam("deviceType") String deviceType, + @PathParam("alertType") String alertType) { try { if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized( new DeviceIdentifier(deviceId, deviceType), @@ -425,26 +515,26 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService { String result = null; switch (alertType) { - case GeoServices.ALERT_TYPE_WITHIN: - alerts = geoService.getWithinAlerts(); - break; - case GeoServices.ALERT_TYPE_EXIT: - alerts = geoService.getExitAlerts(); - break; - case GeoServices.ALERT_TYPE_STATIONARY: - alerts = geoService.getStationaryAlerts(); - break; - case GeoServices.ALERT_TYPE_TRAFFIC: - alerts = geoService.getTrafficAlerts(); - break; - case GeoServices.ALERT_TYPE_SPEED: - result = geoService.getSpeedAlerts(); - return Response.ok().entity(result).build(); - case GeoServices.ALERT_TYPE_PROXIMITY: - result = geoService.getProximityAlerts(); - return Response.ok().entity(result).build(); - default: - throw new GeoLocationBasedServiceException("Invalid Alert Type"); + case GeoServices.ALERT_TYPE_WITHIN: + alerts = geoService.getWithinAlerts(); + break; + case GeoServices.ALERT_TYPE_EXIT: + alerts = geoService.getExitAlerts(); + break; + case GeoServices.ALERT_TYPE_STATIONARY: + alerts = geoService.getStationaryAlerts(); + break; + case GeoServices.ALERT_TYPE_TRAFFIC: + alerts = geoService.getTrafficAlerts(); + break; + case GeoServices.ALERT_TYPE_SPEED: + result = geoService.getSpeedAlerts(); + return Response.ok().entity(result).build(); + case GeoServices.ALERT_TYPE_PROXIMITY: + result = geoService.getProximityAlerts(); + return Response.ok().entity(result).build(); + default: + throw new GeoLocationBasedServiceException("Invalid Alert Type"); } return Response.ok().entity(alerts).build(); @@ -455,144 +545,142 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService { } } - //todo:amalka -// @Path("alerts/history/{deviceType}/{deviceId}") -// @GET -// @Consumes("application/json") -// @Produces("application/json") -// public Response getGeoAlertsHistory(@PathParam("deviceId") String deviceId, -// @PathParam("deviceType") String deviceType, -// @QueryParam("from") long from, @QueryParam("to") long to) { -// String tableName = "IOT_PER_DEVICE_STREAM_GEO_ALERTNOTIFICATIONS"; -// String fromDate = String.valueOf(from); -// String toDate = String.valueOf(to); -// String query = "id:" + deviceId + " AND type:" + deviceType; -// if (from != 0 || to != 0) { -// query += " AND timeStamp : [" + fromDate + " TO " + toDate + "]"; -// } -// try { -// if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized( -// new DeviceIdentifier(deviceId, deviceType), -// DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) { -// return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); -// } -// List sortByFields = new ArrayList<>(); -// SortByField sortByField = new SortByField("timeStamp", SortType.ASC); -// sortByFields.add(sortByField); -// -// // this is the user who initiates the request -// String authorizedUser = MultitenantUtils.getTenantAwareUsername( -// CarbonContext.getThreadLocalCarbonContext().getUsername()); -// -// try { -// String tenantDomain = MultitenantUtils.getTenantDomain(authorizedUser); -// int tenantId = DeviceMgtAPIUtils.getRealmService().getTenantManager().getTenantId(tenantDomain); -// AnalyticsDataAPI analyticsDataAPI = DeviceMgtAPIUtils.getAnalyticsDataAPI(); -// List searchResults = analyticsDataAPI.search(tenantId, tableName, query, -// 0, -// 100, -// sortByFields); -// List events = getEventBeans(analyticsDataAPI, tenantId, tableName, new ArrayList(), -// searchResults); -// return Response.ok().entity(events).build(); -// } catch (AnalyticsException | UserStoreException e) { -// log.error("Failed to perform search on table: " + tableName + " : " + e.getMessage(), e); -// throw DeviceMgtUtil.buildBadRequestException( -// Constants.ErrorMessages.STATUS_BAD_REQUEST_MESSAGE_DEFAULT); -// } -// } catch (DeviceAccessAuthorizationException e) { -// log.error(e.getErrorMessage()); -// return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build(); -// } -// } - - //todo:amalka -// @Path("alerts/history") -// @GET -// @Consumes("application/json") -// @Produces("application/json") -// public Response getGeoAlertsHistoryForGeoClusters(@QueryParam("from") long from, @QueryParam("to") long to) { -// String tableName = "IOT_PER_DEVICE_STREAM_GEO_ALERTNOTIFICATIONS"; -// String fromDate = String.valueOf(from); -// String toDate = String.valueOf(to); -// String query = ""; -// if (from != 0 || to != 0) { -// query = "timeStamp : [" + fromDate + " TO " + toDate + "]"; -// } -// try { -// List sortByFields = new ArrayList<>(); -// SortByField sortByField = new SortByField("timeStamp", SortType.ASC); -// sortByFields.add(sortByField); -// -// // this is the user who initiates the request -// String authorizedUser = MultitenantUtils.getTenantAwareUsername( -// CarbonContext.getThreadLocalCarbonContext().getUsername()); -// -// String tenantDomain = MultitenantUtils.getTenantDomain(authorizedUser); -// int tenantId = DeviceMgtAPIUtils.getRealmService().getTenantManager().getTenantId(tenantDomain); -// AnalyticsDataAPI analyticsDataAPI = DeviceMgtAPIUtils.getAnalyticsDataAPI(); -// List searchResults = analyticsDataAPI.search(tenantId, tableName, query, -// 0, -// 100, -// sortByFields); -// List events = getEventBeans(analyticsDataAPI, tenantId, tableName, new ArrayList(), -// searchResults); -// return Response.ok().entity(events).build(); -// -// } catch (AnalyticsException | UserStoreException e) { -// log.error("Failed to perform search on table: " + tableName + " : " + e.getMessage(), e); -// throw DeviceMgtUtil.buildBadRequestException( -// Constants.ErrorMessages.STATUS_BAD_REQUEST_MESSAGE_DEFAULT); -// } -// } - -// private List getEventBeans(AnalyticsDataAPI analyticsDataAPI, int tenantId, String tableName, -// List columns, -// List searchResults) throws AnalyticsException { -// List ids = getIds(searchResults); -// List requiredColumns = (columns == null || columns.isEmpty()) ? null : columns; -// AnalyticsDataResponse response = analyticsDataAPI.get(tenantId, tableName, 1, requiredColumns, ids); -// List records = AnalyticsDataAPIUtil.listRecords(analyticsDataAPI, response); -// Map eventBeanMap = getEventBeanKeyedWithIds(records); -// return getSortedEventBeans(eventBeanMap, searchResults); -// } - -// private List getSortedEventBeans(Map eventBeanMap, -// List searchResults) { -// List sortedRecords = new ArrayList<>(); -// for (SearchResultEntry entry : searchResults) { -// sortedRecords.add(eventBeanMap.get(entry.getId())); -// } -// return sortedRecords; -// } - -// private Map getEventBeanKeyedWithIds(List records) { -// Map eventBeanMap = new HashMap<>(); -// for (Record record : records) { -// Event event = getEventBean(record); -// eventBeanMap.put(event.getId(), event); -// } -// return eventBeanMap; -// } - -// private List getIds(List searchResults) { -// List ids = new ArrayList<>(); -// if (searchResults != null) { -// for (SearchResultEntry resultEntry : searchResults) { -// ids.add(resultEntry.getId()); -// } -// } -// return ids; -// } - -// private static Event getEventBean(Record record) { -// Event eventBean = new Event(); -// eventBean.setId(record.getId()); -// eventBean.setTableName(record.getTableName()); -// eventBean.setTimestamp(record.getTimestamp()); -// eventBean.setValues(record.getValues()); -// return eventBean; -// } + @Path("alerts/history/{deviceType}/{deviceId}") + @GET + @Consumes("application/json") + @Produces("application/json") + public Response getGeoAlertsHistory(@PathParam("deviceId") String deviceId, + @PathParam("deviceType") String deviceType, + @QueryParam("from") long from, @QueryParam("to") long to) { + String tableName = "IOT_PER_DEVICE_STREAM_GEO_ALERTNOTIFICATIONS"; + String fromDate = String.valueOf(from); + String toDate = String.valueOf(to); + String query = "id:" + deviceId + " AND type:" + deviceType; + if (from != 0 || to != 0) { + query += " AND timeStamp : [" + fromDate + " TO " + toDate + "]"; + } + try { + if (!DeviceMgtAPIUtils.getDeviceAccessAuthorizationService().isUserAuthorized( + new DeviceIdentifier(deviceId, deviceType), + DeviceGroupConstants.Permissions.DEFAULT_STATS_MONITOR_PERMISSIONS)) { + return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); + } + List sortByFields = new ArrayList<>(); + SortByField sortByField = new SortByField("timeStamp", SortType.ASC); + sortByFields.add(sortByField); + + // this is the user who initiates the request + String authorizedUser = MultitenantUtils.getTenantAwareUsername( + CarbonContext.getThreadLocalCarbonContext().getUsername()); + + try { + String tenantDomain = MultitenantUtils.getTenantDomain(authorizedUser); + int tenantId = DeviceMgtAPIUtils.getRealmService().getTenantManager().getTenantId(tenantDomain); + AnalyticsDataAPI analyticsDataAPI = DeviceMgtAPIUtils.getAnalyticsDataAPI(); + List searchResults = analyticsDataAPI.search(tenantId, tableName, query, + 0, + 100, + sortByFields); + List events = getEventBeans(analyticsDataAPI, tenantId, tableName, new ArrayList(), + searchResults); + return Response.ok().entity(events).build(); + } catch (AnalyticsException | UserStoreException e) { + log.error("Failed to perform search on table: " + tableName + " : " + e.getMessage(), e); + throw DeviceMgtUtil.buildBadRequestException( + Constants.ErrorMessages.STATUS_BAD_REQUEST_MESSAGE_DEFAULT); + } + } catch (DeviceAccessAuthorizationException e) { + log.error(e.getErrorMessage()); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).build(); + } + } + + @Path("alerts/history") + @GET + @Consumes("application/json") + @Produces("application/json") + public Response getGeoAlertsHistoryForGeoClusters(@QueryParam("from") long from, @QueryParam("to") long to) { + String tableName = "IOT_PER_DEVICE_STREAM_GEO_ALERTNOTIFICATIONS"; + String fromDate = String.valueOf(from); + String toDate = String.valueOf(to); + String query = ""; + if (from != 0 || to != 0) { + query = "timeStamp : [" + fromDate + " TO " + toDate + "]"; + } + try { + List sortByFields = new ArrayList<>(); + SortByField sortByField = new SortByField("timeStamp", SortType.ASC); + sortByFields.add(sortByField); + + // this is the user who initiates the request + String authorizedUser = MultitenantUtils.getTenantAwareUsername( + CarbonContext.getThreadLocalCarbonContext().getUsername()); + + String tenantDomain = MultitenantUtils.getTenantDomain(authorizedUser); + int tenantId = DeviceMgtAPIUtils.getRealmService().getTenantManager().getTenantId(tenantDomain); + AnalyticsDataAPI analyticsDataAPI = DeviceMgtAPIUtils.getAnalyticsDataAPI(); + List searchResults = analyticsDataAPI.search(tenantId, tableName, query, + 0, + 100, + sortByFields); + List events = getEventBeans(analyticsDataAPI, tenantId, tableName, new ArrayList(), + searchResults); + return Response.ok().entity(events).build(); + + } catch (AnalyticsException | UserStoreException e) { + log.error("Failed to perform search on table: " + tableName + " : " + e.getMessage(), e); + throw DeviceMgtUtil.buildBadRequestException( + Constants.ErrorMessages.STATUS_BAD_REQUEST_MESSAGE_DEFAULT); + } + } + + private List getEventBeans(AnalyticsDataAPI analyticsDataAPI, int tenantId, String tableName, + List columns, + List searchResults) throws AnalyticsException { + List ids = getIds(searchResults); + List requiredColumns = (columns == null || columns.isEmpty()) ? null : columns; + AnalyticsDataResponse response = analyticsDataAPI.get(tenantId, tableName, 1, requiredColumns, ids); + List records = AnalyticsDataAPIUtil.listRecords(analyticsDataAPI, response); + Map eventBeanMap = getEventBeanKeyedWithIds(records); + return getSortedEventBeans(eventBeanMap, searchResults); + } + + private List getSortedEventBeans(Map eventBeanMap, + List searchResults) { + List sortedRecords = new ArrayList<>(); + for (SearchResultEntry entry : searchResults) { + sortedRecords.add(eventBeanMap.get(entry.getId())); + } + return sortedRecords; + } + + private Map getEventBeanKeyedWithIds(List records) { + Map eventBeanMap = new HashMap<>(); + for (Record record : records) { + Event event = getEventBean(record); + eventBeanMap.put(event.getId(), event); + } + return eventBeanMap; + } + + private List getIds(List searchResults) { + List ids = new ArrayList<>(); + if (searchResults != null) { + for (SearchResultEntry resultEntry : searchResults) { + ids.add(resultEntry.getId()); + } + } + return ids; + } + + private static Event getEventBean(Record record) { + Event eventBean = new Event(); + eventBean.setId(record.getId()); + eventBean.setTableName(record.getTableName()); + eventBean.setTimestamp(record.getTimestamp()); + eventBean.setValues(record.getValues()); + return eventBean; + } @Path("/geo-fence") @POST @@ -651,7 +739,7 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService { @Consumes("application/json") @Produces("application/json") public Response getGeofence(@PathParam("fenceId") int fenceId, - @QueryParam("requireEventData") boolean requireEventData) { + @QueryParam("requireEventData") boolean requireEventData) { try { GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService(); GeofenceData geofenceData = geoService.getGeoFences(fenceId); @@ -734,9 +822,9 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService { @Consumes("application/json") @Produces("application/json") public Response getGeofence(@QueryParam("offset") int offset, - @QueryParam("limit") int limit, - @QueryParam("name") String name, - @QueryParam("requireEventData") boolean requireEventData) { + @QueryParam("limit") int limit, + @QueryParam("name") String name, + @QueryParam("requireEventData") boolean requireEventData) { try { GeoLocationProviderService geoService = DeviceMgtAPIUtils.getGeoService(); if (offset >= 0 && limit != 0) { @@ -805,8 +893,8 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService { @Consumes("application/json") @Produces("application/json") public Response updateGeofence(GeofenceWrapper geofenceWrapper, - @PathParam("fenceId") int fenceId, - @QueryParam("eventIds") int[] eventIds) { + @PathParam("fenceId") int fenceId, + @QueryParam("eventIds") int[] eventIds) { RequestValidationUtil.validateGeofenceData(geofenceWrapper); RequestValidationUtil.validateEventConfigurationData(geofenceWrapper.getEventConfig()); try { 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 d19e835848..ebb965fc80 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 @@ -7,8 +7,9 @@ import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException; -import org.wso2.carbon.device.mgt.core.geo.GeoCluster; -import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate; +import org.wso2.carbon.device.mgt.common.geo.service.GeoCluster; +import org.wso2.carbon.device.mgt.common.geo.service.GeoCoordinate; +import org.wso2.carbon.device.mgt.common.geo.service.GeoQuery; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.jaxrs.service.api.GeoLocationBasedService; @@ -33,8 +34,9 @@ public class GeoLocationBasedServiceImplTest { @Test(description = "This method tests the behaviour of getGeoDeviceLocations when there are no devices" + "in the given map boundaries") public void testGetGeoDeviceLocations1() throws DeviceManagementException { + GeoQuery geoQuery = new GeoQuery(Mockito.any(GeoCoordinate.class), Mockito.any(GeoCoordinate.class), Mockito.anyInt()); Mockito.doReturn(new ArrayList()).when(deviceManagementProviderService) - .findGeoClusters(null, Mockito.any(GeoCoordinate.class), Mockito.any(GeoCoordinate.class), Mockito.anyInt()); + .findGeoClusters(geoQuery); Response response = geoLocationBasedService.getGeoDeviceLocations(null, 0.4, 15, 75.6, 90.1, 6); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), @@ -47,12 +49,14 @@ public class GeoLocationBasedServiceImplTest { List geoClusters = new ArrayList<>(); geoClusters.add(new GeoCluster(new GeoCoordinate(1.5, 80.7), new GeoCoordinate(1.1, 79.5), new GeoCoordinate(1.9, 82.1), 3, - "tb32", "aegtew234", "test1", "android", "1234")); + "tb32", null)); geoClusters.add(new GeoCluster(new GeoCoordinate(10.2, 86.1), new GeoCoordinate(9.8, 84.7), new GeoCoordinate(11.1, 88.1), 4, - "t1gd", "swerty12s", "t2test", "android", "1234")); + "t1gd", null)); + + GeoQuery geoQuery = new GeoQuery(Mockito.any(GeoCoordinate.class), Mockito.any(GeoCoordinate.class), Mockito.anyInt()); Mockito.doReturn(geoClusters).when(deviceManagementProviderService) - .findGeoClusters(null, Mockito.any(GeoCoordinate.class), Mockito.any(GeoCoordinate.class), Mockito.anyInt()); + .findGeoClusters(geoQuery); Response response = geoLocationBasedService.getGeoDeviceLocations(null, 0.4, 15, 75.6, 90.1, 6); Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode(), diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/GeoCluster.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/GeoCluster.java new file mode 100644 index 0000000000..d2bcdc8931 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/GeoCluster.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2018-2021, 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.geo.service; + +import org.wso2.carbon.device.mgt.common.Device; + +public class GeoCluster { + + private final GeoCoordinate coordinates; + private final GeoCoordinate southWestBound; + private final GeoCoordinate northEastBound; + private final long count; + private final String geohashPrefix; + private final Device device; + + public GeoCluster(GeoCoordinate coordinates, GeoCoordinate southWestBound, GeoCoordinate northEastBound, + long count, String geohashPrefix, Device device) { + this.coordinates = coordinates; + this.southWestBound = southWestBound; + this.northEastBound = northEastBound; + this.count = count; + this.geohashPrefix = geohashPrefix; + this.device = device; + } + + public String getGeohashPrefix() { + return geohashPrefix; + } + + public long getCount() { + return count; + } + + public GeoCoordinate getCoordinates() { + return coordinates; + } + + public GeoCoordinate getSouthWestBound() { + return southWestBound; + } + + public GeoCoordinate getNorthEastBound() { + return northEastBound; + } + + public Device getDevice() { + return device; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/GeoCoordinate.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/GeoCoordinate.java new file mode 100644 index 0000000000..c83d18b1ac --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/GeoCoordinate.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018-2021, 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.geo.service; + +public class GeoCoordinate { + + private final double latitude; + private final double longitude; + + public GeoCoordinate(double latitude, double longitude) { + this.latitude = latitude; + this.longitude = longitude; + } + + public double getLatitude() { + return latitude; + } + + public double getLongitude() { + return longitude; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/GeoQuery.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/GeoQuery.java new file mode 100644 index 0000000000..f50e5ae700 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/GeoQuery.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2018-2021, 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.geo.service; + +import org.wso2.carbon.device.mgt.common.EnrolmentInfo; + +import java.util.List; + +public class GeoQuery { + + private final GeoCoordinate southWest; + private final GeoCoordinate northEast; + private final int geohashLength; + private List deviceTypes; + private List deviceIdentifiers; + private List statuses; + private List ownerships; + private List owners; + private boolean noClusters; + private long createdBefore; + private long createdAfter; + private long updatedBefore; + private long updatedAfter; + + public GeoQuery(GeoCoordinate southWest, GeoCoordinate northEast, int geohashLength) { + this.southWest = southWest; + this.northEast = northEast; + this.geohashLength = geohashLength; + } + + public GeoCoordinate getSouthWest() { + return southWest; + } + + public GeoCoordinate getNorthEast() { + return northEast; + } + + public int getGeohashLength() { + return geohashLength; + } + + public List getDeviceTypes() { + return deviceTypes; + } + + public void setDeviceTypes(List deviceTypes) { + this.deviceTypes = deviceTypes; + } + + public List getDeviceIdentifiers() { + return deviceIdentifiers; + } + + public void setDeviceIdentifiers(List deviceIdentifiers) { + this.deviceIdentifiers = deviceIdentifiers; + } + + public List getStatuses() { + return statuses; + } + + public void setStatuses(List statuses) { + this.statuses = statuses; + } + + public List getOwnerships() { + return ownerships; + } + + public void setOwnerships(List ownerships) { + this.ownerships = ownerships; + } + + public List getOwners() { + return owners; + } + + public void setOwners(List owners) { + this.owners = owners; + } + + public boolean isNoClusters() { + return noClusters; + } + + public void setNoClusters(boolean noClusters) { + this.noClusters = noClusters; + } + + public long getCreatedBefore() { + return createdBefore; + } + + public void setCreatedBefore(long createdBefore) { + this.createdBefore = createdBefore; + } + + public long getCreatedAfter() { + return createdAfter; + } + + public void setCreatedAfter(long createdAfter) { + this.createdAfter = createdAfter; + } + + public long getUpdatedBefore() { + return updatedBefore; + } + + public void setUpdatedBefore(long updatedBefore) { + this.updatedBefore = updatedBefore; + } + + public long getUpdatedAfter() { + return updatedAfter; + } + + public void setUpdatedAfter(long updatedAfter) { + this.updatedAfter = updatedAfter; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/ui/UIConfiguration.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/ui/UIConfiguration.java index 914597687c..1c4a1e91cd 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/ui/UIConfiguration.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/config/ui/UIConfiguration.java @@ -31,6 +31,7 @@ public class UIConfiguration { private AppRegistration appRegistration; private List scopes; private boolean isSsoEnable; + private int sessionTimeOut; @XmlElement(name = "AppRegistration", required=true) public AppRegistration getAppRegistration() { @@ -59,4 +60,13 @@ public class UIConfiguration { public void setSsoEnable(boolean ssoEnable) { isSsoEnable = ssoEnable; } + + @XmlElement(name = "SessionTimeOut") + public int getSessionTimeOut() { + return sessionTimeOut; + } + + public void setSessionTimeOut(int sessionTimeOut) { + this.sessionTimeOut = sessionTimeOut; + } } 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 82aded2490..77b9d76c5c 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 @@ -46,9 +46,10 @@ import org.wso2.carbon.device.mgt.common.configuration.mgt.DevicePropertyInfo; import org.wso2.carbon.device.mgt.common.device.details.DeviceData; import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistorySnapshot; import org.wso2.carbon.device.mgt.common.device.details.DeviceMonitoringData; +import org.wso2.carbon.device.mgt.common.geo.service.GeoQuery; 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; +import org.wso2.carbon.device.mgt.common.geo.service.GeoCluster; +import org.wso2.carbon.device.mgt.common.geo.service.GeoCoordinate; import java.sql.SQLException; import java.util.Date; @@ -555,14 +556,11 @@ public interface DeviceDAO { * This method is used to retrieve the details of geoclusters formed relatively to the zoom level and map * boundaries. * - * @param deviceType Optional device type name. - * @param southWest the coordinates of southWest corner of the map. - * @param northEast the coordinates of northEast corner of the map. - * @param tenantId tenant id. + * @param geoQuery the query to determine the geo data. + * @param tenantId tenant id. * @return returns a list of enrolment info objects. */ - List findGeoClusters(String deviceType, GeoCoordinate southWest, GeoCoordinate northEast, - int geohashLength,int tenantId) throws DeviceManagementDAOException; + List findGeoClusters(GeoQuery geoQuery, int tenantId) throws DeviceManagementDAOException; /** * This method is used to identify whether given device ids are exist or not. 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 749a31e0bb..bf387744e2 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 @@ -48,13 +48,14 @@ import org.wso2.carbon.device.mgt.common.configuration.mgt.DevicePropertyInfo; import org.wso2.carbon.device.mgt.common.device.details.DeviceData; import org.wso2.carbon.device.mgt.common.device.details.DeviceLocationHistorySnapshot; import org.wso2.carbon.device.mgt.common.device.details.DeviceMonitoringData; +import org.wso2.carbon.device.mgt.common.geo.service.GeoQuery; 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; import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil; 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; +import org.wso2.carbon.device.mgt.common.geo.service.GeoCluster; +import org.wso2.carbon.device.mgt.common.geo.service.GeoCoordinate; import java.sql.Connection; import java.sql.PreparedStatement; @@ -64,6 +65,7 @@ import java.sql.Statement; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; @@ -1850,62 +1852,161 @@ public abstract class AbstractDeviceDAOImpl implements DeviceDAO { return tenants; } - public List findGeoClusters(String deviceType, GeoCoordinate southWest, GeoCoordinate northEast, - int geohashLength, int tenantId) throws DeviceManagementDAOException { + public List findGeoClusters(GeoQuery geoQuery, int tenantId) throws DeviceManagementDAOException { Connection conn; PreparedStatement stmt = null; ResultSet rs = null; List geoClusters = new ArrayList<>(); try { conn = this.getConnection(); - String sql = "SELECT AVG(DEVICE_LOCATION.LATITUDE) AS LATITUDE,AVG(DEVICE_LOCATION.LONGITUDE) AS LONGITUDE," + - " MIN(DEVICE_LOCATION.LATITUDE) AS MIN_LATITUDE, MAX(DEVICE_LOCATION.LATITUDE) AS MAX_LATITUDE," + - " MIN(DEVICE_LOCATION.LONGITUDE) AS MIN_LONGITUDE," + - " MAX(DEVICE_LOCATION.LONGITUDE) AS MAX_LONGITUDE," + - " SUBSTRING(DEVICE_LOCATION.GEO_HASH,1,?) AS GEOHASH_PREFIX, COUNT(*) AS COUNT," + - " MIN(DEVICE.DEVICE_IDENTIFICATION) AS DEVICE_IDENTIFICATION," + - " MIN(DEVICE.NAME) AS NAME," + - " MIN(DEVICE_TYPE.NAME) AS TYPE, " + - " MIN(DEVICE.LAST_UPDATED_TIMESTAMP) AS LAST_UPDATED_TIMESTAMP " + - "FROM DM_DEVICE_LOCATION AS DEVICE_LOCATION,DM_DEVICE AS DEVICE, DM_DEVICE_TYPE AS DEVICE_TYPE " + - "WHERE DEVICE_LOCATION.LATITUDE BETWEEN ? AND ? AND " + - "DEVICE_LOCATION.LONGITUDE BETWEEN ? AND ? AND " + - "DEVICE.TENANT_ID=? AND " + - "DEVICE.ID=DEVICE_LOCATION.DEVICE_ID AND DEVICE.DEVICE_TYPE_ID=DEVICE_TYPE.ID"; - if (deviceType != null && !deviceType.isEmpty()) { - sql += " AND DEVICE_TYPE.NAME=?"; + String sql = "SELECT AVG(DEVICE_LOCATION.LATITUDE) AS LATITUDE, " + + "AVG(DEVICE_LOCATION.LONGITUDE) AS LONGITUDE, " + + "MIN(DEVICE_LOCATION.LATITUDE) AS MIN_LATITUDE, " + + "MAX(DEVICE_LOCATION.LATITUDE) AS MAX_LATITUDE, " + + "MIN(DEVICE_LOCATION.LONGITUDE) AS MIN_LONGITUDE, " + + "MAX(DEVICE_LOCATION.LONGITUDE) AS MAX_LONGITUDE, " + + "SUBSTRING(DEVICE_LOCATION.GEO_HASH,1,?) AS GEOHASH_PREFIX, " + + "COUNT(DEVICE_LOCATION.ID) AS COUNT, " + + "MIN(DEVICE.ID) AS DEVICE_ID, " + + "MIN(DEVICE.NAME) AS DEVICE_NAME, " + + "MIN(DEVICE.DESCRIPTION) AS DESCRIPTION, " + + "MIN(DEVICE_TYPE.NAME) AS DEVICE_TYPE, " + + "MIN(DEVICE.DEVICE_IDENTIFICATION) AS DEVICE_IDENTIFICATION, " + + "MIN(ENROLMENT.ID) AS ENROLMENT_ID, " + + "MIN(ENROLMENT.OWNER) AS OWNER, " + + "MIN(ENROLMENT.OWNERSHIP) AS OWNERSHIP, " + + "MIN(ENROLMENT.IS_TRANSFERRED) AS IS_TRANSFERRED, " + + "MIN(ENROLMENT.DATE_OF_ENROLMENT) AS DATE_OF_ENROLMENT, " + + "MIN(ENROLMENT.DATE_OF_LAST_UPDATE) AS DATE_OF_LAST_UPDATE, " + + "MIN(ENROLMENT.STATUS) AS STATUS " + + "FROM DM_DEVICE_LOCATION AS DEVICE_LOCATION, DM_DEVICE AS DEVICE, " + + "DM_DEVICE_TYPE AS DEVICE_TYPE, DM_ENROLMENT AS ENROLMENT " + + "WHERE DEVICE_LOCATION.LATITUDE BETWEEN ? AND ? " + + "AND DEVICE_LOCATION.LONGITUDE BETWEEN ? AND ? "; + if (geoQuery.getDeviceTypes() != null && !geoQuery.getDeviceTypes().isEmpty()) { + sql += "AND DEVICE_TYPE.NAME IN ("; + sql += String.join(", ", + Collections.nCopies(geoQuery.getDeviceTypes().size(), "?")); + sql += ") "; + } + if (geoQuery.getDeviceIdentifiers() != null && !geoQuery.getDeviceIdentifiers().isEmpty()) { + sql += "AND DEVICE.DEVICE_IDENTIFICATION IN ("; + sql += String.join(", ", + Collections.nCopies(geoQuery.getDeviceIdentifiers().size(), "?")); + sql += ") "; + } + if (geoQuery.getOwners() != null && !geoQuery.getOwners().isEmpty()) { + sql += "AND ENROLMENT.OWNER IN ("; + sql += String.join(", ", + Collections.nCopies(geoQuery.getOwners().size(), "?")); + sql += ") "; + } + if (geoQuery.getOwnerships() != null && !geoQuery.getOwnerships().isEmpty()) { + sql += "AND ENROLMENT.OWNERSHIP IN ("; + sql += String.join(", ", + Collections.nCopies(geoQuery.getOwnerships().size(), "?")); + sql += ") "; + } + if (geoQuery.getStatuses() != null && !geoQuery.getStatuses().isEmpty()) { + sql += "AND ENROLMENT.STATUS IN ("; + sql += String.join(", ", + Collections.nCopies(geoQuery.getStatuses().size(), "?")); + sql += ") "; + } else { + sql += "AND ENROLMENT.STATUS != 'REMOVED' "; + } + if (geoQuery.getCreatedBefore() != 0 || geoQuery.getCreatedAfter() != 0) { + sql += "AND ENROLMENT.DATE_OF_ENROLMENT BETWEEN ? AND ? "; } - sql += " GROUP BY GEOHASH_PREFIX"; + if (geoQuery.getUpdatedBefore() != 0 || geoQuery.getUpdatedAfter() != 0) { + sql += "AND ENROLMENT.DATE_OF_LAST_UPDATE BETWEEN ? AND ? "; + } + sql += "AND DEVICE.ID = DEVICE_LOCATION.DEVICE_ID AND DEVICE.DEVICE_TYPE_ID = DEVICE_TYPE.ID " + + "AND DEVICE.ID = ENROLMENT.DEVICE_ID " + + "AND DEVICE.TENANT_ID = ? AND DEVICE.TENANT_ID = ENROLMENT.TENANT_ID GROUP BY GEOHASH_PREFIX"; stmt = conn.prepareStatement(sql); - stmt.setInt(1, geohashLength); - stmt.setDouble(2, southWest.getLatitude()); - stmt.setDouble(3, northEast.getLatitude()); - stmt.setDouble(4, southWest.getLongitude()); - stmt.setDouble(5, northEast.getLongitude()); - stmt.setDouble(6, tenantId); - if (deviceType != null && !deviceType.isEmpty()) { - stmt.setString(7, deviceType); + + int index = 1; + stmt.setInt(index++, geoQuery.getGeohashLength()); + stmt.setDouble(index++, geoQuery.getSouthWest().getLatitude()); + stmt.setDouble(index++, geoQuery.getNorthEast().getLatitude()); + stmt.setDouble(index++, geoQuery.getSouthWest().getLongitude()); + stmt.setDouble(index++, geoQuery.getNorthEast().getLongitude()); + if (geoQuery.getDeviceTypes() != null) { + for (String s: geoQuery.getDeviceTypes()) { + stmt.setString(index++, s); + } + } + if (geoQuery.getDeviceIdentifiers() != null) { + for (String s: geoQuery.getDeviceIdentifiers()) { + stmt.setString(index++, s); + } + } + if (geoQuery.getOwners() != null) { + for (String s: geoQuery.getOwners()) { + stmt.setString(index++, s); + } } + if (geoQuery.getOwnerships() != null) { + for (String s: geoQuery.getOwnerships()) { + stmt.setString(index++, s); + } + } + if (geoQuery.getStatuses() != null) { + for (Status s: geoQuery.getStatuses()) { + stmt.setString(index++, s.toString()); + } + } + + if (geoQuery.getCreatedBefore() != 0 || geoQuery.getCreatedAfter() != 0) { + stmt.setTimestamp(index++, new Timestamp(geoQuery.getCreatedAfter())); + if (geoQuery.getCreatedBefore() == 0) { + stmt.setTimestamp(index++, new Timestamp(System.currentTimeMillis())); + } else { + stmt.setTimestamp(index++, new Timestamp(geoQuery.getCreatedBefore())); + } + } + if (geoQuery.getUpdatedBefore() != 0 || geoQuery.getUpdatedAfter() != 0) { + stmt.setTimestamp(index++, new Timestamp(geoQuery.getUpdatedAfter())); + if (geoQuery.getUpdatedBefore() == 0) { + stmt.setTimestamp(index++, new Timestamp(System.currentTimeMillis())); + } else { + stmt.setTimestamp(index++, new Timestamp(geoQuery.getUpdatedBefore())); + } + } + stmt.setInt(index, tenantId); + rs = stmt.executeQuery(); + + double latitude; + double longitude; + double minLatitude; + double maxLatitude; + double minLongitude; + double maxLongitude; + long count; + String geohashPrefix; + Device device; while (rs.next()) { - double latitude = rs.getDouble("LATITUDE"); - double longitude = rs.getDouble("LONGITUDE"); - double min_latitude = rs.getDouble("MIN_LATITUDE"); - double max_latitude = rs.getDouble("MAX_LATITUDE"); - double min_longitude = rs.getDouble("MIN_LONGITUDE"); - double max_longitude = rs.getDouble("MAX_LONGITUDE"); - String device_identification = rs.getString("DEVICE_IDENTIFICATION"); - String device_name = rs.getString("NAME"); - String device_type = rs.getString("TYPE"); - String last_seen = rs.getString("LAST_UPDATED_TIMESTAMP"); - long count = rs.getLong("COUNT"); - String geohashPrefix = rs.getString("GEOHASH_PREFIX"); + latitude = rs.getDouble("LATITUDE"); + longitude = rs.getDouble("LONGITUDE"); + minLatitude = rs.getDouble("MIN_LATITUDE"); + maxLatitude = rs.getDouble("MAX_LATITUDE"); + minLongitude = rs.getDouble("MIN_LONGITUDE"); + maxLongitude = rs.getDouble("MAX_LONGITUDE"); + count = rs.getLong("COUNT"); + geohashPrefix = rs.getString("GEOHASH_PREFIX"); + if (count == 1) { + device = DeviceManagementDAOUtil.loadDevice(rs); + } else { + device = null; + } geoClusters.add(new GeoCluster(new GeoCoordinate(latitude, longitude), - new GeoCoordinate(min_latitude, min_longitude), new GeoCoordinate(max_latitude, max_longitude), - count, geohashPrefix, device_identification, device_name, device_type, last_seen)); + new GeoCoordinate(minLatitude, minLongitude), new GeoCoordinate(maxLatitude, maxLongitude), + count, geohashPrefix, device)); } } catch (SQLException e) { - throw new DeviceManagementDAOException("Error occurred while retrieving information of " + + throw new DeviceManagementDAOException("Error occurred while retrieving information of " + "Geo Clusters", e); } finally { DeviceManagementDAOUtil.cleanupResources(stmt, rs); 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 4e87d8ab61..8911beca49 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 @@ -18,7 +18,6 @@ package org.wso2.carbon.device.mgt.core.dao.impl.device; -import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.device.mgt.common.Count; @@ -29,8 +28,8 @@ import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory; import org.wso2.carbon.device.mgt.core.dao.impl.AbstractDeviceDAOImpl; import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil; -import org.wso2.carbon.device.mgt.core.geo.GeoCluster; -import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate; +import org.wso2.carbon.device.mgt.common.geo.service.GeoCluster; +import org.wso2.carbon.device.mgt.common.geo.service.GeoCoordinate; import org.wso2.carbon.device.mgt.core.report.mgt.Constants; import java.sql.Connection; @@ -1133,6 +1132,8 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl { } } + //TODO: Override for MSSQL + /* @Override public List findGeoClusters(String deviceType, GeoCoordinate southWest, GeoCoordinate northEast, int geohashLength, int tenantId) throws DeviceManagementDAOException { @@ -1207,4 +1208,5 @@ public class SQLServerDeviceDAOImpl extends AbstractDeviceDAOImpl { } return geoClusters; } + */ } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/GeoCluster.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/GeoCluster.java deleted file mode 100644 index e4838aaf6e..0000000000 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/GeoCluster.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.wso2.carbon.device.mgt.core.geo; - -import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate; - -public class GeoCluster { - private GeoCoordinate coordinates; - private GeoCoordinate southWestBound; - private GeoCoordinate northEastBound; - private long count; - private String geohashPrefix; - private String deviceIdentification; - private String deviceName; - private String deviceType; - private String lastSeen; - - - public GeoCluster(GeoCoordinate coordinates, GeoCoordinate southWestBound, GeoCoordinate northEastBound, long count, - String geohashPrefix, String deviceIdentification, String deviceName, String deviceType, String lastSeen){ - this.coordinates=coordinates; - this.southWestBound=southWestBound; - this.northEastBound=northEastBound; - this.count=count; - this.geohashPrefix=geohashPrefix; - this.deviceIdentification=deviceIdentification; - this.deviceName=deviceName; - this.deviceType=deviceType; - this.lastSeen = lastSeen; - - } - - public String getGeohashPrefix() { - return geohashPrefix; - } - - public long getCount() { - return count; - } - - public GeoCoordinate getCoordinates() { - return coordinates; - } - - public GeoCoordinate getSouthWestBound() { - return southWestBound; - } - - public GeoCoordinate getNorthEastBound() { - return northEastBound; - } - - public String getDeviceIdentification() { - return deviceIdentification; - } - - public String getDeviceName() { - return deviceName; - } - - public String getDeviceType() { return deviceType; - } - - public String getLastSeen() { - return lastSeen; - } -} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/geoHash/GeoCoordinate.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/geoHash/GeoCoordinate.java deleted file mode 100644 index 45ca28f0d4..0000000000 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/geoHash/GeoCoordinate.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.wso2.carbon.device.mgt.core.geo.geoHash; - - - -public class GeoCoordinate { - private double latitude; - private double longitude; - - public GeoCoordinate(double latitude, double longitude){ - this.latitude=latitude; - this.longitude=longitude; - } - - public double getLatitude() { - return latitude; - } - - public double getLongitude() { - return longitude; - } -} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/geoHash/GeoHashGenerator.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/geoHash/GeoHashGenerator.java index 21d3ac85e9..557e4ebfe9 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/geoHash/GeoHashGenerator.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/geoHash/GeoHashGenerator.java @@ -1,15 +1,33 @@ +/* + * Copyright (c) 2018-2021, 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.core.geo.geoHash; import org.wso2.carbon.device.mgt.common.device.details.DeviceLocation; - -import java.util.HashMap; -import java.util.Map; +import org.wso2.carbon.device.mgt.common.geo.service.GeoCoordinate; public class GeoHashGenerator { + private static final String BASE_32 = "0123456789bcdefghjkmnpqrstuvwxyz"; private static final int GEOHASH_LENGTH = 16; - private GeoHashGenerator(){}; + private GeoHashGenerator() { + } private static int divideRangeByValue(double value, double[] range) { double mid = middle(range); @@ -36,7 +54,6 @@ public class GeoHashGenerator { } public static String encodeGeohash(double latitude, double longitude) { - int geohashLength=GEOHASH_LENGTH; double[] latRange = new double[]{-90.0, 90.0}; double[] lonRange = new double[]{-180.0, 180.0}; boolean isEven = true; @@ -44,7 +61,7 @@ public class GeoHashGenerator { int base32CharIndex = 0; StringBuilder geohash = new StringBuilder(); - while (geohash.length() < geohashLength) { + while (geohash.length() < GEOHASH_LENGTH) { if (isEven) { base32CharIndex = (base32CharIndex << 1) | divideRangeByValue(longitude, lonRange); } else { @@ -85,8 +102,7 @@ public class GeoHashGenerator { isEvenBit = !isEvenBit; } } - GeoCoordinate coordinates = new GeoCoordinate(middle(latRange),middle(lonRange)); - return coordinates; + return new GeoCoordinate(middle(latRange), middle(lonRange)); } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/geoHash/geoHashStrategy/GeoHashLengthStrategy.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/geoHash/geoHashStrategy/GeoHashLengthStrategy.java index f6845b305e..99032ee211 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/geoHash/geoHashStrategy/GeoHashLengthStrategy.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/geoHash/geoHashStrategy/GeoHashLengthStrategy.java @@ -1,11 +1,31 @@ +/* + * Copyright (c) 2018-2021, 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.core.geo.geoHash.geoHashStrategy; -import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate; +import org.wso2.carbon.device.mgt.common.geo.service.GeoCoordinate; /** * This interface is to decide a length for the geohash prefix * which will be used to group the clusters based on geohash */ public interface GeoHashLengthStrategy { + int getGeohashLength(GeoCoordinate southWest, GeoCoordinate northEast, int zoom); + } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/geoHash/geoHashStrategy/ZoomGeoHashLengthStrategy.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/geoHash/geoHashStrategy/ZoomGeoHashLengthStrategy.java index 0dd0e762f9..1eddf90602 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/geoHash/geoHashStrategy/ZoomGeoHashLengthStrategy.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/geoHash/geoHashStrategy/ZoomGeoHashLengthStrategy.java @@ -1,11 +1,31 @@ +/* + * Copyright (c) 2018-2021, 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.core.geo.geoHash.geoHashStrategy; -import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate; +import org.wso2.carbon.device.mgt.common.geo.service.GeoCoordinate; -/**A class that will decide the geoHashLength based on the zoom level and -* the boundaries of the map**/ +/** + * A class that will decide the geoHashLength based on the zoom level and + * the boundaries of the map + **/ -public class ZoomGeoHashLengthStrategy implements GeoHashLengthStrategy{ +public class ZoomGeoHashLengthStrategy implements GeoHashLengthStrategy { private int minGeohashLength = 1; private int maxGeohashLength = 16; @@ -19,35 +39,36 @@ public class ZoomGeoHashLengthStrategy implements GeoHashLengthStrategy{ return (int) Math.max(minGeohashLength, Math.min(a * Math.exp(b * zoom), maxGeohashLength)); } + public int getMinGeohashLength() { + return minGeohashLength; + } + public void setMinGeohashLength(int minGeohashLength) { this.minGeohashLength = minGeohashLength; } - public void setMaxGeohashLength(int maxGeohashLength) { - this.maxGeohashLength = maxGeohashLength; + public int getMaxGeohashLength() { + return maxGeohashLength; } - public void setMinZoom(int minZoom) { - this.minZoom = minZoom; + public void setMaxGeohashLength(int maxGeohashLength) { + this.maxGeohashLength = maxGeohashLength; } - public void setMaxZoom(int maxZoom) { - this.maxZoom = maxZoom; + public int getMinZoom() { + return minZoom; } - public int getMinGeohashLength() { - return minGeohashLength; + public void setMinZoom(int minZoom) { + this.minZoom = minZoom; } - public int getMaxGeohashLength() { - return maxGeohashLength; + public int getMaxZoom() { + return maxZoom; } - public int getMinZoom() { - return minZoom; + public void setMaxZoom(int maxZoom) { + this.maxZoom = maxZoom; } - public int getMaxZoom() { - return maxZoom; - } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/service/GeoLocationProviderServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/service/GeoLocationProviderServiceImpl.java index 9c77c75588..fad3138d44 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/service/GeoLocationProviderServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/service/GeoLocationProviderServiceImpl.java @@ -44,11 +44,11 @@ import org.wso2.carbon.device.mgt.common.event.config.EventConfigurationExceptio import org.wso2.carbon.device.mgt.common.event.config.EventConfigurationProviderService; import org.wso2.carbon.device.mgt.common.exceptions.TransactionManagementException; import org.wso2.carbon.device.mgt.common.geo.service.Alert; +import org.wso2.carbon.device.mgt.common.geo.service.AlertAlreadyExistException; import org.wso2.carbon.device.mgt.common.geo.service.GeoFence; import org.wso2.carbon.device.mgt.common.geo.service.GeoFenceEventMeta; -import org.wso2.carbon.device.mgt.common.geo.service.GeoLocationProviderService; import org.wso2.carbon.device.mgt.common.geo.service.GeoLocationBasedServiceException; -import org.wso2.carbon.device.mgt.common.geo.service.AlertAlreadyExistException; +import org.wso2.carbon.device.mgt.common.geo.service.GeoLocationProviderService; import org.wso2.carbon.device.mgt.common.geo.service.GeofenceData; import org.wso2.carbon.device.mgt.core.cache.impl.GeoCacheManagerImpl; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException; @@ -85,11 +85,11 @@ import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; -import java.util.Collections; import java.util.Set; import static org.wso2.carbon.device.mgt.common.DeviceManagementConstants.GeoServices.DAS_PORT; @@ -101,7 +101,7 @@ import static org.wso2.carbon.device.mgt.common.DeviceManagementConstants.GeoSer */ public class GeoLocationProviderServiceImpl implements GeoLocationProviderService { - private static Log log = LogFactory.getLog(GeoLocationProviderServiceImpl.class); + private static final Log log = LogFactory.getLog(GeoLocationProviderServiceImpl.class); /** * required soap header for authorization @@ -136,6 +136,18 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic this.geofenceDAO = DeviceManagementDAOFactory.getGeofenceDAO(); } + public static JWTClientManagerService getJWTClientManagerService() { + JWTClientManagerService jwtClientManagerService; + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + jwtClientManagerService = (JWTClientManagerService) ctx.getOSGiService(JWTClientManagerService.class, null); + if (jwtClientManagerService == null) { + String msg = "jwtClientManagerServicehas not initialized."; + log.error(msg); + throw new IllegalStateException(msg); + } + return jwtClientManagerService; + } + @Override public List getWithinAlerts(DeviceIdentifier identifier, String owner) throws GeoLocationBasedServiceException { @@ -227,7 +239,7 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic return fences; } catch (RegistryException | IOException e) { throw new GeoLocationBasedServiceException( - "Error occurred while getting the geo alerts" , e); + "Error occurred while getting the geo alerts", e); } } @@ -334,7 +346,7 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic @Override public boolean createGeoAlert(Alert alert, String alertType) - throws GeoLocationBasedServiceException,AlertAlreadyExistException { + throws GeoLocationBasedServiceException, AlertAlreadyExistException { return saveGeoAlert(alert, alertType, false); } @@ -346,12 +358,12 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic @Override public boolean updateGeoAlert(Alert alert, String alertType) - throws GeoLocationBasedServiceException,AlertAlreadyExistException { + throws GeoLocationBasedServiceException, AlertAlreadyExistException { return saveGeoAlert(alert, alertType, true); } private boolean saveGeoAlert(Alert alert, String alertType, boolean isUpdate) - throws GeoLocationBasedServiceException,AlertAlreadyExistException { + throws GeoLocationBasedServiceException, AlertAlreadyExistException { Type type = new TypeToken>() { }.getType(); @@ -408,7 +420,7 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic if (validationResponse.equals("success")) { allActiveExecutionPlanConfigs = eventprocessorStub.getAllActiveExecutionPlanConfigurations(); if (isUpdate) { - for (ExecutionPlanConfigurationDto activeExectionPlanConfig:allActiveExecutionPlanConfigs) { + for (ExecutionPlanConfigurationDto activeExectionPlanConfig : allActiveExecutionPlanConfigs) { activeExecutionPlan = activeExectionPlanConfig.getExecutionPlan(); if (activeExecutionPlan.contains(executionPlanName)) { eventprocessorStub.editActiveExecutionPlan(parsedTemplate, executionPlanName); @@ -417,14 +429,14 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic } eventprocessorStub.deployExecutionPlan(parsedTemplate); } else { - for (ExecutionPlanConfigurationDto activeExectionPlanConfig:allActiveExecutionPlanConfigs) { + for (ExecutionPlanConfigurationDto activeExectionPlanConfig : allActiveExecutionPlanConfigs) { activeExecutionPlan = activeExectionPlanConfig.getExecutionPlan(); if (activeExecutionPlan.contains(executionPlanName)) { throw new AlertAlreadyExistException("Execution plan already exists with name " + executionPlanName); } } - updateRegistry(getRegistryPath(alertType, alert.getQueryName()),content,options); + updateRegistry(getRegistryPath(alertType, alert.getQueryName()), content, options); eventprocessorStub.deployExecutionPlan(parsedTemplate); } } else { @@ -519,7 +531,7 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic if (validationResponse.equals("success")) { allActiveExecutionPlanConfigs = eventprocessorStub.getAllActiveExecutionPlanConfigurations(); if (isUpdate) { - for (ExecutionPlanConfigurationDto activeExectionPlanConfig:allActiveExecutionPlanConfigs) { + for (ExecutionPlanConfigurationDto activeExectionPlanConfig : allActiveExecutionPlanConfigs) { activeExecutionPlan = activeExectionPlanConfig.getExecutionPlan(); if (activeExecutionPlan.contains(executionPlanName)) { eventprocessorStub.editActiveExecutionPlan(parsedTemplate, executionPlanName); @@ -528,7 +540,7 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic } eventprocessorStub.deployExecutionPlan(parsedTemplate); } else { - for (ExecutionPlanConfigurationDto activeExectionPlanConfig:allActiveExecutionPlanConfigs) { + for (ExecutionPlanConfigurationDto activeExectionPlanConfig : allActiveExecutionPlanConfigs) { activeExecutionPlan = activeExectionPlanConfig.getExecutionPlan(); if (activeExecutionPlan.contains(executionPlanName)) { throw new AlertAlreadyExistException("Execution plan already exists with name " @@ -605,32 +617,32 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic } private String getRegistryPath(String alertType, String queryName) - throws GeoLocationBasedServiceException { - String path = ""; - if (GeoServices.ALERT_TYPE_WITHIN.equals(alertType)) { - path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_WITHIN + - "/" + "/" + queryName; - } else if (GeoServices.ALERT_TYPE_EXIT.equals(alertType)) { - path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_EXIT + - "/" + queryName; - } else if (GeoServices.ALERT_TYPE_SPEED.equals(alertType)) { - path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_SPEED + - "/" ; - } else if (GeoServices.ALERT_TYPE_PROXIMITY.equals(alertType)) { - path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_PROXIMITY + - "/" + queryName; - } else if (GeoServices.ALERT_TYPE_STATIONARY.equals(alertType)) { - path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_STATIONARY + - "/" + queryName; - } else if (GeoServices.ALERT_TYPE_TRAFFIC.equals(alertType)) { - path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_TRAFFIC + - "/" + queryName; - } else { - throw new GeoLocationBasedServiceException( - "Unrecognized execution plan type: " + alertType); - } - return path; + throws GeoLocationBasedServiceException { + String path = ""; + if (GeoServices.ALERT_TYPE_WITHIN.equals(alertType)) { + path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_WITHIN + + "/" + "/" + queryName; + } else if (GeoServices.ALERT_TYPE_EXIT.equals(alertType)) { + path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_EXIT + + "/" + queryName; + } else if (GeoServices.ALERT_TYPE_SPEED.equals(alertType)) { + path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_SPEED + + "/"; + } else if (GeoServices.ALERT_TYPE_PROXIMITY.equals(alertType)) { + path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_PROXIMITY + + "/" + queryName; + } else if (GeoServices.ALERT_TYPE_STATIONARY.equals(alertType)) { + path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_STATIONARY + + "/" + queryName; + } else if (GeoServices.ALERT_TYPE_TRAFFIC.equals(alertType)) { + path = GeoServices.REGISTRY_PATH_FOR_ALERTS + GeoServices.ALERT_TYPE_TRAFFIC + + "/" + queryName; + } else { + throw new GeoLocationBasedServiceException( + "Unrecognized execution plan type: " + alertType); } + return path; + } private String getExecutionPlanName(String alertType, String queryName, String deviceId, String owner) { if (GeoServices.ALERT_TYPE_TRAFFIC.equals(alertType)) { @@ -798,7 +810,7 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic InputStream inputStream = resource.getContentStream(); StringWriter writer = new StringWriter(); IOUtils.copy(inputStream, writer, "UTF-8"); - return "{'speedLimit':" + writer.toString() + "}"; + return "{'speedLimit':" + writer + "}"; } catch (RegistryException | IOException e) { return "{'content': false}"; } @@ -816,7 +828,7 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic InputStream inputStream = resource.getContentStream(); StringWriter writer = new StringWriter(); IOUtils.copy(inputStream, writer, "UTF-8"); - return "{'speedLimit':" + writer.toString() + "}"; + return "{'speedLimit':" + writer + "}"; } catch (RegistryException | IOException e) { return "{'content': false}"; } @@ -835,8 +847,8 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic List proxTimeObj = (List) props.get(GeoServices.PROXIMITY_TIME); return String.format("{proximityDistance:\"%s\", proximityTime:\"%s\"}", - proxDisObj != null ? proxDisObj.get(0).toString() : "", - proxTimeObj != null ? proxTimeObj.get(0).toString() : ""); + proxDisObj != null ? proxDisObj.get(0).toString() : "", + proxTimeObj != null ? proxTimeObj.get(0).toString() : ""); } else { return "{'content': false}"; } @@ -868,7 +880,6 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic } } - @Override public List getStationaryAlerts(DeviceIdentifier identifier, String owner) throws GeoLocationBasedServiceException { @@ -1079,7 +1090,7 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic } private String parseTemplate(String alertType, Map parseMap) throws - GeoLocationBasedServiceException { + GeoLocationBasedServiceException { String templatePath = "alerts/Geo-ExecutionPlan-" + alertType + "_alert.siddhiql"; InputStream resource = getClass().getClassLoader().getResourceAsStream(templatePath); if (resource == null) { @@ -1142,22 +1153,22 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic } private void updateRegistry(String path, Object content, Map options) - throws GeoLocationBasedServiceException { - try { + throws GeoLocationBasedServiceException { + try { - Registry registry = getGovernanceRegistry(); - Resource newResource = registry.newResource(); - newResource.setContent(content); - newResource.setMediaType("application/json"); - for (Map.Entry option : options.entrySet()) { - newResource.addProperty(option.getKey(), option.getValue()); - } - registry.put(path, newResource); - } catch (RegistryException e) { - throw new GeoLocationBasedServiceException( - "Error occurred while setting the Within Alert", e); + Registry registry = getGovernanceRegistry(); + Resource newResource = registry.newResource(); + newResource.setContent(content); + newResource.setMediaType("application/json"); + for (Map.Entry option : options.entrySet()) { + newResource.addProperty(option.getKey(), option.getValue()); } + registry.put(path, newResource); + } catch (RegistryException e) { + throw new GeoLocationBasedServiceException( + "Error occurred while setting the Within Alert", e); } + } /** * Loads the keystore. @@ -1207,7 +1218,7 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic */ private SSLContext initSSLConnection(String tenantAdminUser) throws NoSuchAlgorithmException, UnrecoverableKeyException, - KeyStoreException, KeyManagementException, IOException, CertificateException { + KeyStoreException, KeyManagementException, IOException, CertificateException { String keyStorePassword = ServerConfiguration.getInstance().getFirstProperty("Security.KeyStore.Password"); String trustStorePassword = ServerConfiguration.getInstance().getFirstProperty( "Security.TrustStore.Password"); @@ -1243,18 +1254,6 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic } } - public static JWTClientManagerService getJWTClientManagerService() { - JWTClientManagerService jwtClientManagerService; - PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); - jwtClientManagerService = (JWTClientManagerService) ctx.getOSGiService(JWTClientManagerService.class, null); - if (jwtClientManagerService == null) { - String msg = "jwtClientManagerServicehas not initialized."; - log.error(msg); - throw new IllegalStateException(msg); - } - return jwtClientManagerService; - } - @Override public boolean createGeofence(GeofenceData geofenceData) throws GeoLocationBasedServiceException, EventConfigurationException { int tenantId; @@ -1291,7 +1290,7 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic List createdEventIds; try { setEventSource(geofenceData.getEventConfig()); - eventConfigService = DeviceManagementDataHolder.getInstance().getEventConfigurationService(); + eventConfigService = DeviceManagementDataHolder.getInstance().getEventConfigurationService(); createdEventIds = eventConfigService.createEventsOfDeviceGroup(geofenceData.getEventConfig(), geofenceData.getGroupIds()); DeviceManagementDAOFactory.beginTransaction(); geofenceDAO.createGeofenceEventMapping(geofenceData.getId(), createdEventIds); @@ -1333,6 +1332,7 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic /** * Set source of the event to GEOFENCE + * * @param eventConfig event list to be set event source */ private void setEventSource(List eventConfig) { @@ -1365,7 +1365,7 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic } return geofence; } catch (DeviceManagementDAOException e) { - String msg = "Error occurred while retrieving Geofence data with ID "+fenceId; + String msg = "Error occurred while retrieving Geofence data with ID " + fenceId; log.error(msg, e); throw new GeoLocationBasedServiceException(msg, e); } catch (SQLException e) { @@ -1608,7 +1608,7 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic try { tenantId = DeviceManagementDAOUtil.getTenantId(); setEventSource(geofenceData.getEventConfig()); - eventConfigService = DeviceManagementDataHolder.getInstance().getEventConfigurationService(); + eventConfigService = DeviceManagementDataHolder.getInstance().getEventConfigurationService(); if (eventConfigService == null) { String msg = "Failed to load EventConfigurationProviderService osgi service of tenant " + tenantId; log.error(msg); @@ -1747,8 +1747,9 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic /** * Delete events of geofence + * * @param geofenceData geofence mapped with deleting events - * @param eventList events to be deleted + * @param eventList events to be deleted */ private void deleteGeoFenceEvents(GeofenceData geofenceData, List eventList) throws GeoLocationBasedServiceException { @@ -1762,7 +1763,7 @@ public class GeoLocationProviderServiceImpl implements GeoLocationProviderServic } try { - EventConfigurationProviderService eventConfigService = DeviceManagementDataHolder + EventConfigurationProviderService eventConfigService = DeviceManagementDataHolder .getInstance().getEventConfigurationService(); eventConfigService.deleteEvents(eventList); eventConfigService.createEventOperationTask(OperationMgtConstants.OperationCodes.EVENT_REVOKE, diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/task/EventCreateCallback.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/task/EventCreateCallback.java index a5277e09a8..02c49b7406 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/task/EventCreateCallback.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/task/EventCreateCallback.java @@ -17,6 +17,7 @@ */ package org.wso2.carbon.device.mgt.core.geo.task; + public interface EventCreateCallback { void onCompleteEventOperation(Object values); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/task/EventOperationTaskException.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/task/EventOperationTaskException.java index 4e8e14d914..3288410e76 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/task/EventOperationTaskException.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/task/EventOperationTaskException.java @@ -18,7 +18,8 @@ package org.wso2.carbon.device.mgt.core.geo.task; -public class EventOperationTaskException extends Exception{ +public class EventOperationTaskException extends Exception { + public EventOperationTaskException(String message) { super(message); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/task/GeoFenceEventOperationManager.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/task/GeoFenceEventOperationManager.java index e18968524f..daea9d53df 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/task/GeoFenceEventOperationManager.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/task/GeoFenceEventOperationManager.java @@ -45,14 +45,15 @@ public class GeoFenceEventOperationManager { this.eventOperationCode = eventOperationCode; this.tenantId = tenantId; this.callback = callback; - isEventEnabled= DeviceConfigurationManager.getInstance().getDeviceManagementConfig() + isEventEnabled = DeviceConfigurationManager.getInstance().getDeviceManagementConfig() .getEventOperationTaskConfiguration().isEnabled(); } /** * Get executor for create EVENT_CONFIG / EVENT_REVOKE operations at the time of a device/s * assigned into a group or removed from a group - * @param groupId Id of the assigned / removed group + * + * @param groupId Id of the assigned / removed group * @param deviceIdentifiers Device identifiers assigned to / removed from the group * @return {@link GroupAssignmentEventOperationExecutor} Created executor to create operations */ @@ -72,7 +73,8 @@ public class GeoFenceEventOperationManager { /** * Get executor for create EVENT_CONFIG / EVENT_REVOKE operations at the time of a event is created - * @param groupIds list of group ids to apply the created event + * + * @param groupIds list of group ids to apply the created event * @param eventMetaData contains all the data of the related event * @return {@link EventOperationExecutor} The created event executor object */ diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java index aed6c935a3..1ce3d8a006 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java @@ -53,8 +53,6 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.HashMap; -import java.util.Date; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -167,7 +165,7 @@ public class GenericOperationDAOImpl implements OperationDAO { try { Connection connection = OperationManagementDAOFactory.getConnection(); StringBuilder query = new StringBuilder("SELECT OPERATION_ID, ENROLMENT_ID FROM DM_ENROLMENT_OP_MAPPING " + - "WHERE OPERATION_CODE = ? AND STATUS = ? AND ENROLMENT_ID IN ("); + "WHERE OPERATION_CODE = ? AND STATUS IN ('NOTNOW', 'PENDING') AND ENROLMENT_ID IN ("); for (int i = 0; i < enrolmentIds.length; i++) { query.append(" ?,"); } @@ -175,10 +173,9 @@ public class GenericOperationDAOImpl implements OperationDAO { query.append(")"); stmt = connection.prepareStatement(query.toString()); stmt.setString(1, operationCode); - stmt.setString(2, Operation.Status.PENDING.toString()); for (int i = 0; i < enrolmentIds.length; i++) { - stmt.setInt(i + 3, enrolmentIds[i]); + stmt.setInt(i + 2, enrolmentIds[i]); } rs = stmt.executeQuery(); @@ -324,7 +321,7 @@ public class GenericOperationDAOImpl implements OperationDAO { for (int i = 0; i < operationResponseIds.size(); i++) { builder.append("?,"); } - sql1 += builder.deleteCharAt(builder.length() - 1).toString() + ")"; + sql1 += builder.deleteCharAt(builder.length() - 1) + ")"; stmt = conn.prepareStatement(sql1); int i; for (i = 0; i < operationResponseIds.size(); i++) { 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 f084e35c3a..6ff661568c 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 @@ -62,6 +62,7 @@ import org.wso2.carbon.device.mgt.common.exceptions.DeviceTypeNotFoundException; import org.wso2.carbon.device.mgt.common.exceptions.InvalidDeviceException; import org.wso2.carbon.device.mgt.common.exceptions.UnauthorizedDeviceAccessException; import org.wso2.carbon.device.mgt.common.exceptions.UserNotFoundException; +import org.wso2.carbon.device.mgt.common.geo.service.GeoQuery; import org.wso2.carbon.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitationDetails; import org.wso2.carbon.device.mgt.common.license.mgt.License; import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; @@ -74,8 +75,8 @@ import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService; import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException; import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.dto.DeviceTypeVersion; -import org.wso2.carbon.device.mgt.core.geo.GeoCluster; -import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate; +import org.wso2.carbon.device.mgt.common.geo.service.GeoCluster; +import org.wso2.carbon.device.mgt.common.geo.service.GeoCoordinate; import java.sql.SQLException; import java.util.Date; @@ -827,8 +828,7 @@ public interface DeviceManagementProviderService { List getDeviceEnrolledTenants() throws DeviceManagementException; - List findGeoClusters(String deviceType, GeoCoordinate southWest, GeoCoordinate northEast, - int geohashLength) throws DeviceManagementException; + List findGeoClusters(GeoQuery geoQuery) throws DeviceManagementException; int getDeviceCountOfTypeByStatus(String deviceType, String deviceStatus) throws DeviceManagementException; 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 e9082f4010..5bf4162729 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 @@ -91,6 +91,7 @@ import org.wso2.carbon.device.mgt.common.exceptions.InvalidDeviceException; import org.wso2.carbon.device.mgt.common.exceptions.TransactionManagementException; import org.wso2.carbon.device.mgt.common.exceptions.UnauthorizedDeviceAccessException; import org.wso2.carbon.device.mgt.common.exceptions.UserNotFoundException; +import org.wso2.carbon.device.mgt.common.geo.service.GeoQuery; import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup; import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroupConstants; import org.wso2.carbon.device.mgt.common.group.mgt.GroupAlreadyExistException; @@ -127,8 +128,8 @@ import org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceInformationManag import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.dto.DeviceTypeServiceIdentifier; import org.wso2.carbon.device.mgt.core.dto.DeviceTypeVersion; -import org.wso2.carbon.device.mgt.core.geo.GeoCluster; -import org.wso2.carbon.device.mgt.core.geo.geoHash.GeoCoordinate; +import org.wso2.carbon.device.mgt.common.geo.service.GeoCluster; +import org.wso2.carbon.device.mgt.common.geo.service.GeoCoordinate; import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder; import org.wso2.carbon.device.mgt.core.internal.DeviceManagementServiceComponent; import org.wso2.carbon.device.mgt.core.internal.PluginInitializationListener; @@ -3376,18 +3377,13 @@ public class DeviceManagementProviderServiceImpl implements DeviceManagementProv } @Override - public List findGeoClusters(String deviceType, GeoCoordinate southWest, GeoCoordinate northEast, - int geohashLength) throws DeviceManagementException { + public List findGeoClusters(GeoQuery geoQuery) throws DeviceManagementException { if (log.isDebugEnabled()) { - if (deviceType == null || deviceType.isEmpty()) { - log.debug("get information about geo clusters."); - } else { - log.debug("get information about geo clusters for device type: " + deviceType); - } + log.debug("Get information about geo clusters for query: " + new Gson().toJson(geoQuery)); } try { DeviceManagementDAOFactory.openConnection(); - return deviceDAO.findGeoClusters(deviceType, southWest, northEast, geohashLength, this.getTenantId()); + return deviceDAO.findGeoClusters(geoQuery, this.getTenantId()); } catch (DeviceManagementDAOException e) { String msg = "Error occurred while retrieving the geo clusters."; 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/config/OperationMetadata.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/config/OperationMetadata.java index 81a4139d8e..9fc9715f4d 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/config/OperationMetadata.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/config/OperationMetadata.java @@ -58,6 +58,7 @@ import java.util.List; "method", "contentType", "permission", + "scope", "filterList" }) public class OperationMetadata { @@ -74,6 +75,9 @@ public class OperationMetadata { @XmlElement(name = "permission") private String permission; + @XmlElement(name = "scope") + private String scope; + @XmlElementWrapper(name = "filters") @XmlElement(name = "filter") private List filterList; @@ -110,6 +114,14 @@ public class OperationMetadata { this.permission = permission; } + public String getScope() { + return scope; + } + + public void setScope(String scope) { + this.scope = scope; + } + public List getFilterList() { return filterList; } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/feature/ConfigurationBasedFeatureManager.java b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/feature/ConfigurationBasedFeatureManager.java index 1043628369..95c702041f 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/feature/ConfigurationBasedFeatureManager.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.extensions/src/main/java/org/wso2/carbon/device/mgt/extensions/device/type/template/feature/ConfigurationBasedFeatureManager.java @@ -63,6 +63,7 @@ public class ConfigurationBasedFeatureManager implements FeatureManager { private static final String OPERATION_META = "operationMeta"; private static final String CONTENT_TYPE = "contentType"; private static final String PERMISSION = "permission"; + private static final String SCOPE = "scope"; private static final String ICON = "icon"; private static final String FILTERS = "filters"; private static final String PATH_PARAMS = "pathParams"; @@ -108,6 +109,9 @@ public class ConfigurationBasedFeatureManager implements FeatureManager { if (StringUtils.isNotEmpty(metadata.getPermission())) { operationMeta.put(PERMISSION, metadata.getPermission()); } + if (StringUtils.isNotEmpty(metadata.getScope())) { + operationMeta.put(SCOPE, metadata.getScope()); + } if (metadata.getFilterList() != null && metadata.getFilterList().size() > 0) { operationMeta.put(FILTERS, metadata.getFilterList()); } diff --git a/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/pom.xml b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/pom.xml index 2853017c24..2a9d3b6c2f 100644 --- a/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/pom.xml +++ b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/pom.xml @@ -44,10 +44,6 @@ org.wso2.carbon org.wso2.carbon.user.core - - - org.wso2.carbon.apimgt - org.wso2.carbon.apimgt.keymgt com.googlecode.json-simple.wso2 @@ -103,7 +99,7 @@ org.wso2.carbon.utils, org.wso2.carbon.context, org.wso2.carbon.identity.oauth.*;version="${carbon.identity.framework.version.range}", - org.wso2.carbon.apimgt.keymgt.*;version="${carbon.api.mgt.version.range}", + org.wso2.carbon.base, org.wso2.carbon.identity.application.authentication.framework.model;version="${carbon.identity.framework.version.range}", org.wso2.carbon.identity.base;version="${carbon.identity.framework.version.range}", diff --git a/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/handlers/grant/AccessTokenGrantHandler.java b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/handlers/grant/AccessTokenGrantHandler.java index 1153cb0561..92dd1ad814 100644 --- a/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/handlers/grant/AccessTokenGrantHandler.java +++ b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/handlers/grant/AccessTokenGrantHandler.java @@ -21,7 +21,6 @@ package org.wso2.carbon.device.mgt.oauth.extensions.handlers.grant; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.apimgt.keymgt.ScopesIssuer; import org.wso2.carbon.device.mgt.oauth.extensions.handlers.grant.oauth.validator.LocalOAuthValidator; import org.wso2.carbon.device.mgt.oauth.extensions.handlers.grant.oauth.validator.OAuthValidationResponse; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; @@ -57,11 +56,6 @@ public class AccessTokenGrantHandler extends AbstractAuthorizationGrantHandler { } } - @Override - public boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) { - return ScopesIssuer.getInstance().setScopes(tokReqMsgCtx); - } - @Override public boolean validateGrant(OAuthTokenReqMessageContext tokReqMsgCtx) throws IdentityOAuth2Exception { if (!super.validateGrant(tokReqMsgCtx)) { diff --git a/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/handlers/grant/ExtendedJWTGrantHandler.java b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/handlers/grant/ExtendedJWTGrantHandler.java index 006317f179..0fe613fa31 100644 --- a/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/handlers/grant/ExtendedJWTGrantHandler.java +++ b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/handlers/grant/ExtendedJWTGrantHandler.java @@ -20,14 +20,10 @@ package org.wso2.carbon.device.mgt.oauth.extensions.handlers.grant; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.apimgt.keymgt.ScopesIssuer; -import org.wso2.carbon.base.MultitenantConstants; -import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception; import org.wso2.carbon.identity.oauth2.grant.jwt.JWTBearerGrantHandler; import org.wso2.carbon.identity.oauth2.model.RequestParameter; import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext; -import org.wso2.carbon.utils.multitenancy.MultitenantUtils; /** * This sets up user with tenant aware username. @@ -37,11 +33,6 @@ public class ExtendedJWTGrantHandler extends JWTBearerGrantHandler { private static Log log = LogFactory.getLog(ExtendedJWTGrantHandler.class); private static final String TENANT_DOMAIN_KEY = "tenantDomain"; - @Override - public boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) { - return ScopesIssuer.getInstance().setScopes(tokReqMsgCtx); - } - @Override public boolean validateGrant(OAuthTokenReqMessageContext tokReqMsgCtx) throws IdentityOAuth2Exception { diff --git a/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/handlers/grant/ExtendedSAML2BearerGrantHandler.java b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/handlers/grant/ExtendedSAML2BearerGrantHandler.java index 5caededdaf..749cf84147 100644 --- a/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/handlers/grant/ExtendedSAML2BearerGrantHandler.java +++ b/components/identity-extensions/org.wso2.carbon.device.mgt.oauth.extensions/src/main/java/org/wso2/carbon/device/mgt/oauth/extensions/handlers/grant/ExtendedSAML2BearerGrantHandler.java @@ -20,7 +20,6 @@ package org.wso2.carbon.device.mgt.oauth.extensions.handlers.grant; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.apimgt.keymgt.ScopesIssuer; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; import org.wso2.carbon.identity.oauth2.IdentityOAuth2Exception; import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext; @@ -34,11 +33,6 @@ import org.wso2.carbon.utils.multitenancy.MultitenantUtils; public class ExtendedSAML2BearerGrantHandler extends SAML2BearerGrantHandler { private static Log log = LogFactory.getLog(ExtendedSAML2BearerGrantHandler.class); - @Override - public boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) { - return ScopesIssuer.getInstance().setScopes(tokReqMsgCtx); - } - @Override public boolean validateGrant(OAuthTokenReqMessageContext tokReqMsgCtx) throws IdentityOAuth2Exception { if(!super.validateGrant(tokReqMsgCtx)){ diff --git a/components/identity-extensions/pom.xml b/components/identity-extensions/pom.xml index 27d6a1bc79..05a00e3768 100644 --- a/components/identity-extensions/pom.xml +++ b/components/identity-extensions/pom.xml @@ -33,6 +33,7 @@ http://wso2.org + org.wso2.carbon.device.mgt.oauth.extensions org.wso2.carbon.identity.jwt.client.extension diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/InvokerHandler.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/InvokerHandler.java index 1bc5de7831..7bf0861f72 100644 --- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/InvokerHandler.java +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/InvokerHandler.java @@ -48,7 +48,6 @@ import org.apache.http.entity.mime.HttpMultipartMode; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.content.InputStreamBody; import io.entgra.ui.request.interceptor.beans.ProxyResponse; -import org.wso2.carbon.context.CarbonContext; import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; @@ -112,11 +111,6 @@ public class InvokerHandler extends HttpServlet { HttpGet getRequest = new HttpGet(generateBackendRequestURL(req)); copyRequestHeaders(req, getRequest, false); getRequest.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BEARER + authData.getAccessToken()); - if (apiEndpoint.equals(System.getProperty("iot.reporting.webapp.host"))) { - getRequest.setHeader("Tenant-Id", String.valueOf( - CarbonContext.getThreadLocalCarbonContext().getTenantId() - )); - } ProxyResponse proxyResponse = HandlerUtil.execute(getRequest); if (HandlerConstants.TOKEN_IS_EXPIRED.equals(proxyResponse.getExecutorResponse())) { proxyResponse = retryRequestWithRefreshedToken(req, resp, getRequest); diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/LoginHandler.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/LoginHandler.java index 6042f66031..b1e34a99da 100644 --- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/LoginHandler.java +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/LoginHandler.java @@ -39,6 +39,7 @@ import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.protocol.HTTP; import io.entgra.ui.request.interceptor.beans.ProxyResponse; +import org.json.JSONString; import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; @@ -70,13 +71,14 @@ public class LoginHandler extends HttpServlet { httpSession.invalidate(); } httpSession = req.getSession(true); - //setting session to expiry in 5 minutes - httpSession.setMaxInactiveInterval(Math.toIntExact(HandlerConstants.TIMEOUT)); JsonObject uiConfigJsonObject = HandlerUtil.getUIConfigAndPersistInSession(uiConfigUrl, gatewayUrl, httpSession, resp); - JsonArray tags = uiConfigJsonObject.get("appRegistration").getAsJsonObject().get("tags").getAsJsonArray(); JsonArray scopes = uiConfigJsonObject.get("scopes").getAsJsonArray(); + int sessionTimeOut = Integer.parseInt(String.valueOf(uiConfigJsonObject.get("sessionTimeOut"))); + + //setting session to expire in 1h + httpSession.setMaxInactiveInterval(sessionTimeOut); // Check if OAuth app cache exists. If not create a new application. LoginCacheManager loginCacheManager = new LoginCacheManager(); diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/SsoLoginCallbackHandler.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/SsoLoginCallbackHandler.java index e77137ff1c..4bd8a3daaa 100644 --- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/SsoLoginCallbackHandler.java +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/SsoLoginCallbackHandler.java @@ -27,7 +27,6 @@ import io.entgra.ui.request.interceptor.util.HandlerUtil; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpHeaders; -import org.apache.http.HttpStatus; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; @@ -50,9 +49,7 @@ public class SsoLoginCallbackHandler extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { String code = req.getParameter("code"); HttpSession session = req.getSession(false); - String scope = session.getAttribute("scope").toString(); String iotsCorePort = System.getProperty(HandlerConstants.IOT_CORE_HTTPS_PORT_ENV_VAR); - if (HandlerConstants.HTTP_PROTOCOL.equals(req.getScheme())) { iotsCorePort = System.getProperty(HandlerConstants.IOT_CORE_HTTP_PORT_ENV_VAR); } @@ -62,6 +59,19 @@ public class SsoLoginCallbackHandler extends HttpServlet { String iotsCoreUrl = req.getScheme() + HandlerConstants.SCHEME_SEPARATOR + System.getProperty(HandlerConstants.IOT_CORE_HOST_ENV_VAR) + HandlerConstants.COLON + iotsCorePort; + if (session == null) { + String baseContextPath = req.getContextPath(); + String applicationName = baseContextPath.substring(1, baseContextPath.indexOf("-ui-request-handler")); + if (applicationName.equals("entgra")) { + resp.sendRedirect(iotsCoreUrl + "/endpoint-mgt"); + } else { + resp.sendRedirect(iotsCoreUrl + "/" + applicationName); + } + return; + } + + String scope = session.getAttribute("scope").toString(); + HttpPost tokenEndpoint = new HttpPost(iotsCoreUrl + HandlerConstants.TOKEN_ENDPOINT); tokenEndpoint.setHeader(HttpHeaders.AUTHORIZATION, HandlerConstants.BASIC + session.getAttribute("encodedClientApp")); tokenEndpoint.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED.toString()); @@ -76,11 +86,9 @@ public class SsoLoginCallbackHandler extends HttpServlet { ProxyResponse tokenResultResponse = HandlerUtil.execute(tokenEndpoint); JsonParser jsonParser = new JsonParser(); - JsonElement jTokenResult = jsonParser.parse(tokenResultResponse.getData()); if (jTokenResult.isJsonObject()) { JsonObject jTokenResultAsJsonObject = jTokenResult.getAsJsonObject(); - AuthData authData = new AuthData(); authData.setClientId(session.getAttribute("clientId").toString()); authData.setClientSecret(session.getAttribute("clientSecret").toString()); @@ -89,7 +97,6 @@ public class SsoLoginCallbackHandler extends HttpServlet { authData.setRefreshToken(jTokenResultAsJsonObject.get("refresh_token").getAsString()); authData.setScope(jTokenResultAsJsonObject.get("scope").getAsString()); session.setAttribute(HandlerConstants.SESSION_AUTH_DATA_KEY, authData); - resp.sendRedirect(session.getAttribute("redirectUrl").toString()); } } diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/SsoLoginHandler.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/SsoLoginHandler.java index 15358ad362..6ae4c55ed7 100644 --- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/SsoLoginHandler.java +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/SsoLoginHandler.java @@ -72,6 +72,7 @@ public class SsoLoginHandler extends HttpServlet { private static String adminPassword; private static String gatewayUrl; private static String iotsCoreUrl; + private static int sessionTimeOut; private static String encodedAdminCredentials; private static String encodedClientApp; private static String applicationId; @@ -88,12 +89,12 @@ public class SsoLoginHandler extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) { try { httpSession = req.getSession(false); - if (httpSession != null) { httpSession.invalidate(); } httpSession = req.getSession(true); + initializeAdminCredentials(); baseContextPath = req.getContextPath(); applicationName = baseContextPath.substring(1, baseContextPath.indexOf("-ui-request-handler")); @@ -157,6 +158,7 @@ public class SsoLoginHandler extends HttpServlet { uiConfigJsonObject = HandlerUtil.getUIConfigAndPersistInSession(uiConfigUrl, gatewayUrl, httpSession, resp); JsonArray tags = uiConfigJsonObject.get("appRegistration").getAsJsonObject().get("tags").getAsJsonArray(); JsonArray scopes = uiConfigJsonObject.get("scopes").getAsJsonArray(); + sessionTimeOut = Integer.parseInt(String.valueOf(uiConfigJsonObject.get("sessionTimeOut"))); // Register the client application HttpPost apiRegEndpoint = new HttpPost(gatewayUrl + HandlerConstants.APP_REG_ENDPOINT); @@ -294,6 +296,7 @@ public class SsoLoginHandler extends HttpServlet { httpSession.setAttribute("encodedClientApp", encodedClientApp); httpSession.setAttribute("scope", scopes); httpSession.setAttribute("redirectUrl", req.getParameter("redirect")); + httpSession.setMaxInactiveInterval(sessionTimeOut); } /*** diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerConstants.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerConstants.java index fa7020ac6d..4c864c81e5 100644 --- a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerConstants.java +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/util/HandlerConstants.java @@ -81,5 +81,5 @@ public class HandlerConstants { public static final String IOT_GW_HOST_ENV_VAR = "iot.gateway.host"; public static final String IOT_GW_HTTP_PORT_ENV_VAR = "iot.gateway.http.port"; public static final String IOT_GW_HTTPS_PORT_ENV_VAR = "iot.gateway.https.port"; - public static final String USER_SCOPES = "user-scopes"; + public static final String USER_SCOPES = "userScopes"; } diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml index a0ba89e8b7..36fe025034 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/conf/mdm-ui-config.xml @@ -20,6 +20,8 @@ true true + + 3600 application_management @@ -177,6 +179,8 @@ perm:metadata:view perm:metadata:create perm:metadata:update + perm:android:google-account + perm:android:update-default-sim device-mgt diff --git a/pom.xml b/pom.xml index 5f6a2d8d1d..ea11339d6e 100644 --- a/pom.xml +++ b/pom.xml @@ -869,11 +869,6 @@ - - org.wso2.carbon.apimgt - org.wso2.carbon.apimgt.keymgt - ${carbon.api.mgt.version} - org.wso2.carbon.apimgt org.wso2.carbon.apimgt.api