From 57e05b4ca9b656a2f8bfd48ec37c846b39326cc0 Mon Sep 17 00:00:00 2001 From: Charitha Goonetilleke Date: Fri, 9 Aug 2024 09:14:33 +0530 Subject: [PATCH 1/4] Add supported operations param to subtype --- .../core/subtype/mgt/dao/util/DAOUtil.java | 2 +- .../core/subtype/mgt/dto/DeviceSubType.java | 29 +++++++++++-------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/components/subtype-mgt/io.entgra.device.mgt.core.subtype.mgt/src/main/java/io/entgra/device/mgt/core/subtype/mgt/dao/util/DAOUtil.java b/components/subtype-mgt/io.entgra.device.mgt.core.subtype.mgt/src/main/java/io/entgra/device/mgt/core/subtype/mgt/dao/util/DAOUtil.java index f4569c6c36..3a1aa6fa67 100644 --- a/components/subtype-mgt/io.entgra.device.mgt.core.subtype.mgt/src/main/java/io/entgra/device/mgt/core/subtype/mgt/dao/util/DAOUtil.java +++ b/components/subtype-mgt/io.entgra.device.mgt.core.subtype.mgt/src/main/java/io/entgra/device/mgt/core/subtype/mgt/dao/util/DAOUtil.java @@ -72,7 +72,7 @@ public class DAOUtil { deviceSubType = loadDeviceSubType(rs); } if (operationCode != null) { - deviceSubType.addOperationCode(operationCode); + deviceSubType.addSupportedOperation(operationCode); } deviceSubTypes.put(key, deviceSubType); } diff --git a/components/subtype-mgt/io.entgra.device.mgt.core.subtype.mgt/src/main/java/io/entgra/device/mgt/core/subtype/mgt/dto/DeviceSubType.java b/components/subtype-mgt/io.entgra.device.mgt.core.subtype.mgt/src/main/java/io/entgra/device/mgt/core/subtype/mgt/dto/DeviceSubType.java index cc27bb592e..e52ed3dbd0 100644 --- a/components/subtype-mgt/io.entgra.device.mgt.core.subtype.mgt/src/main/java/io/entgra/device/mgt/core/subtype/mgt/dto/DeviceSubType.java +++ b/components/subtype-mgt/io.entgra.device.mgt.core.subtype.mgt/src/main/java/io/entgra/device/mgt/core/subtype/mgt/dto/DeviceSubType.java @@ -24,7 +24,6 @@ import com.fasterxml.jackson.core.JsonProcessingException; import java.util.HashSet; import java.util.Set; - public abstract class DeviceSubType { private String subTypeId; @@ -32,22 +31,22 @@ public abstract class DeviceSubType { private String deviceType; private String subTypeName; private String typeDefinition; - private Set operationCodes = new HashSet<>(); + private final Set supportedOperations = new HashSet<>(); + public DeviceSubType() { } - public DeviceSubType(String subTypeId, int tenantId, String deviceType, String subTypeName, String typeDefinition, - Set operationCodes) { + public DeviceSubType(String subTypeId, int tenantId, String deviceType, + String subTypeName, String typeDefinition, + Set supportedOperations) { this.subTypeId = subTypeId; this.tenantId = tenantId; this.deviceType = deviceType; this.subTypeName = subTypeName; this.typeDefinition = typeDefinition; - if (operationCodes != null || !operationCodes.isEmpty()) { - this.operationCodes.addAll(operationCodes); + if (supportedOperations != null && !supportedOperations.isEmpty()) { + this.supportedOperations.addAll(supportedOperations); } - - } public String getSubTypeId() { @@ -94,10 +93,16 @@ public abstract class DeviceSubType { public abstract String parseSubTypeToJson() throws JsonProcessingException; - public void addOperationCode(String code) { - operationCodes.add(code); + public void setSupportedOperations(Set supportedOperations) { + this.supportedOperations.addAll(supportedOperations); } - public Set getOperationCodes() { - return operationCodes; + + public void addSupportedOperation(String code) { + supportedOperations.add(code); } + + public Set getSupportedOperations() { + return supportedOperations; + } + } From 7f8f6d6f75598a99ab99c7f4a01ae75cbc1b771a Mon Sep 17 00:00:00 2001 From: Pahansith Date: Fri, 9 Aug 2024 09:32:15 +0530 Subject: [PATCH 2/4] Add FCM request improvements --- .../pom.xml | 4 ++ .../provider/fcm/FCMNotificationStrategy.java | 42 +++++++++---------- .../provider/fcm/util/FCMUtil.java | 22 ++++++++++ 3 files changed, 45 insertions(+), 23 deletions(-) diff --git a/components/device-mgt-extensions/io.entgra.device.mgt.core.device.mgt.extensions.push.notification.provider.fcm/pom.xml b/components/device-mgt-extensions/io.entgra.device.mgt.core.device.mgt.extensions.push.notification.provider.fcm/pom.xml index 8453f05e9f..a36ec650b6 100644 --- a/components/device-mgt-extensions/io.entgra.device.mgt.core.device.mgt.extensions.push.notification.provider.fcm/pom.xml +++ b/components/device-mgt-extensions/io.entgra.device.mgt.core.device.mgt.extensions.push.notification.provider.fcm/pom.xml @@ -151,6 +151,10 @@ org.wso2.carbon org.wso2.carbon.utils + + com.squareup.okhttp3 + okhttp + diff --git a/components/device-mgt-extensions/io.entgra.device.mgt.core.device.mgt.extensions.push.notification.provider.fcm/src/main/java/io/entgra/device/mgt/core/device/mgt/extensions/push/notification/provider/fcm/FCMNotificationStrategy.java b/components/device-mgt-extensions/io.entgra.device.mgt.core.device.mgt.extensions.push.notification.provider.fcm/src/main/java/io/entgra/device/mgt/core/device/mgt/extensions/push/notification/provider/fcm/FCMNotificationStrategy.java index 39bd1ba7e5..66ee2ebb00 100644 --- a/components/device-mgt-extensions/io.entgra.device.mgt.core.device.mgt.extensions.push.notification.provider.fcm/src/main/java/io/entgra/device/mgt/core/device/mgt/extensions/push/notification/provider/fcm/FCMNotificationStrategy.java +++ b/components/device-mgt-extensions/io.entgra.device.mgt.core.device.mgt.extensions.push.notification.provider.fcm/src/main/java/io/entgra/device/mgt/core/device/mgt/extensions/push/notification/provider/fcm/FCMNotificationStrategy.java @@ -19,6 +19,9 @@ package io.entgra.device.mgt.core.device.mgt.extensions.push.notification.provid import com.google.gson.JsonObject; import io.entgra.device.mgt.core.device.mgt.extensions.push.notification.provider.fcm.util.FCMUtil; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import io.entgra.device.mgt.core.device.mgt.common.Device; @@ -89,8 +92,6 @@ public class FCMNotificationStrategy implements NotificationStrategy { */ private void sendWakeUpCall(String accessToken, String registrationId) throws IOException, PushNotificationExecutionFailedException { - HttpURLConnection conn = null; - String fcmServerEndpoint = FCMUtil.getInstance().getContextMetadataProperties() .getProperty(FCM_ENDPOINT_KEY); if(fcmServerEndpoint == null) { @@ -99,26 +100,21 @@ public class FCMNotificationStrategy implements NotificationStrategy { throw new PushNotificationExecutionFailedException(msg); } - try { - byte[] bytes = getFCMRequest(registrationId).getBytes(); - URL url = new URL(fcmServerEndpoint); - conn = (HttpURLConnection) url.openConnection(); - conn.setRequestProperty("Content-Type", "application/json"); - conn.setRequestProperty("Authorization", "Bearer " + accessToken); - conn.setRequestMethod("POST"); - conn.setDoOutput(true); - - try (OutputStream os = conn.getOutputStream()) { - os.write(bytes); - } - - int status = conn.getResponseCode(); - if (status != 200) { - log.error("Response Status: " + status + ", Response Message: " + conn.getResponseMessage()); + RequestBody fcmRequest = getFCMRequest(registrationId); + Request request = new Request.Builder() + .url(fcmServerEndpoint) + .post(fcmRequest) + .addHeader("Authorization", "Bearer " + accessToken) + .build(); + try (Response response = FCMUtil.getInstance().getHttpClient().newCall(request).execute()) { + if (log.isDebugEnabled()) { + log.debug("FCM message sent to the FCM server. Response code: " + response.code() + + " Response message : " + response.message()); } - } finally { - if (conn != null) { - conn.disconnect(); + if(!response.isSuccessful()) { + String msg = "Response Status: " + response.code() + ", Response Message: " + response.message(); + log.error(msg); + throw new IOException(msg); } } } @@ -128,14 +124,14 @@ public class FCMNotificationStrategy implements NotificationStrategy { * @param registrationId Registration ID of the device * @return FCM request as a JSON string */ - private static String getFCMRequest(String registrationId) { + private static RequestBody getFCMRequest(String registrationId) { JsonObject messageObject = new JsonObject(); messageObject.addProperty("token", registrationId); JsonObject fcmRequest = new JsonObject(); fcmRequest.add("message", messageObject); - return fcmRequest.toString(); + return RequestBody.create(fcmRequest.toString(), okhttp3.MediaType.parse("application/json")); } @Override diff --git a/components/device-mgt-extensions/io.entgra.device.mgt.core.device.mgt.extensions.push.notification.provider.fcm/src/main/java/io/entgra/device/mgt/core/device/mgt/extensions/push/notification/provider/fcm/util/FCMUtil.java b/components/device-mgt-extensions/io.entgra.device.mgt.core.device.mgt.extensions.push.notification.provider.fcm/src/main/java/io/entgra/device/mgt/core/device/mgt/extensions/push/notification/provider/fcm/util/FCMUtil.java index 0c6c433cc7..e3d15d8974 100644 --- a/components/device-mgt-extensions/io.entgra.device.mgt.core.device.mgt.extensions.push.notification.provider.fcm/src/main/java/io/entgra/device/mgt/core/device/mgt/extensions/push/notification/provider/fcm/util/FCMUtil.java +++ b/components/device-mgt-extensions/io.entgra.device.mgt.core.device.mgt.extensions.push.notification.provider.fcm/src/main/java/io/entgra/device/mgt/core/device/mgt/extensions/push/notification/provider/fcm/util/FCMUtil.java @@ -22,6 +22,8 @@ import io.entgra.device.mgt.core.device.mgt.core.config.DeviceConfigurationManag import io.entgra.device.mgt.core.device.mgt.core.config.push.notification.ContextMetadata; import io.entgra.device.mgt.core.device.mgt.core.config.push.notification.PushNotificationConfiguration; import io.entgra.device.mgt.core.device.mgt.extensions.push.notification.provider.fcm.FCMNotificationStrategy; +import okhttp3.ConnectionPool; +import okhttp3.OkHttpClient; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.utils.CarbonUtils; @@ -33,6 +35,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; import java.util.Properties; +import java.util.concurrent.TimeUnit; public class FCMUtil { @@ -43,10 +46,29 @@ public class FCMUtil { "repository" + File.separator + "resources" + File.separator + "service-account.json"; private static final String[] FCM_SCOPES = { "https://www.googleapis.com/auth/firebase.messaging" }; private Properties contextMetadataProperties; + private static ConnectionPool connectionPool; + private static OkHttpClient client; private FCMUtil() { initContextConfigs(); initDefaultOAuthApplication(); + initPooledConnection(); + } + + /** + * Initialize the connection pool for the OkHttpClient instance. + */ + private void initPooledConnection() { + connectionPool = new ConnectionPool(25, 1, TimeUnit.MINUTES); + client = new OkHttpClient.Builder().connectionPool(connectionPool).build(); + } + + /** + * Get the Pooled OkHttpClient instance + * @return OkHttpClient instance + */ + public OkHttpClient getHttpClient() { + return client; } private void initDefaultOAuthApplication() { From a4138b47789b02fa5f03ebb95aa91f46e2fe1df9 Mon Sep 17 00:00:00 2001 From: Charitha Goonetilleke Date: Mon, 12 Aug 2024 16:31:13 +0530 Subject: [PATCH 3/4] Fix inconsistencies with subtypes and operation templates --- .../impl/OperationTemplateServiceImpl.java | 20 +++++++++---------- .../template/ServiceNegativeTest.java | 2 +- ...der.java => DeviceSubTypeCacheLoader.java} | 6 +++--- .../mgt/dao/impl/DeviceSubTypeDAOImpl.java | 13 ++++++------ .../mgt/impl/DeviceSubTypeServiceImpl.java | 12 ++++++++--- 5 files changed, 30 insertions(+), 23 deletions(-) rename components/subtype-mgt/io.entgra.device.mgt.core.subtype.mgt/src/main/java/io/entgra/device/mgt/core/subtype/mgt/cache/{GetDeviceSubTypeCacheLoader.java => DeviceSubTypeCacheLoader.java} (93%) diff --git a/components/operation-template-mgt/io.entgra.device.mgt.core.operation.template/src/main/java/io/entgra/device/mgt/core/operation/template/impl/OperationTemplateServiceImpl.java b/components/operation-template-mgt/io.entgra.device.mgt.core.operation.template/src/main/java/io/entgra/device/mgt/core/operation/template/impl/OperationTemplateServiceImpl.java index 5bc0d1c238..5fdefcfd84 100644 --- a/components/operation-template-mgt/io.entgra.device.mgt.core.operation.template/src/main/java/io/entgra/device/mgt/core/operation/template/impl/OperationTemplateServiceImpl.java +++ b/components/operation-template-mgt/io.entgra.device.mgt.core.operation.template/src/main/java/io/entgra/device/mgt/core/operation/template/impl/OperationTemplateServiceImpl.java @@ -216,8 +216,8 @@ public class OperationTemplateServiceImpl implements OperationTemplateService { throws OperationTemplateMgtPluginException { AssertUtils.hasText(deviceType, "Invalid device type."); try { - ConnectionManagerUtils.openDBConnection(); - return operationTemplateDAO.getAllOperationTemplates(deviceType); + ConnectionManagerUtils.openDBConnection(); + return operationTemplateDAO.getAllOperationTemplates(deviceType); } catch (DBConnectionException | OperationTemplateManagementDAOException e) { log.error(e.getMessage()); throw new OperationTemplateMgtPluginException(e.getMessage(), e); @@ -273,11 +273,12 @@ public class OperationTemplateServiceImpl implements OperationTemplateService { */ @Override public Set getOperationTemplateCodes(String deviceType, String subTypeId) - throws OperationTemplateMgtPluginException { + throws OperationTemplateMgtPluginException { try { - AssertUtils.hasText(subTypeId, "Invalid meter device subtype id: " + subTypeId); - AssertUtils.isTrue(Integer.valueOf(subTypeId)>0, "Invalid meter device subtype id: " + subTypeId); + AssertUtils.hasText(subTypeId, "Invalid device subtype id: " + subTypeId); + AssertUtils.isTrue(Integer.parseInt(subTypeId) > 0, + "Invalid device subtype id: " + subTypeId); AssertUtils.hasText(deviceType, "Invalid device type."); String key = OperationTemplateManagementUtil.setOperationTemplateCacheKey(deviceType, subTypeId); @@ -294,7 +295,6 @@ public class OperationTemplateServiceImpl implements OperationTemplateService { } /** - * * @param subTypeId * @param deviceType * @param operationCode @@ -303,18 +303,18 @@ public class OperationTemplateServiceImpl implements OperationTemplateService { private void validateGetOperationTemplate(String subTypeId, String deviceType, String operationCode) throws OperationTemplateMgtPluginException { - AssertUtils.hasText(subTypeId, "Invalid meter device subtype id: " + subTypeId); - AssertUtils.isTrue(Integer.valueOf(subTypeId)>0, "Invalid meter device subtype id: " + subTypeId); + AssertUtils.hasText(subTypeId, "Invalid device subtype id: " + subTypeId); + AssertUtils.isTrue(Integer.parseInt(subTypeId) > 0, "Invalid device subtype id: " + subTypeId); AssertUtils.hasText(operationCode, "Validation failed due to invalid operation code: " + operationCode); AssertUtils.hasText(deviceType, "Invalid device type."); - AssertUtils.isTrue(deviceType.equals("METER"), "Invalid device type. "); } /** * @param operationTemplate * @throws OperationTemplateMgtPluginException */ - private void validateAddOperationTemplate(OperationTemplate operationTemplate) throws OperationTemplateMgtPluginException { + private void validateAddOperationTemplate(OperationTemplate operationTemplate) + throws OperationTemplateMgtPluginException { AssertUtils.isNull(operationTemplate, "Operation Template can not be null"); AssertUtils.hasText(operationTemplate.getOperationDefinition(), "Operation definition can not be null"); diff --git a/components/operation-template-mgt/io.entgra.device.mgt.core.operation.template/src/test/java/io/entgra/device/mgt/core/operation/template/ServiceNegativeTest.java b/components/operation-template-mgt/io.entgra.device.mgt.core.operation.template/src/test/java/io/entgra/device/mgt/core/operation/template/ServiceNegativeTest.java index 2c41d1ffc3..dbb7ecdbad 100644 --- a/components/operation-template-mgt/io.entgra.device.mgt.core.operation.template/src/test/java/io/entgra/device/mgt/core/operation/template/ServiceNegativeTest.java +++ b/components/operation-template-mgt/io.entgra.device.mgt.core.operation.template/src/test/java/io/entgra/device/mgt/core/operation/template/ServiceNegativeTest.java @@ -49,7 +49,7 @@ public class ServiceNegativeTest extends BaseOperationTemplatePluginTest { @Test(description = "This method tests Add Operation template under negative circumstances while missing " + "required fields", expectedExceptions = {OperationTemplateMgtPluginException.class}, - expectedExceptionsMessageRegExp = "Invalid meter device subtype id: 0") + expectedExceptionsMessageRegExp = "Invalid device subtype id: 0") public void testAddOperationTemplates() throws OperationTemplateMgtPluginException { OperationTemplate operationTemplate = new OperationTemplate(); diff --git a/components/subtype-mgt/io.entgra.device.mgt.core.subtype.mgt/src/main/java/io/entgra/device/mgt/core/subtype/mgt/cache/GetDeviceSubTypeCacheLoader.java b/components/subtype-mgt/io.entgra.device.mgt.core.subtype.mgt/src/main/java/io/entgra/device/mgt/core/subtype/mgt/cache/DeviceSubTypeCacheLoader.java similarity index 93% rename from components/subtype-mgt/io.entgra.device.mgt.core.subtype.mgt/src/main/java/io/entgra/device/mgt/core/subtype/mgt/cache/GetDeviceSubTypeCacheLoader.java rename to components/subtype-mgt/io.entgra.device.mgt.core.subtype.mgt/src/main/java/io/entgra/device/mgt/core/subtype/mgt/cache/DeviceSubTypeCacheLoader.java index 7bf985e5b9..1ac3cd593f 100644 --- a/components/subtype-mgt/io.entgra.device.mgt.core.subtype.mgt/src/main/java/io/entgra/device/mgt/core/subtype/mgt/cache/GetDeviceSubTypeCacheLoader.java +++ b/components/subtype-mgt/io.entgra.device.mgt.core.subtype.mgt/src/main/java/io/entgra/device/mgt/core/subtype/mgt/cache/DeviceSubTypeCacheLoader.java @@ -31,13 +31,13 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -public class GetDeviceSubTypeCacheLoader extends CacheLoader { +public class DeviceSubTypeCacheLoader extends CacheLoader { - private static final Log log = LogFactory.getLog(GetDeviceSubTypeCacheLoader.class); + private static final Log log = LogFactory.getLog(DeviceSubTypeCacheLoader.class); private final DeviceSubTypeDAO deviceSubTypeDAO; - public GetDeviceSubTypeCacheLoader() { + public DeviceSubTypeCacheLoader() { this.deviceSubTypeDAO = DeviceSubTypeDAOFactory.getDeviceSubTypeDAO(); } diff --git a/components/subtype-mgt/io.entgra.device.mgt.core.subtype.mgt/src/main/java/io/entgra/device/mgt/core/subtype/mgt/dao/impl/DeviceSubTypeDAOImpl.java b/components/subtype-mgt/io.entgra.device.mgt.core.subtype.mgt/src/main/java/io/entgra/device/mgt/core/subtype/mgt/dao/impl/DeviceSubTypeDAOImpl.java index 6cc2c7cac7..f3aafa5d28 100644 --- a/components/subtype-mgt/io.entgra.device.mgt.core.subtype.mgt/src/main/java/io/entgra/device/mgt/core/subtype/mgt/dao/impl/DeviceSubTypeDAOImpl.java +++ b/components/subtype-mgt/io.entgra.device.mgt.core.subtype.mgt/src/main/java/io/entgra/device/mgt/core/subtype/mgt/dao/impl/DeviceSubTypeDAOImpl.java @@ -101,8 +101,9 @@ public class DeviceSubTypeDAOImpl implements DeviceSubTypeDAO { public DeviceSubType getDeviceSubType(String subTypeId, int tenantId, String deviceType) throws SubTypeMgtDAOException { try { - String sql = "SELECT s.*, o.OPERATION_CODE FROM DM_DEVICE_SUB_TYPE s " + - "LEFT JOIN SUB_OPERATION_TEMPLATE o on s.SUB_TYPE_ID = o.SUB_TYPE_ID " + + String sql = "SELECT s.*, o.OPERATION_CODE FROM DM_DEVICE_SUB_TYPE s " + + "LEFT JOIN SUB_OPERATION_TEMPLATE o ON s.SUB_TYPE_ID = o.SUB_TYPE_ID " + + "AND s.DEVICE_TYPE = o.DEVICE_TYPE " + "WHERE s.SUB_TYPE_ID = ? AND s.TENANT_ID = ? AND s.DEVICE_TYPE = ?"; Connection conn = ConnectionManagerUtil.getDBConnection(); @@ -143,8 +144,7 @@ public class DeviceSubTypeDAOImpl implements DeviceSubTypeDAO { stmt.setInt(1, tenantId); stmt.setString(2, deviceType); try (ResultSet rs = stmt.executeQuery()) { - List deviceSubTypes = DAOUtil.loadDeviceSubTypes(rs); - return deviceSubTypes; + return DAOUtil.loadDeviceSubTypes(rs); } } } catch (DBConnectionException e) { @@ -163,14 +163,14 @@ public class DeviceSubTypeDAOImpl implements DeviceSubTypeDAO { @Override public int getDeviceSubTypeCount(String deviceType) throws SubTypeMgtDAOException { try { - String sql = "SELECT COUNT(*) as DEVICE_COUNT FROM DM_DEVICE_SUB_TYPE WHERE DEVICE_TYPE = ? "; + String sql = "SELECT COUNT(*) as SUB_TYPE_COUNT FROM DM_DEVICE_SUB_TYPE WHERE DEVICE_TYPE = ? "; Connection conn = ConnectionManagerUtil.getDBConnection(); try (PreparedStatement stmt = conn.prepareStatement(sql)) { stmt.setString(1, deviceType); try (ResultSet rs = stmt.executeQuery()) { if (rs.next()) { - return rs.getInt("DEVICE_COUNT"); + return rs.getInt("SUB_TYPE_COUNT"); } return 0; } @@ -252,4 +252,5 @@ public class DeviceSubTypeDAOImpl implements DeviceSubTypeDAO { throw new SubTypeMgtDAOException(msg, e); } } + } diff --git a/components/subtype-mgt/io.entgra.device.mgt.core.subtype.mgt/src/main/java/io/entgra/device/mgt/core/subtype/mgt/impl/DeviceSubTypeServiceImpl.java b/components/subtype-mgt/io.entgra.device.mgt.core.subtype.mgt/src/main/java/io/entgra/device/mgt/core/subtype/mgt/impl/DeviceSubTypeServiceImpl.java index 4e5d855a23..1227f629fe 100644 --- a/components/subtype-mgt/io.entgra.device.mgt.core.subtype.mgt/src/main/java/io/entgra/device/mgt/core/subtype/mgt/impl/DeviceSubTypeServiceImpl.java +++ b/components/subtype-mgt/io.entgra.device.mgt.core.subtype.mgt/src/main/java/io/entgra/device/mgt/core/subtype/mgt/impl/DeviceSubTypeServiceImpl.java @@ -21,7 +21,7 @@ package io.entgra.device.mgt.core.subtype.mgt.impl; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; -import io.entgra.device.mgt.core.subtype.mgt.cache.GetDeviceSubTypeCacheLoader; +import io.entgra.device.mgt.core.subtype.mgt.cache.DeviceSubTypeCacheLoader; import io.entgra.device.mgt.core.subtype.mgt.dto.DeviceSubTypeCacheKey; import io.entgra.device.mgt.core.subtype.mgt.exception.BadRequestException; import io.entgra.device.mgt.core.subtype.mgt.exception.DBConnectionException; @@ -48,7 +48,7 @@ public class DeviceSubTypeServiceImpl implements DeviceSubTypeService { private static final LoadingCache deviceSubTypeCache = CacheBuilder.newBuilder() .expireAfterWrite(15, TimeUnit.MINUTES) - .build(new GetDeviceSubTypeCacheLoader()); + .build(new DeviceSubTypeCacheLoader()); private final DeviceSubTypeDAO deviceSubTypeDAO; public DeviceSubTypeServiceImpl() { @@ -166,7 +166,13 @@ public class DeviceSubTypeServiceImpl implements DeviceSubTypeService { throws SubTypeMgtPluginException { try { ConnectionManagerUtil.openDBConnection(); - return deviceSubTypeDAO.getAllDeviceSubTypes(tenantId, deviceType); + List subtypes = deviceSubTypeDAO.getAllDeviceSubTypes(tenantId, deviceType); + DeviceSubTypeCacheKey key; + for (DeviceSubType dst: subtypes) { + key = DeviceSubTypeMgtUtil.getDeviceSubTypeCacheKey(tenantId, dst.getSubTypeId(), deviceType); + deviceSubTypeCache.put(key, dst); + } + return subtypes; } catch (DBConnectionException e) { String msg = "Error occurred while obtaining the database connection to retrieve all device subtype for " + deviceType + " subtypes"; From e384adc6570c0d7fae7a41e05879dbbe9ff18122 Mon Sep 17 00:00:00 2001 From: Rajitha Kumara Date: Mon, 12 Aug 2024 17:50:45 +0530 Subject: [PATCH 4/4] Fix default scopes not updating issue --- .../publisher/APIPublisherStartupHandler.java | 50 +++++++++++++++++++ .../APIPublisherLifecycleListener.java | 12 +---- .../core/internal/TenantCreateObserver.java | 35 ------------- 3 files changed, 51 insertions(+), 46 deletions(-) diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherStartupHandler.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherStartupHandler.java index e039259b92..d218238dc1 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherStartupHandler.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/APIPublisherStartupHandler.java @@ -18,12 +18,24 @@ package io.entgra.device.mgt.core.apimgt.webapp.publisher; +import com.google.gson.Gson; +import io.entgra.device.mgt.core.apimgt.extension.rest.api.constants.Constants; +import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataKeyAlreadyExistsException; +import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataManagementException; +import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.Metadata; +import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.MetadataManagementService; +import io.entgra.device.mgt.core.device.mgt.core.config.DeviceConfigurationManager; +import io.entgra.device.mgt.core.device.mgt.core.config.DeviceManagementConfig; +import io.entgra.device.mgt.core.device.mgt.core.config.permission.DefaultPermission; +import io.entgra.device.mgt.core.device.mgt.core.config.permission.DefaultPermissions; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import io.entgra.device.mgt.core.apimgt.webapp.publisher.exception.APIManagerPublisherException; import io.entgra.device.mgt.core.apimgt.webapp.publisher.internal.APIPublisherDataHolder; import org.wso2.carbon.core.ServerStartupObserver; +import java.util.HashMap; +import java.util.Map; import java.util.Stack; public class APIPublisherStartupHandler implements ServerStartupObserver { @@ -34,6 +46,7 @@ public class APIPublisherStartupHandler implements ServerStartupObserver { private static final int MAX_RETRY_COUNT = 5; private static Stack failedAPIsStack = new Stack<>(); private static Stack currentAPIsStack; + private static final Gson gson = new Gson(); private APIPublisherService publisher; @@ -91,6 +104,8 @@ public class APIPublisherStartupHandler implements ServerStartupObserver { log.error("failed to update scope role mapping.", e); } + updateScopeMetadataEntryWithDefaultScopes(); + // execute after api publishing for (PostApiPublishingObsever observer : APIPublisherDataHolder.getInstance().getPostApiPublishingObseverList()) { if (log.isDebugEnabled()) { @@ -116,4 +131,39 @@ public class APIPublisherStartupHandler implements ServerStartupObserver { } } + /** + * Update permission scope mapping entry with default scopes if perm-scope-mapping entry exists, otherwise this function + * will create that entry and update the value with default permissions. + */ + private void updateScopeMetadataEntryWithDefaultScopes() { + MetadataManagementService metadataManagementService = APIPublisherDataHolder.getInstance().getMetadataManagementService(); + try { + DeviceManagementConfig deviceManagementConfig = DeviceConfigurationManager.getInstance().getDeviceManagementConfig(); + DefaultPermissions defaultPermissions = deviceManagementConfig.getDefaultPermissions(); + Metadata permScopeMapping = metadataManagementService.retrieveMetadata(Constants.PERM_SCOPE_MAPPING_META_KEY); + Map permScopeMap = (permScopeMapping != null) ? gson.fromJson(permScopeMapping.getMetaValue(), HashMap.class) : + new HashMap<>(); + for (DefaultPermission defaultPermission : defaultPermissions.getDefaultPermissions()) { + permScopeMap.putIfAbsent(defaultPermission.getName(), + defaultPermission.getScopeMapping().getKey()); + } + + APIPublisherDataHolder.getInstance().setPermScopeMapping(permScopeMap); + if (permScopeMapping != null) { + permScopeMapping.setMetaValue(gson.toJson(permScopeMap)); + metadataManagementService.updateMetadata(permScopeMapping); + return; + } + + permScopeMapping = new Metadata(); + permScopeMapping.setMetaKey(Constants.PERM_SCOPE_MAPPING_META_KEY); + permScopeMapping.setMetaValue(gson.toJson(permScopeMap)); + metadataManagementService.createMetadata(permScopeMapping); + } catch (MetadataManagementException e) { + log.error("Error encountered while updating permission scope mapping metadata with default scopes"); + } catch (MetadataKeyAlreadyExistsException e) { + log.error("Metadata entry already exists for " + Constants.PERM_SCOPE_MAPPING_META_KEY); + } + } + } diff --git a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/lifecycle/listener/APIPublisherLifecycleListener.java b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/lifecycle/listener/APIPublisherLifecycleListener.java index bbd2fd952e..737f734d07 100644 --- a/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/lifecycle/listener/APIPublisherLifecycleListener.java +++ b/components/apimgt-extensions/io.entgra.device.mgt.core.apimgt.webapp.publisher/src/main/java/io/entgra/device/mgt/core/apimgt/webapp/publisher/lifecycle/listener/APIPublisherLifecycleListener.java @@ -22,10 +22,6 @@ import io.entgra.device.mgt.core.apimgt.webapp.publisher.dto.ApiScope; import io.entgra.device.mgt.core.device.mgt.common.exceptions.MetadataManagementException; import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.Metadata; import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.MetadataManagementService; -import io.entgra.device.mgt.core.device.mgt.core.config.DeviceConfigurationManager; -import io.entgra.device.mgt.core.device.mgt.core.config.DeviceManagementConfig; -import io.entgra.device.mgt.core.device.mgt.core.config.permission.DefaultPermission; -import io.entgra.device.mgt.core.device.mgt.core.config.permission.DefaultPermissions; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleEvent; import org.apache.catalina.LifecycleListener; @@ -131,19 +127,13 @@ public class APIPublisherLifecycleListener implements LifecycleListener { Metadata existingMetaData = metadataManagementService.retrieveMetadata("perm-scope" + "-mapping"); + if (existingMetaData != null) { existingMetaData.setMetaValue(new Gson().toJson(permScopeMap)); metadataManagementService.updateMetadata(existingMetaData); } else { Metadata newMetaData = new Metadata(); newMetaData.setMetaKey("perm-scope-mapping"); - - DeviceManagementConfig deviceManagementConfig = DeviceConfigurationManager.getInstance().getDeviceManagementConfig(); - DefaultPermissions defaultPermissions = deviceManagementConfig.getDefaultPermissions(); - - for (DefaultPermission defaultPermission : defaultPermissions.getDefaultPermissions()) { - permScopeMap.put(defaultPermission.getName(), defaultPermission.getScopeMapping().getKey()); - } newMetaData.setMetaValue(new Gson().toJson(permScopeMap)); metadataManagementService.createMetadata(newMetaData); } diff --git a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/internal/TenantCreateObserver.java b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/internal/TenantCreateObserver.java index eb5fe919d2..da5acc7562 100644 --- a/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/internal/TenantCreateObserver.java +++ b/components/device-mgt/io.entgra.device.mgt.core.device.mgt.core/src/main/java/io/entgra/device/mgt/core/device/mgt/core/internal/TenantCreateObserver.java @@ -46,7 +46,6 @@ import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.user.api.UserStoreManager; import org.wso2.carbon.utils.AbstractAxis2ConfigurationContextObserver; import org.wso2.carbon.utils.multitenancy.MultitenantConstants; -import org.wso2.carbon.utils.multitenancy.MultitenantUtils; import java.util.ArrayList; import java.util.Arrays; @@ -143,26 +142,6 @@ public class TenantCreateObserver extends AbstractAxis2ConfigurationContextObser */ private void publishScopesToTenant(String tenantDomain) throws TenantManagementException { if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { - - MetadataManagementService metadataManagementService = DeviceManagementDataHolder.getInstance().getMetadataManagementService(); - - Map superTenantPermScopeMapping = getPermScopeMapping(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME); - Map subTenantPermScopeMapping = getPermScopeMapping(tenantDomain); - - if (superTenantPermScopeMapping == null) { - msg = "Error occurred while retrieving meta key '" + Constants.PERM_SCOPE_MAPPING_META_KEY + "' for tenant '" + - MultitenantConstants.SUPER_TENANT_DOMAIN_NAME + "'. Hence aborting publishing scopes to tenant: '" + - tenantDomain + "'."; - log.error(msg); - throw new TenantManagementException(msg); - } - if (superTenantPermScopeMapping.equals(subTenantPermScopeMapping)) { - if (log.isDebugEnabled()) { - log.debug( "Scopes in '" + tenantDomain + "' are up to date with super tenant scopes."); - } - return; - } - APIApplicationServices apiApplicationServices = DeviceManagementDataHolder.getInstance().getApiApplicationServices(); APIApplicationKey apiApplicationKey; AccessTokenInfo accessTokenInfo; @@ -268,10 +247,6 @@ public class TenantCreateObserver extends AbstractAxis2ConfigurationContextObser } } } - - if (missingScopes.size() > 0 || deletedScopes.size() > 0) { - updatePermScopeMetaData(superTenantPermScopeMapping, metadataManagementService); - } } else { if (log.isDebugEnabled()) { log.debug("Starting to publish shared scopes to newly created tenant: '" + tenantDomain + "'."); @@ -279,7 +254,6 @@ public class TenantCreateObserver extends AbstractAxis2ConfigurationContextObser publishSharedScopes(Arrays.asList(superTenantScopes), publisherRESTAPIServices, apiApplicationKey, accessTokenInfo); - updatePermScopeMetaData(superTenantPermScopeMapping, metadataManagementService); } } else { msg = "Unable to publish scopes to sub tenants due to super tenant scopes list being empty."; @@ -298,15 +272,6 @@ public class TenantCreateObserver extends AbstractAxis2ConfigurationContextObser msg = "Error occurred while publishing scopes to '" + tenantDomain + "' tenant space."; log.error(msg, e); throw new TenantManagementException(msg, e); - } catch (MetadataManagementException e) { - msg = "Error occurred trying to create metadata entry '" + Constants.PERM_SCOPE_MAPPING_META_KEY + "'."; - log.error(msg); - throw new TenantManagementException(msg); - } catch (MetadataKeyAlreadyExistsException e) { - msg = "Error occurred trying to create metadata entry '" + Constants.PERM_SCOPE_MAPPING_META_KEY + "'. The meta key " + - "already exists."; - log.error(msg); - throw new TenantManagementException(msg); } finally { APIPublisherUtils.removeScopePublishUserIfExists(tenantDomain); PrivilegedCarbonContext.endTenantFlow();