Sync with master

notification-11094
tcdlpds 4 months ago
commit a4f1f64a70

@ -18,12 +18,24 @@
package io.entgra.device.mgt.core.apimgt.webapp.publisher; 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.apimgt.webapp.publisher.exception.APIManagerPublisherException; import io.entgra.device.mgt.core.apimgt.webapp.publisher.exception.APIManagerPublisherException;
import io.entgra.device.mgt.core.apimgt.webapp.publisher.internal.APIPublisherDataHolder; import io.entgra.device.mgt.core.apimgt.webapp.publisher.internal.APIPublisherDataHolder;
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.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.core.ServerStartupObserver; import org.wso2.carbon.core.ServerStartupObserver;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack; import java.util.Stack;
public class APIPublisherStartupHandler implements ServerStartupObserver { public class APIPublisherStartupHandler implements ServerStartupObserver {
@ -34,6 +46,7 @@ public class APIPublisherStartupHandler implements ServerStartupObserver {
private static final int MAX_RETRY_COUNT = 5; private static final int MAX_RETRY_COUNT = 5;
private static Stack<APIConfig> failedAPIsStack = new Stack<>(); private static Stack<APIConfig> failedAPIsStack = new Stack<>();
private static Stack<APIConfig> currentAPIsStack; private static Stack<APIConfig> currentAPIsStack;
private static final Gson gson = new Gson();
private APIPublisherService publisher; private APIPublisherService publisher;
@ -91,6 +104,8 @@ public class APIPublisherStartupHandler implements ServerStartupObserver {
log.error("failed to update scope role mapping.", e); log.error("failed to update scope role mapping.", e);
} }
updateScopeMetadataEntryWithDefaultScopes();
// execute after api publishing // execute after api publishing
for (PostApiPublishingObsever observer : APIPublisherDataHolder.getInstance().getPostApiPublishingObseverList()) { for (PostApiPublishingObsever observer : APIPublisherDataHolder.getInstance().getPostApiPublishingObseverList()) {
if (log.isDebugEnabled()) { 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<String, String> 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);
}
}
} }

@ -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.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.Metadata;
import io.entgra.device.mgt.core.device.mgt.common.metadata.mgt.MetadataManagementService; 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.Lifecycle;
import org.apache.catalina.LifecycleEvent; import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleListener; import org.apache.catalina.LifecycleListener;
@ -137,19 +133,13 @@ public class APIPublisherLifecycleListener implements LifecycleListener {
Metadata existingMetaData = metadataManagementService.retrieveMetadata("perm-scope" + Metadata existingMetaData = metadataManagementService.retrieveMetadata("perm-scope" +
"-mapping"); "-mapping");
if (existingMetaData != null) { if (existingMetaData != null) {
existingMetaData.setMetaValue(new Gson().toJson(permScopeMap)); existingMetaData.setMetaValue(new Gson().toJson(permScopeMap));
metadataManagementService.updateMetadata(existingMetaData); metadataManagementService.updateMetadata(existingMetaData);
} else { } else {
Metadata newMetaData = new Metadata(); Metadata newMetaData = new Metadata();
newMetaData.setMetaKey("perm-scope-mapping"); 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)); newMetaData.setMetaValue(new Gson().toJson(permScopeMap));
metadataManagementService.createMetadata(newMetaData); metadataManagementService.createMetadata(newMetaData);
} }

@ -148,6 +148,10 @@
<groupId>org.wso2.carbon</groupId> <groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.utils</artifactId> <artifactId>org.wso2.carbon.utils</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>

