From 3816e09b1d7fe72845c3bba627862d795c7fd29e Mon Sep 17 00:00:00 2001 From: Farheen99 Date: Sat, 24 Apr 2021 11:26:59 +0530 Subject: [PATCH 1/7] Add a query to get the applications sort according to latest timestamp order (cherry picked from commit 86720b1a458cc1ab1ba35896921ed8077f4ee6b2) --- .../application/GenericApplicationDAOImpl.java | 15 +++++++++++++-- .../application/OracleApplicationDAOImpl.java | 15 +++++++++++++-- .../application/SQLServerApplicationDAOImpl.java | 15 +++++++++++++-- 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/GenericApplicationDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/GenericApplicationDAOImpl.java index a4d9d4a87a..dd8880c6fc 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/GenericApplicationDAOImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/GenericApplicationDAOImpl.java @@ -134,7 +134,8 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic + "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, " + "AP_APP_RELEASE.RATING AS RELEASE_RATING, " + "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, " - + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT " + + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT, " + + "NEW_AP_APP_LIFECYCLE_STATE.UPDATED_AT AS LATEST_UPDATE " + "FROM AP_APP " + "INNER JOIN AP_APP_RELEASE ON " + "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID " @@ -181,7 +182,17 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic if (filter.getLimit() != -1) { sql += "LIMIT ? OFFSET ? "; } - sql += ") AS app_data ON app_data.ID = AP_APP.ID WHERE AP_APP.TENANT_ID = ? ORDER BY AP_APP.ID"; + sql += ") AS app_data ON app_data.ID = AP_APP.ID " + + "INNER JOIN (" + + "SELECT AP_APP_LIFECYCLE_STATE.UPDATED_AT, AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID " + + "FROM AP_APP_LIFECYCLE_STATE WHERE AP_APP_LIFECYCLE_STATE.ID " + + "IN(SELECT MAX(AP_APP_LIFECYCLE_STATE.ID) " + + "FROM AP_APP_LIFECYCLE_STATE " + + "GROUP BY AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID)) AS NEW_AP_APP_LIFECYCLE_STATE " + + "ON AP_APP_RELEASE.ID = NEW_AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID " + + "WHERE AP_APP.TENANT_ID = ? " + + "ORDER BY AP_APP.ID, LATEST_UPDATE DESC"; + try { Connection conn = this.getDBConnection(); try (PreparedStatement stmt = conn.prepareStatement(sql)) { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/OracleApplicationDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/OracleApplicationDAOImpl.java index c57ef8a07d..bb705d7f82 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/OracleApplicationDAOImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/OracleApplicationDAOImpl.java @@ -80,7 +80,8 @@ public class OracleApplicationDAOImpl extends GenericApplicationDAOImpl { + "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, " + "AP_APP_RELEASE.RATING AS RELEASE_RATING, " + "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, " - + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT " + + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT, " + + "NEW_AP_APP_LIFECYCLE_STATE.UPDATED_AT AS LATEST_UPDATE " + "FROM AP_APP " + "INNER JOIN AP_APP_RELEASE ON " + "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID " @@ -125,7 +126,17 @@ public class OracleApplicationDAOImpl extends GenericApplicationDAOImpl { if (filter.getLimit() != -1) { sql += "OFFSET ? ROWS FETCH NEXT ? ROWS ONLY "; } - sql += ") AS app_data ON app_data.ID = AP_APP.ID WHERE AP_APP.TENANT_ID = ? ORDER BY AP_APP.ID"; + sql += ") AS app_data ON app_data.ID = AP_APP.ID " + + "INNER JOIN (" + + "SELECT AP_APP_LIFECYCLE_STATE.UPDATED_AT, AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID " + + "FROM AP_APP_LIFECYCLE_STATE WHERE AP_APP_LIFECYCLE_STATE.ID " + + "IN(SELECT MAX(AP_APP_LIFECYCLE_STATE.ID) " + + "FROM AP_APP_LIFECYCLE_STATE " + + "GROUP BY AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID)) AS NEW_AP_APP_LIFECYCLE_STATE " + + "ON AP_APP_RELEASE.ID = NEW_AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID " + + "WHERE AP_APP.TENANT_ID = ? " + + "ORDER BY AP_APP.ID, LATEST_UPDATE DESC"; + try { Connection conn = this.getDBConnection(); try (PreparedStatement stmt = conn.prepareStatement(sql)) { diff --git a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/SQLServerApplicationDAOImpl.java b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/SQLServerApplicationDAOImpl.java index ee7c78f8ba..d27e55aa9b 100644 --- a/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/SQLServerApplicationDAOImpl.java +++ b/components/application-mgt/org.wso2.carbon.device.application.mgt.core/src/main/java/org/wso2/carbon/device/application/mgt/core/dao/impl/application/SQLServerApplicationDAOImpl.java @@ -79,7 +79,8 @@ public class SQLServerApplicationDAOImpl extends GenericApplicationDAOImpl { + "AP_APP_RELEASE.SUPPORTED_OS_VERSIONS AS RELEASE_SUP_OS_VERSIONS, " + "AP_APP_RELEASE.RATING AS RELEASE_RATING, " + "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, " - + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT " + + "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT, " + + "NEW_AP_APP_LIFECYCLE_STATE.UPDATED_AT AS LATEST_UPDATE " + "FROM AP_APP " + "INNER JOIN AP_APP_RELEASE ON " + "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID " @@ -124,7 +125,17 @@ public class SQLServerApplicationDAOImpl extends GenericApplicationDAOImpl { if (filter.getLimit() != -1) { sql += "ORDER BY ID OFFSET ? ROWS FETCH NEXT ? ROWS ONLY "; } - sql += ") AS app_data ON app_data.ID = AP_APP.ID WHERE AP_APP.TENANT_ID = ? ORDER BY AP_APP.ID"; + sql += ") AS app_data ON app_data.ID = AP_APP.ID " + + "INNER JOIN (" + + "SELECT AP_APP_LIFECYCLE_STATE.UPDATED_AT, AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID " + + "FROM AP_APP_LIFECYCLE_STATE WHERE AP_APP_LIFECYCLE_STATE.ID " + + "IN(SELECT MAX(AP_APP_LIFECYCLE_STATE.ID) " + + "FROM AP_APP_LIFECYCLE_STATE " + + "GROUP BY AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID)) AS NEW_AP_APP_LIFECYCLE_STATE " + + "ON AP_APP_RELEASE.ID = NEW_AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID " + + "WHERE AP_APP.TENANT_ID = ? " + + "ORDER BY AP_APP.ID, LATEST_UPDATE DESC"; + try { Connection conn = this.getDBConnection(); try (PreparedStatement stmt = conn.prepareStatement(sql)) { From f64007bcc894042c8e764ca3047c614f4ceff249 Mon Sep 17 00:00:00 2001 From: Pahansith Date: Mon, 3 May 2021 23:11:21 +0530 Subject: [PATCH 2/7] Add session scope handler (cherry picked from commit 429e76cfdc8184e99df84f1678eb17d0780b22ad) --- .../interceptor/PermissionScopeHandler.java | 65 +++++++++++++++++++ .../interceptor/util/HandlerConstants.java | 2 +- 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/PermissionScopeHandler.java diff --git a/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/PermissionScopeHandler.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/PermissionScopeHandler.java new file mode 100644 index 0000000000..96d1d1151f --- /dev/null +++ b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/PermissionScopeHandler.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package io.entgra.ui.request.interceptor; + +import io.entgra.ui.request.interceptor.beans.AuthData; +import io.entgra.ui.request.interceptor.beans.ProxyResponse; +import io.entgra.ui.request.interceptor.util.HandlerConstants; +import io.entgra.ui.request.interceptor.util.HandlerUtil; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpStatus; +import org.json.JSONObject; + +import javax.servlet.ServletException; +import javax.servlet.annotation.MultipartConfig; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.IOException; + +@MultipartConfig +@WebServlet("/login-user/scopes") +public class PermissionScopeHandler extends HttpServlet { + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + HttpSession httpSession = req.getSession(false); + if (httpSession == null) { + HandlerUtil.sendUnAuthorizeResponse(resp); + return; + } + + AuthData authData = (AuthData) httpSession.getAttribute(HandlerConstants.SESSION_AUTH_DATA_KEY); + if (authData == null) { + HandlerUtil.sendUnAuthorizeResponse(resp); + return; + } + + if (!StringUtils.isEmpty(authData.getScope())) { + ProxyResponse proxyResponse = new ProxyResponse(); + JSONObject jsonObject = new JSONObject(); + jsonObject.put(HandlerConstants.USER_SCOPES, authData.getScope()); + proxyResponse.setCode(HttpStatus.SC_OK); + proxyResponse.setData(jsonObject.toString()); + HandlerUtil.handleSuccess(resp, proxyResponse); + } + HandlerUtil.handleError(resp, null); + } +} 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 6760fcf236..b94309be57 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 @@ -80,5 +80,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"; } From 19268aaa5b551a739ff156165a53ebf9c901e0c1 Mon Sep 17 00:00:00 2001 From: vigneshan Date: Thu, 6 May 2021 22:42:37 +0530 Subject: [PATCH 3/7] Fix session expire issue during sso authorization (cherry picked from commit c2369cde71ec6c8ef96539d636d2804fd815eb2e) --- .../interceptor/SsoLoginCallbackHandler.java | 19 +++++++++++++------ .../request/interceptor/SsoLoginHandler.java | 2 +- 2 files changed, 14 insertions(+), 7 deletions(-) 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 92bd0e6b70..c437398d20 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(gatewayUrl + 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 1a5a550571..e23019d2c8 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 @@ -88,12 +88,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); + httpSession.setMaxInactiveInterval(Math.toIntExact(HandlerConstants.TIMEOUT)); initializeAdminCredentials(); baseContextPath = req.getContextPath(); applicationName = baseContextPath.substring(1, baseContextPath.indexOf("-ui-request-handler")); From 233f09a6767876a9f2a27bac13afc8e097c567ee Mon Sep 17 00:00:00 2001 From: Kaveesha Date: Wed, 12 May 2021 15:00:56 +0530 Subject: [PATCH 4/7] Update item bean class to get documentation link from xml (cherry picked from commit 6c947962d6a19a420908064f5cb66d60638398c7) --- .../carbon/device/mgt/common/policy/mgt/ui/Item.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/policy/mgt/ui/Item.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/policy/mgt/ui/Item.java index faf97d7e11..43927eb876 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/policy/mgt/ui/Item.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/policy/mgt/ui/Item.java @@ -27,6 +27,7 @@ public class Item { private String label; private String tooltip; + private String docLink; private String key; private String value; private boolean isRequired; @@ -65,6 +66,16 @@ public class Item { this.tooltip = tooltip; } + @XmlElement(name = "DocLink") + public String getDocLink() { + return docLink; + } + + public void setDocLink(String docLink) { + this.docLink = docLink; + } + + @XmlElement(name = "Key", required = true) public String getKey() { return key; From 554e20e389ef294394e98f0efa245679fc68b6fd Mon Sep 17 00:00:00 2001 From: inoshperera Date: Mon, 17 May 2021 12:04:21 +0530 Subject: [PATCH 5/7] Support AE with QR code based enrollment Fixes https://gitlab.com/entgra/emm-proprietary-plugins/-/merge_requests/601 (cherry picked from commit 2f73bcb0c7a635d3b7c077dcb73faddb3b4f10a6) --- .../src/main/resources/conf/mdm-ui-config.xml | 1 + 1 file changed, 1 insertion(+) 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..3a425274f1 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 @@ -177,6 +177,7 @@ perm:metadata:view perm:metadata:create perm:metadata:update + perm:android:google-account device-mgt From 9419eef7f9929e3e11dbc447548e19030bdc319a Mon Sep 17 00:00:00 2001 From: charithag Date: Wed, 19 May 2021 17:12:50 +0530 Subject: [PATCH 6/7] Add geo view API (cherry picked from commit e5fb17aceb98ccc8b5b843db65484a61fd33e414) --- .../device/mgt/jaxrs/beans/GeoCluster.java | 84 ++++++++ .../service/api/GeoLocationBasedService.java | 124 +++++++++++- .../impl/GeoLocationBasedServiceImpl.java | 86 +++++++- .../impl/GeoLocationBasedServiceImplTest.java | 16 +- .../mgt/common/geo/service/GeoCluster.java | 66 ++++++ .../mgt/common/geo/service/GeoCoordinate.java | 39 ++++ .../mgt/common/geo/service/GeoQuery.java | 139 +++++++++++++ .../carbon/device/mgt/core/dao/DeviceDAO.java | 14 +- .../core/dao/impl/AbstractDeviceDAOImpl.java | 189 ++++++++++++++---- .../impl/device/SQLServerDeviceDAOImpl.java | 8 +- .../device/mgt/core/geo/GeoCluster.java | 65 ------ .../mgt/core/geo/geoHash/GeoCoordinate.java | 21 -- .../core/geo/geoHash/GeoHashGenerator.java | 32 ++- .../GeoHashLengthStrategy.java | 22 +- .../ZoomGeoHashLengthStrategy.java | 59 ++++-- .../GeoLocationProviderServiceImpl.java | 151 +++++++------- .../core/geo/task/EventCreateCallback.java | 1 + .../geo/task/EventOperationTaskException.java | 3 +- .../task/GeoFenceEventOperationManager.java | 8 +- .../DeviceManagementProviderService.java | 8 +- .../DeviceManagementProviderServiceImpl.java | 16 +- 21 files changed, 874 insertions(+), 277 deletions(-) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/GeoCluster.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/GeoCluster.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/GeoCoordinate.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/geo/service/GeoQuery.java delete mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/GeoCluster.java delete mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/geo/geoHash/GeoCoordinate.java 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 5e55acdc77..a2a6979803 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( @@ -208,6 +207,7 @@ public interface GeoLocationBasedService { message = "Internal Server Error. \n Error on retrieving stats", response = Response.class) }) + @Deprecated Response getGeoDeviceLocations( @ApiParam( name = "deviceType", @@ -244,6 +244,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 b2c28d8f1e..793b83c46c 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 @@ -38,6 +38,7 @@ 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; @@ -47,13 +48,14 @@ 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; @@ -81,7 +83,10 @@ 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; @@ -91,7 +96,7 @@ import java.util.Map; */ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService { - private static Log log = LogFactory.getLog(GeoLocationBasedServiceImpl.class); + private static final Log log = LogFactory.getLog(GeoLocationBasedServiceImpl.class); @Path("stats/{deviceType}/{deviceId}") @GET @@ -155,6 +160,7 @@ public class GeoLocationBasedServiceImpl implements GeoLocationBasedService { @GET @Consumes("application/json") @Produces("application/json") + @Deprecated public Response getGeoDeviceLocations( @QueryParam("deviceType") String deviceType, @QueryParam("minLat") double minLat, @@ -162,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); @@ -169,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}") 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/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/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 4959c282c4..1f4bac57d1 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 @@ -92,6 +92,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; @@ -128,8 +129,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; @@ -3371,18 +3372,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); From 12ebc03d125ad1b13474cef0a09be443c2f4ee08 Mon Sep 17 00:00:00 2001 From: MalshaPiumini Date: Mon, 24 May 2021 22:36:09 +0530 Subject: [PATCH 7/7] Increase session time for sso and non-sso login. (cherry picked from commit a1567d8a3ded0ab3a0076add05a1b6064808fba3) --- .../device/mgt/core/config/ui/UIConfiguration.java | 10 ++++++++++ .../io/entgra/ui/request/interceptor/LoginHandler.java | 8 +++++--- .../entgra/ui/request/interceptor/SsoLoginHandler.java | 5 ++++- .../src/main/resources/conf/mdm-ui-config.xml | 2 ++ 4 files changed, 21 insertions(+), 4 deletions(-) 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/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 e4246fbfc0..60dd31ab2d 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; @@ -69,13 +70,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/SsoLoginHandler.java b/components/ui-request-interceptor/io.entgra.ui.request.interceptor/src/main/java/io/entgra/ui/request/interceptor/SsoLoginHandler.java index e23019d2c8..fb4f93b0c9 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; @@ -93,7 +94,7 @@ public class SsoLoginHandler extends HttpServlet { } httpSession = req.getSession(true); - httpSession.setMaxInactiveInterval(Math.toIntExact(HandlerConstants.TIMEOUT)); + 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/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 3a425274f1..eba51b1d84 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