@ -26,13 +26,13 @@ import io.entgra.device.mgt.core.device.mgt.common.push.notification.PushNotific
import io.entgra.device.mgt.core.device.mgt.common.push.notification.PushNotificationExecutionFailedException; import io.entgra.device.mgt.core.device.mgt.common.push.notification.PushNotificationExecutionFailedException;
import io.entgra.device.mgt.core.device.mgt.extensions.push.notification.provider.fcm.internal.FCMDataHolder; import io.entgra.device.mgt.core.device.mgt.extensions.push.notification.provider.fcm.internal.FCMDataHolder;
import io.entgra.device.mgt.core.device.mgt.extensions.push.notification.provider.fcm.util.FCMUtil; 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.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List; import java.util.List;
public class FCMNotificationStrategy implements NotificationStrategy { public class FCMNotificationStrategy implements NotificationStrategy {
@ -89,8 +89,6 @@ public class FCMNotificationStrategy implements NotificationStrategy {
*/ */
private void sendWakeUpCall(String accessToken, String registrationId) throws IOException, private void sendWakeUpCall(String accessToken, String registrationId) throws IOException,
PushNotificationExecutionFailedException { PushNotificationExecutionFailedException {
HttpURLConnection conn = null;
String fcmServerEndpoint = FCMUtil.getInstance().getContextMetadataProperties() String fcmServerEndpoint = FCMUtil.getInstance().getContextMetadataProperties()
.getProperty(FCM_ENDPOINT_KEY); .getProperty(FCM_ENDPOINT_KEY);
if(fcmServerEndpoint == null) { if(fcmServerEndpoint == null) {
@ -99,26 +97,21 @@ public class FCMNotificationStrategy implements NotificationStrategy {
throw new PushNotificationExecutionFailedException(msg); throw new PushNotificationExecutionFailedException(msg);
} }
try { RequestBody fcmRequest = getFCMRequest(registrationId);
byte[] bytes = getFCMRequest(registrationId).getBytes(); Request request = new Request.Builder()
URL url = new URL(fcmServerEndpoint); .url(fcmServerEndpoint)
conn = (HttpURLConnection) url.openConnection(); .post(fcmRequest)
conn.setRequestProperty("Content-Type", "application/json"); .addHeader("Authorization", "Bearer " + accessToken)
conn.setRequestProperty("Authorization", "Bearer " + accessToken); .build();
conn.setRequestMethod("POST"); try (Response response = FCMUtil.getInstance().getHttpClient().newCall(request).execute()) {
conn.setDoOutput(true); if (log.isDebugEnabled()) {
log.debug("FCM message sent to the FCM server. Response code: " + response.code()
try (OutputStream os = conn.getOutputStream()) { + " Response message : " + response.message());
os.write(bytes);
}
int status = conn.getResponseCode();
if (status != 200) {
log.error("Response Status: " + status + ", Response Message: " + conn.getResponseMessage());
} }
} finally { if(!response.isSuccessful()) {
if (conn != null) { String msg = "Response Status: " + response.code() + ", Response Message: " + response.message();
conn.disconnect(); log.error(msg);
throw new IOException(msg);
} }
} }
} }
@ -128,14 +121,14 @@ public class FCMNotificationStrategy implements NotificationStrategy {
* @param registrationId Registration ID of the device * @param registrationId Registration ID of the device
* @return FCM request as a JSON string * @return FCM request as a JSON string
*/ */
private static String getFCMRequest(String registrationId) { private static RequestBody getFCMRequest(String registrationId) {
JsonObject messageObject = new JsonObject(); JsonObject messageObject = new JsonObject();
messageObject.addProperty("token", registrationId); messageObject.addProperty("token", registrationId);
JsonObject fcmRequest = new JsonObject(); JsonObject fcmRequest = new JsonObject();
fcmRequest.add("message", messageObject); fcmRequest.add("message", messageObject);
return fcmRequest.toString(); return RequestBody.create(fcmRequest.toString(), okhttp3.MediaType.parse("application/json"));
} }
@Override @Override

@ -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.ContextMetadata;
import io.entgra.device.mgt.core.device.mgt.core.config.push.notification.PushNotificationConfiguration; 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 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.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.utils.CarbonUtils; import org.wso2.carbon.utils.CarbonUtils;
@ -33,6 +35,7 @@ import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.List; import java.util.List;
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.TimeUnit;
public class FCMUtil { public class FCMUtil {
@ -43,10 +46,29 @@ public class FCMUtil {
"repository" + File.separator + "resources" + File.separator + "service-account.json"; "repository" + File.separator + "resources" + File.separator + "service-account.json";
private static final String[] FCM_SCOPES = { "https://www.googleapis.com/auth/firebase.messaging" }; private static final String[] FCM_SCOPES = { "https://www.googleapis.com/auth/firebase.messaging" };
private Properties contextMetadataProperties; private Properties contextMetadataProperties;
private static ConnectionPool connectionPool;
private static OkHttpClient client;
private FCMUtil() { private FCMUtil() {
initContextConfigs(); initContextConfigs();
initDefaultOAuthApplication(); 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() { private void initDefaultOAuthApplication() {

@ -46,7 +46,6 @@ import org.wso2.carbon.user.api.UserStoreException;
import org.wso2.carbon.user.api.UserStoreManager; import org.wso2.carbon.user.api.UserStoreManager;
import org.wso2.carbon.utils.AbstractAxis2ConfigurationContextObserver; import org.wso2.carbon.utils.AbstractAxis2ConfigurationContextObserver;
import org.wso2.carbon.utils.multitenancy.MultitenantConstants; import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -143,26 +142,6 @@ public class TenantCreateObserver extends AbstractAxis2ConfigurationContextObser
*/ */
private void publishScopesToTenant(String tenantDomain) throws TenantManagementException { private void publishScopesToTenant(String tenantDomain) throws TenantManagementException {
if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) {
MetadataManagementService metadataManagementService = DeviceManagementDataHolder.getInstance().getMetadataManagementService();
Map<String, String> superTenantPermScopeMapping = getPermScopeMapping(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
Map<String, String> 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(); APIApplicationServices apiApplicationServices = DeviceManagementDataHolder.getInstance().getApiApplicationServices();
APIApplicationKey apiApplicationKey; APIApplicationKey apiApplicationKey;
AccessTokenInfo accessTokenInfo; AccessTokenInfo accessTokenInfo;
@ -270,10 +249,6 @@ public class TenantCreateObserver extends AbstractAxis2ConfigurationContextObser
} }
} }
} }
if (missingScopes.size() > 0 || deletedScopes.size() > 0) {
updatePermScopeMetaData(superTenantPermScopeMapping, metadataManagementService);
}
} else { } else {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Starting to publish shared scopes to newly created tenant: '" + tenantDomain + "'."); log.debug("Starting to publish shared scopes to newly created tenant: '" + tenantDomain + "'.");
@ -281,7 +256,6 @@ public class TenantCreateObserver extends AbstractAxis2ConfigurationContextObser
publishSharedScopes(Arrays.asList(superTenantScopes), publisherRESTAPIServices, publishSharedScopes(Arrays.asList(superTenantScopes), publisherRESTAPIServices,
apiApplicationKey, accessTokenInfo); apiApplicationKey, accessTokenInfo);
updatePermScopeMetaData(superTenantPermScopeMapping, metadataManagementService);
} }
} else { } else {
msg = "Unable to publish scopes to sub tenants due to super tenant scopes list being empty."; msg = "Unable to publish scopes to sub tenants due to super tenant scopes list being empty.";
@ -300,15 +274,6 @@ public class TenantCreateObserver extends AbstractAxis2ConfigurationContextObser
msg = "Error occurred while publishing scopes to '" + tenantDomain + "' tenant space."; msg = "Error occurred while publishing scopes to '" + tenantDomain + "' tenant space.";
log.error(msg, e); log.error(msg, e);
throw new TenantManagementException(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 { } finally {
APIPublisherUtils.removeScopePublishUserIfExists(tenantDomain); APIPublisherUtils.removeScopePublishUserIfExists(tenantDomain);
PrivilegedCarbonContext.endTenantFlow(); PrivilegedCarbonContext.endTenantFlow();

@ -216,8 +216,8 @@ public class OperationTemplateServiceImpl implements OperationTemplateService {
throws OperationTemplateMgtPluginException { throws OperationTemplateMgtPluginException {
AssertUtils.hasText(deviceType, "Invalid device type."); AssertUtils.hasText(deviceType, "Invalid device type.");
try { try {
ConnectionManagerUtils.openDBConnection(); ConnectionManagerUtils.openDBConnection();
return operationTemplateDAO.getAllOperationTemplates(deviceType); return operationTemplateDAO.getAllOperationTemplates(deviceType);
} catch (DBConnectionException | OperationTemplateManagementDAOException e) { } catch (DBConnectionException | OperationTemplateManagementDAOException e) {
log.error(e.getMessage()); log.error(e.getMessage());
throw new OperationTemplateMgtPluginException(e.getMessage(), e); throw new OperationTemplateMgtPluginException(e.getMessage(), e);
@ -273,11 +273,12 @@ public class OperationTemplateServiceImpl implements OperationTemplateService {
*/ */
@Override @Override
public Set<String> getOperationTemplateCodes(String deviceType, String subTypeId) public Set<String> getOperationTemplateCodes(String deviceType, String subTypeId)
throws OperationTemplateMgtPluginException { throws OperationTemplateMgtPluginException {
try { try {
AssertUtils.hasText(subTypeId, "Invalid meter device subtype id: " + subTypeId); AssertUtils.hasText(subTypeId, "Invalid device subtype id: " + subTypeId);
AssertUtils.isTrue(Integer.valueOf(subTypeId)>0, "Invalid meter device subtype id: " + subTypeId); AssertUtils.isTrue(Integer.parseInt(subTypeId) > 0,
"Invalid device subtype id: " + subTypeId);
AssertUtils.hasText(deviceType, "Invalid device type."); AssertUtils.hasText(deviceType, "Invalid device type.");
String key = OperationTemplateManagementUtil.setOperationTemplateCacheKey(deviceType, subTypeId); String key = OperationTemplateManagementUtil.setOperationTemplateCacheKey(deviceType, subTypeId);
@ -294,7 +295,6 @@ public class OperationTemplateServiceImpl implements OperationTemplateService {
} }
/** /**
*
* @param subTypeId * @param subTypeId
* @param deviceType * @param deviceType
* @param operationCode * @param operationCode
@ -303,18 +303,18 @@ public class OperationTemplateServiceImpl implements OperationTemplateService {
private void validateGetOperationTemplate(String subTypeId, String deviceType, String operationCode) private void validateGetOperationTemplate(String subTypeId, String deviceType, String operationCode)
throws OperationTemplateMgtPluginException { throws OperationTemplateMgtPluginException {
AssertUtils.hasText(subTypeId, "Invalid meter device subtype id: " + subTypeId); AssertUtils.hasText(subTypeId, "Invalid device subtype id: " + subTypeId);
AssertUtils.isTrue(Integer.valueOf(subTypeId)>0, "Invalid meter 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(operationCode, "Validation failed due to invalid operation code: " + operationCode);
AssertUtils.hasText(deviceType, "Invalid device type."); AssertUtils.hasText(deviceType, "Invalid device type.");
AssertUtils.isTrue(deviceType.equals("METER"), "Invalid device type. ");
} }
/** /**
* @param operationTemplate * @param operationTemplate
* @throws OperationTemplateMgtPluginException * @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.isNull(operationTemplate, "Operation Template can not be null");
AssertUtils.hasText(operationTemplate.getOperationDefinition(), "Operation definition can not be null"); AssertUtils.hasText(operationTemplate.getOperationDefinition(), "Operation definition can not be null");

@ -49,7 +49,7 @@ public class ServiceNegativeTest extends BaseOperationTemplatePluginTest {
@Test(description = "This method tests Add Operation template under negative circumstances while missing " + @Test(description = "This method tests Add Operation template under negative circumstances while missing " +
"required fields", "required fields",
expectedExceptions = {OperationTemplateMgtPluginException.class}, expectedExceptions = {OperationTemplateMgtPluginException.class},
expectedExceptionsMessageRegExp = "Invalid meter device subtype id: 0") expectedExceptionsMessageRegExp = "Invalid device subtype id: 0")
public void testAddOperationTemplates() throws OperationTemplateMgtPluginException { public void testAddOperationTemplates() throws OperationTemplateMgtPluginException {
OperationTemplate operationTemplate = new OperationTemplate(); OperationTemplate operationTemplate = new OperationTemplate();

@ -31,13 +31,13 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
public class GetDeviceSubTypeCacheLoader extends CacheLoader<DeviceSubTypeCacheKey, DeviceSubType> { public class DeviceSubTypeCacheLoader extends CacheLoader<DeviceSubTypeCacheKey, DeviceSubType> {
private static final Log log = LogFactory.getLog(GetDeviceSubTypeCacheLoader.class); private static final Log log = LogFactory.getLog(DeviceSubTypeCacheLoader.class);
private final DeviceSubTypeDAO deviceSubTypeDAO; private final DeviceSubTypeDAO deviceSubTypeDAO;
public GetDeviceSubTypeCacheLoader() { public DeviceSubTypeCacheLoader() {
this.deviceSubTypeDAO = DeviceSubTypeDAOFactory.getDeviceSubTypeDAO(); this.deviceSubTypeDAO = DeviceSubTypeDAOFactory.getDeviceSubTypeDAO();
} }

@ -101,8 +101,9 @@ public class DeviceSubTypeDAOImpl implements DeviceSubTypeDAO {
public DeviceSubType getDeviceSubType(String subTypeId, int tenantId, String deviceType) public DeviceSubType getDeviceSubType(String subTypeId, int tenantId, String deviceType)
throws SubTypeMgtDAOException { throws SubTypeMgtDAOException {
try { try {
String sql = "SELECT s.*, o.OPERATION_CODE FROM DM_DEVICE_SUB_TYPE s " + 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 " + "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 = ?"; "WHERE s.SUB_TYPE_ID = ? AND s.TENANT_ID = ? AND s.DEVICE_TYPE = ?";
Connection conn = ConnectionManagerUtil.getDBConnection(); Connection conn = ConnectionManagerUtil.getDBConnection();
@ -143,8 +144,7 @@ public class DeviceSubTypeDAOImpl implements DeviceSubTypeDAO {
stmt.setInt(1, tenantId); stmt.setInt(1, tenantId);
stmt.setString(2, deviceType); stmt.setString(2, deviceType);
try (ResultSet rs = stmt.executeQuery()) { try (ResultSet rs = stmt.executeQuery()) {
List<DeviceSubType> deviceSubTypes = DAOUtil.loadDeviceSubTypes(rs); return DAOUtil.loadDeviceSubTypes(rs);
return deviceSubTypes;
} }
} }
} catch (DBConnectionException e) { } catch (DBConnectionException e) {
@ -163,14 +163,14 @@ public class DeviceSubTypeDAOImpl implements DeviceSubTypeDAO {
@Override @Override
public int getDeviceSubTypeCount(String deviceType) throws SubTypeMgtDAOException { public int getDeviceSubTypeCount(String deviceType) throws SubTypeMgtDAOException {
try { 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(); Connection conn = ConnectionManagerUtil.getDBConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)) { try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, deviceType); stmt.setString(1, deviceType);
try (ResultSet rs = stmt.executeQuery()) { try (ResultSet rs = stmt.executeQuery()) {
if (rs.next()) { if (rs.next()) {
return rs.getInt("DEVICE_COUNT"); return rs.getInt("SUB_TYPE_COUNT");
} }
return 0; return 0;
} }
@ -252,4 +252,5 @@ public class DeviceSubTypeDAOImpl implements DeviceSubTypeDAO {
throw new SubTypeMgtDAOException(msg, e); throw new SubTypeMgtDAOException(msg, e);
} }
} }
} }

@ -72,7 +72,7 @@ public class DAOUtil {
deviceSubType = loadDeviceSubType(rs); deviceSubType = loadDeviceSubType(rs);
} }
if (operationCode != null) { if (operationCode != null) {
deviceSubType.addOperationCode(operationCode); deviceSubType.addSupportedOperation(operationCode);
} }
deviceSubTypes.put(key, deviceSubType); deviceSubTypes.put(key, deviceSubType);
} }

@ -24,7 +24,6 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
public abstract class DeviceSubType { public abstract class DeviceSubType {
private String subTypeId; private String subTypeId;
@ -32,22 +31,22 @@ public abstract class DeviceSubType {
private String deviceType; private String deviceType;
private String subTypeName; private String subTypeName;
private String typeDefinition; private String typeDefinition;
private Set<String> operationCodes = new HashSet<>(); private final Set<String> supportedOperations = new HashSet<>();
public DeviceSubType() { public DeviceSubType() {
} }
public DeviceSubType(String subTypeId, int tenantId, String deviceType, String subTypeName, String typeDefinition, public DeviceSubType(String subTypeId, int tenantId, String deviceType,
Set<String> operationCodes) { String subTypeName, String typeDefinition,
Set<String> supportedOperations) {
this.subTypeId = subTypeId; this.subTypeId = subTypeId;
this.tenantId = tenantId; this.tenantId = tenantId;
this.deviceType = deviceType; this.deviceType = deviceType;
this.subTypeName = subTypeName; this.subTypeName = subTypeName;
this.typeDefinition = typeDefinition; this.typeDefinition = typeDefinition;
if (operationCodes != null || !operationCodes.isEmpty()) { if (supportedOperations != null && !supportedOperations.isEmpty()) {
this.operationCodes.addAll(operationCodes); this.supportedOperations.addAll(supportedOperations);
} }
} }
public String getSubTypeId() { public String getSubTypeId() {
@ -94,10 +93,16 @@ public abstract class DeviceSubType {
public abstract String parseSubTypeToJson() throws JsonProcessingException; public abstract String parseSubTypeToJson() throws JsonProcessingException;
public void addOperationCode(String code) { public void setSupportedOperations(Set<String> supportedOperations) {
operationCodes.add(code); this.supportedOperations.addAll(supportedOperations);
} }
public Set<String> getOperationCodes() {
return operationCodes; public void addSupportedOperation(String code) {
supportedOperations.add(code);
} }
public Set<String> getSupportedOperations() {
return supportedOperations;
}
} }

@ -21,7 +21,7 @@ package io.entgra.device.mgt.core.subtype.mgt.impl;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache; 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.dao.DeviceSubTypeDAO; import io.entgra.device.mgt.core.subtype.mgt.dao.DeviceSubTypeDAO;
import io.entgra.device.mgt.core.subtype.mgt.dao.DeviceSubTypeDAOFactory; import io.entgra.device.mgt.core.subtype.mgt.dao.DeviceSubTypeDAOFactory;
import io.entgra.device.mgt.core.subtype.mgt.dao.util.ConnectionManagerUtil; import io.entgra.device.mgt.core.subtype.mgt.dao.util.ConnectionManagerUtil;
@ -48,7 +48,7 @@ public class DeviceSubTypeServiceImpl implements DeviceSubTypeService {
private static final LoadingCache<DeviceSubTypeCacheKey, DeviceSubType> deviceSubTypeCache private static final LoadingCache<DeviceSubTypeCacheKey, DeviceSubType> deviceSubTypeCache
= CacheBuilder.newBuilder() = CacheBuilder.newBuilder()
.expireAfterWrite(15, TimeUnit.MINUTES) .expireAfterWrite(15, TimeUnit.MINUTES)
.build(new GetDeviceSubTypeCacheLoader()); .build(new DeviceSubTypeCacheLoader());
private final DeviceSubTypeDAO deviceSubTypeDAO; private final DeviceSubTypeDAO deviceSubTypeDAO;
public DeviceSubTypeServiceImpl() { public DeviceSubTypeServiceImpl() {
@ -166,7 +166,13 @@ public class DeviceSubTypeServiceImpl implements DeviceSubTypeService {
throws SubTypeMgtPluginException { throws SubTypeMgtPluginException {
try { try {
ConnectionManagerUtil.openDBConnection(); ConnectionManagerUtil.openDBConnection();
return deviceSubTypeDAO.getAllDeviceSubTypes(tenantId, deviceType); List<DeviceSubType> 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) { } catch (DBConnectionException e) {
String msg = "Error occurred while obtaining the database connection to retrieve all device subtype for " + String msg = "Error occurred while obtaining the database connection to retrieve all device subtype for " +
deviceType + " subtypes"; deviceType + " subtypes";

Loading…
Cancel
Save