From 64d194bfea72d6a5f55ac20f41f1c8f92d13d401 Mon Sep 17 00:00:00 2001 From: rajitha Date: Mon, 10 Apr 2023 03:29:10 +0530 Subject: [PATCH 01/10] add tenant-mgt module --- .../DeviceManagementServiceComponent.java | 4 +- .../io.entgra.tenant.mgt.common/pom.xml | 49 +++++++ .../common/exception/TenantMgtException.java | 11 ++ .../mgt/common/spi/TenantManagerService.java | 10 ++ .../io.entgra.tenant.mgt.core/pom.xml | 115 +++++++++++++++++ .../entgra/tenant/mgt/core/TenantManager.java | 10 ++ .../mgt/core/impl/TenantManagerImpl.java | 122 ++++++++++++++++++ .../core/impl/TenantManagerServiceImpl.java | 27 ++++ .../core/internal/TenantMgtDataHolder.java | 53 ++++++++ .../internal/TenantMgtServiceComponent.java | 74 +++++++++++ .../listener/DeviceMgtTenantListener.java | 74 +++++++++++ components/tenant-mgt/pom.xml | 23 ++++ .../pom.xml | 94 ++++++++++++++ .../src/main/resources/build.properties | 1 + .../src/main/resources/p2.inf | 1 + features/tenant-mgt/pom.xml | 19 +++ pom.xml | 15 ++- 17 files changed, 699 insertions(+), 3 deletions(-) create mode 100644 components/tenant-mgt/io.entgra.tenant.mgt.common/pom.xml create mode 100644 components/tenant-mgt/io.entgra.tenant.mgt.common/src/main/java/io/entgra/tenant/mgt/common/exception/TenantMgtException.java create mode 100644 components/tenant-mgt/io.entgra.tenant.mgt.common/src/main/java/io/entgra/tenant/mgt/common/spi/TenantManagerService.java create mode 100644 components/tenant-mgt/io.entgra.tenant.mgt.core/pom.xml create mode 100644 components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/TenantManager.java create mode 100644 components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/impl/TenantManagerImpl.java create mode 100644 components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/impl/TenantManagerServiceImpl.java create mode 100644 components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtDataHolder.java create mode 100644 components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtServiceComponent.java create mode 100644 components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/listener/DeviceMgtTenantListener.java create mode 100644 components/tenant-mgt/pom.xml create mode 100644 features/tenant-mgt/io.entgra.tenant.mgt.server.feature/pom.xml create mode 100644 features/tenant-mgt/io.entgra.tenant.mgt.server.feature/src/main/resources/build.properties create mode 100644 features/tenant-mgt/io.entgra.tenant.mgt.server.feature/src/main/resources/p2.inf create mode 100644 features/tenant-mgt/pom.xml diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementServiceComponent.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementServiceComponent.java index f36def494d7..180730dd6cb 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementServiceComponent.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementServiceComponent.java @@ -271,8 +271,8 @@ public class DeviceManagementServiceComponent { componentContext.getBundleContext().registerService(PrivacyComplianceProvider.class.getName(), privacyComplianceProvider, null); - componentContext.getBundleContext() - .registerService(TenantMgtListener.class.getName(), new DeviceMgtTenantMgtListener(), null); +// componentContext.getBundleContext() +// .registerService(TenantMgtListener.class.getName(), new DeviceMgtTenantMgtListener(), null); if (log.isDebugEnabled()) { log.debug("Device management core bundle has been successfully initialized"); diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.common/pom.xml b/components/tenant-mgt/io.entgra.tenant.mgt.common/pom.xml new file mode 100644 index 00000000000..2c81fb58c6c --- /dev/null +++ b/components/tenant-mgt/io.entgra.tenant.mgt.common/pom.xml @@ -0,0 +1,49 @@ + + + + tenant-mgt + org.wso2.carbon.devicemgt + 5.0.25-SNAPSHOT + ../pom.xml + + + 4.0.0 + io.entgra.tenant.mgt.common + Entgra IoT - Tenant Manager Common + Entgra IoT - Tenant Manager Common + bundle + + + + + org.apache.felix + maven-bundle-plugin + true + + + ${project.artifactId} + ${project.artifactId} + ${carbon.device.mgt.version} + Tenant Management Common Bundle + + org.apache.commons.logging, + org.wso2.carbon.stratos.common.beans + + io.entgra.tenant.mgt.common.* + + + + + + + + + org.wso2.carbon.commons + org.wso2.carbon.tenant.common + ${carbon.commons.version} + + + + \ No newline at end of file diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.common/src/main/java/io/entgra/tenant/mgt/common/exception/TenantMgtException.java b/components/tenant-mgt/io.entgra.tenant.mgt.common/src/main/java/io/entgra/tenant/mgt/common/exception/TenantMgtException.java new file mode 100644 index 00000000000..c0e278bd2b3 --- /dev/null +++ b/components/tenant-mgt/io.entgra.tenant.mgt.common/src/main/java/io/entgra/tenant/mgt/common/exception/TenantMgtException.java @@ -0,0 +1,11 @@ +package io.entgra.tenant.mgt.common.exception; + +public class TenantMgtException extends Exception { + public TenantMgtException(String msg, Throwable ex) { + super(msg, ex); + } + + public TenantMgtException(String msg) { + super(msg); + } +} diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.common/src/main/java/io/entgra/tenant/mgt/common/spi/TenantManagerService.java b/components/tenant-mgt/io.entgra.tenant.mgt.common/src/main/java/io/entgra/tenant/mgt/common/spi/TenantManagerService.java new file mode 100644 index 00000000000..a721e030298 --- /dev/null +++ b/components/tenant-mgt/io.entgra.tenant.mgt.common/src/main/java/io/entgra/tenant/mgt/common/spi/TenantManagerService.java @@ -0,0 +1,10 @@ +package io.entgra.tenant.mgt.common.spi; + +import io.entgra.tenant.mgt.common.exception.TenantMgtException; +import org.wso2.carbon.stratos.common.beans.TenantInfoBean; + +public interface TenantManagerService { + void addDefaultRoles(TenantInfoBean tenantInfoBean) throws TenantMgtException; + + void addDefaultAppCategories(TenantInfoBean tenantInfoBean) throws TenantMgtException; +} \ No newline at end of file diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.core/pom.xml b/components/tenant-mgt/io.entgra.tenant.mgt.core/pom.xml new file mode 100644 index 00000000000..76284fea49f --- /dev/null +++ b/components/tenant-mgt/io.entgra.tenant.mgt.core/pom.xml @@ -0,0 +1,115 @@ + + + + tenant-mgt + org.wso2.carbon.devicemgt + 5.0.25-SNAPSHOT + ../pom.xml + + + 4.0.0 + io.entgra.tenant.mgt.core + Entgra IoT - Tenant Manager Core + Entgra IoT - Tenant Manager Core + bundle + + + + + org.apache.felix + maven-scr-plugin + + + org.apache.felix + maven-bundle-plugin + true + + + ${project.artifactId} + ${project.artifactId} + ${carbon.device.mgt.version} + Tenant Management Core Bundle + io.entgra.tenant.mgt.core.internal + + org.osgi.framework.*;version="${imp.package.version.osgi.framework}", + org.osgi.service.*;version="${imp.package.version.osgi.service}", + org.apache.commons.logging, + io.entgra.application.mgt.common.*, + io.entgra.application.mgt.core.config, + org.wso2.carbon.device.mgt.core, + org.wso2.carbon.user.api, + org.wso2.carbon.registry.core.exceptions, + io.entgra.tenant.mgt.common.*, + org.wso2.carbon.stratos.common.beans, + org.wso2.carbon.stratos.common.exception, + org.wso2.carbon.stratos.common.listeners, + org.wso2.carbon.device.mgt.common.metadata.mgt, + org.wso2.carbon.device.mgt.core.metadata.mgt, + org.wso2.carbon.user.core.service, + org.wso2.carbon.context + + + !io.entgra.tenant.mgt.core.internal, + io.entgra.tenant.mgt.core.* + + + + + + + + + + org.eclipse.osgi + org.eclipse.osgi + + + org.eclipse.osgi + org.eclipse.osgi.services + + + org.wso2.carbon.commons + org.wso2.carbon.tenant.common + ${carbon.commons.version} + + + org.wso2.carbon + org.wso2.carbon.registry.core + + + org.wso2.carbon + org.wso2.carbon.user.core + + + org.wso2.carbon + org.wso2.carbon.user.api + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.core + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.common + + + org.wso2.carbon.devicemgt + io.entgra.application.mgt.core + + + org.wso2.carbon.devicemgt + io.entgra.application.mgt.common + + + org.wso2.carbon.devicemgt + io.entgra.tenant.mgt.common + + + org.wso2.carbon + org.wso2.carbon.utils + + + + \ No newline at end of file diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/TenantManager.java b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/TenantManager.java new file mode 100644 index 00000000000..2f9b63281b3 --- /dev/null +++ b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/TenantManager.java @@ -0,0 +1,10 @@ +package io.entgra.tenant.mgt.core; + +import io.entgra.tenant.mgt.common.exception.TenantMgtException; +import org.wso2.carbon.stratos.common.beans.TenantInfoBean; + +public interface TenantManager { + void addDefaultRoles(TenantInfoBean tenantInfoBean) throws TenantMgtException; + + void addDefaultAppCategories(TenantInfoBean tenantInfoBean) throws TenantMgtException; +} diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/impl/TenantManagerImpl.java b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/impl/TenantManagerImpl.java new file mode 100644 index 00000000000..8782f7ca1ae --- /dev/null +++ b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/impl/TenantManagerImpl.java @@ -0,0 +1,122 @@ +package io.entgra.tenant.mgt.core.impl; + +import io.entgra.application.mgt.common.exception.ApplicationManagementException; +import io.entgra.application.mgt.common.exception.InvalidConfigurationException; +import io.entgra.application.mgt.core.config.ConfigurationManager; +import io.entgra.application.mgt.common.services.ApplicationManager; +import io.entgra.tenant.mgt.core.TenantManager; +import io.entgra.tenant.mgt.common.exception.TenantMgtException; +import io.entgra.tenant.mgt.core.internal.TenantMgtDataHolder; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager; +import org.wso2.carbon.device.mgt.core.config.DeviceManagementConfig; +import org.wso2.carbon.device.mgt.core.permission.mgt.PermissionUtils; +import org.wso2.carbon.registry.core.exceptions.RegistryException; +import org.wso2.carbon.stratos.common.beans.TenantInfoBean; +import org.wso2.carbon.user.api.Permission; +import org.wso2.carbon.device.mgt.common.exceptions.MetadataManagementException; +import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagementException; +import org.wso2.carbon.device.mgt.common.roles.config.Role; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.user.api.UserStoreManager; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class TenantManagerImpl implements TenantManager { + private static final Log log = LogFactory.getLog(TenantManagerImpl.class); + private static final String PERMISSION_ACTION = "ui.execute"; + + @Override + public void addDefaultRoles(TenantInfoBean tenantInfoBean) throws TenantMgtException { + initTenantFlow(tenantInfoBean); + DeviceManagementConfig config = DeviceConfigurationManager.getInstance().getDeviceManagementConfig(); + if (config.getDefaultRoles().isEnabled()) { + Map> roleMap = getValidRoleMap(config); + try { + UserStoreManager userStoreManager = TenantMgtDataHolder.getInstance().getRealmService() + .getTenantUserRealm(tenantInfoBean.getTenantId()).getUserStoreManager(); + + roleMap.forEach((key, value) -> { + try { + userStoreManager.addRole(key, null, value.toArray(new Permission[0])); + } catch (UserStoreException e) { + log.error("Error occurred while adding default roles into user store", e); + } + }); + } catch (UserStoreException e) { + String msg = "Error occurred while getting user store manager"; + log.error(msg, e); + throw new TenantMgtException(msg, e); + } + } + try { + TenantMgtDataHolder.getInstance().getWhiteLabelManagementService(). + addDefaultWhiteLabelThemeIfNotExist(tenantInfoBean.getTenantId()); + } catch (MetadataManagementException e) { + String msg = "Error occurred while adding default white label theme to created tenant - id "+tenantInfoBean.getTenantId(); + log.error(msg, e); + throw new TenantMgtException(msg, e); + } finally { + endTenantFlow(); + } + } + + @Override + public void addDefaultAppCategories(TenantInfoBean tenantInfoBean) throws TenantMgtException { + initTenantFlow(tenantInfoBean); + try { + ApplicationManager applicationManager = TenantMgtDataHolder.getInstance().getApplicationManager(); + applicationManager + .addApplicationCategories(ConfigurationManager.getInstance().getConfiguration().getAppCategories()); + } catch (InvalidConfigurationException e) { + String msg = "Error occurred while getting application manager"; + throw new TenantMgtException(msg, e); + } catch (ApplicationManagementException e) { + String msg = "Error occurred while getting default application categories"; + log.error(msg, e); + throw new TenantMgtException(msg, e); + } finally { + endTenantFlow(); + } + + } + + private void initTenantFlow(TenantInfoBean tenantInfoBean) { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext privilegedCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + privilegedCarbonContext.setTenantId(tenantInfoBean.getTenantId()); + privilegedCarbonContext.setTenantDomain(tenantInfoBean.getTenantDomain()); + } + + private void endTenantFlow() { + PrivilegedCarbonContext.endTenantFlow(); + } + + private Map> getValidRoleMap(DeviceManagementConfig config) { + Map> roleMap = new HashMap<>(); + try { + for (Role role : config.getDefaultRoles().getRoles()) { + List permissionList = new ArrayList<>(); + for (String permissionPath : role.getPermissions()) { + if (PermissionUtils.checkResourceExists(permissionPath)) { + Permission permission = new Permission(permissionPath, PERMISSION_ACTION); + + permissionList.add(permission); + } else { + log.warn("Permission " + permissionPath + " does not exist. Hence it will not add to role " + + role.getName()); + } + } + roleMap.put(role.getName(), permissionList); + } + } catch (PermissionManagementException | RegistryException e) { + log.error("Error occurred while checking permission existence.", e); + } + return roleMap; + } +} diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/impl/TenantManagerServiceImpl.java b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/impl/TenantManagerServiceImpl.java new file mode 100644 index 00000000000..760e49f4e85 --- /dev/null +++ b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/impl/TenantManagerServiceImpl.java @@ -0,0 +1,27 @@ +package io.entgra.tenant.mgt.core.impl; + +import io.entgra.tenant.mgt.common.spi.TenantManagerService; +import io.entgra.tenant.mgt.core.TenantManager; +import io.entgra.tenant.mgt.common.exception.TenantMgtException; +import io.entgra.tenant.mgt.core.internal.TenantMgtDataHolder; +import org.wso2.carbon.stratos.common.beans.TenantInfoBean; + +public class TenantManagerServiceImpl implements TenantManagerService { + + private final TenantManager tenantManager; + + public TenantManagerServiceImpl() { + tenantManager = new TenantManagerImpl(); + TenantMgtDataHolder.getInstance().setTenantManager(tenantManager); + } + + @Override + public void addDefaultRoles(TenantInfoBean tenantInfoBean) throws TenantMgtException { + tenantManager.addDefaultRoles(tenantInfoBean); + } + + @Override + public void addDefaultAppCategories(TenantInfoBean tenantInfoBean) throws TenantMgtException { + tenantManager.addDefaultAppCategories(tenantInfoBean); + } +} diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtDataHolder.java b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtDataHolder.java new file mode 100644 index 00000000000..6f9d603a3ff --- /dev/null +++ b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtDataHolder.java @@ -0,0 +1,53 @@ +package io.entgra.tenant.mgt.core.internal; + +import io.entgra.application.mgt.common.services.ApplicationManager; +import io.entgra.tenant.mgt.core.TenantManager; +import org.wso2.carbon.device.mgt.common.metadata.mgt.WhiteLabelManagementService; +import org.wso2.carbon.user.core.service.RealmService; + +public class TenantMgtDataHolder { + private static final TenantMgtDataHolder instance = new TenantMgtDataHolder(); + private TenantManager tenantManager; + + private ApplicationManager applicationManager; + + private WhiteLabelManagementService whiteLabelManagementService; + + private RealmService realmService; + + public RealmService getRealmService() { + return realmService; + } + + public void setRealmService(RealmService realmService) { + this.realmService = realmService; + } + + public ApplicationManager getApplicationManager() { + return applicationManager; + } + + public void setApplicationManager(ApplicationManager applicationManager) { + this.applicationManager = applicationManager; + } + + public WhiteLabelManagementService getWhiteLabelManagementService() { + return whiteLabelManagementService; + } + + public void setWhiteLabelManagementService(WhiteLabelManagementService whiteLabelManagementService) { + this.whiteLabelManagementService = whiteLabelManagementService; + } + + public TenantManager getTenantManager() { + return tenantManager; + } + + public void setTenantManager(TenantManager tenantManager) { + this.tenantManager = tenantManager; + } + + public static TenantMgtDataHolder getInstance() { + return instance; + } +} diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtServiceComponent.java b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtServiceComponent.java new file mode 100644 index 00000000000..ac2b0be69bb --- /dev/null +++ b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtServiceComponent.java @@ -0,0 +1,74 @@ +package io.entgra.tenant.mgt.core.internal; + +import io.entgra.application.mgt.common.services.ApplicationManager; +import io.entgra.tenant.mgt.common.spi.TenantManagerService; +import io.entgra.tenant.mgt.core.impl.TenantManagerServiceImpl; +import io.entgra.tenant.mgt.core.listener.DeviceMgtTenantListener; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.osgi.service.component.ComponentContext; +import org.wso2.carbon.device.mgt.common.metadata.mgt.WhiteLabelManagementService; +import org.wso2.carbon.device.mgt.core.metadata.mgt.WhiteLabelManagementServiceImpl; +import org.wso2.carbon.user.core.service.RealmService; + +/** + * @scr.component name="org.wso2.carbon.devicemgt.tenant.manager" immediate="true" + * @scr.reference name="org.wso2.carbon.application.mgt.service" + * interface="io.entgra.application.mgt.common.services.ApplicationManager" + * cardinality="1..1" + * policy="dynamic" + * bind="setApplicationManager" + * unbind="unsetApplicationManager" + * @scr.reference name="user.realmservice.default" + * interface="org.wso2.carbon.user.core.service.RealmService" + * cardinality="1..1" + * policy="dynamic" + * bind="setRealmService" + * unbind="unsetRealmService" + */ + +public class TenantMgtServiceComponent { + + private static final Log log = LogFactory.getLog(TenantManagerService.class); + + @SuppressWarnings("unused") + protected void activate(ComponentContext componentContext) { + try { + TenantManagerService tenantManagerService = new TenantManagerServiceImpl(); + componentContext.getBundleContext(). + registerService(TenantManagerServiceImpl.class.getName(), tenantManagerService, null); + WhiteLabelManagementService whiteLabelManagementService = new WhiteLabelManagementServiceImpl(); + componentContext.getBundleContext().registerService(WhiteLabelManagementServiceImpl.class.getName(), + whiteLabelManagementService, null); + TenantMgtDataHolder.getInstance().setWhiteLabelManagementService(whiteLabelManagementService); + DeviceMgtTenantListener deviceMgtTenantListener = new DeviceMgtTenantListener(); + componentContext.getBundleContext(). + registerService(DeviceMgtTenantListener.class.getName(), deviceMgtTenantListener, null); + log.info("Tenant management service activated"); + } catch (Throwable t) { + String msg = "Error occurred while activating tenant management service"; + log.error(msg, t); + } + } + + @SuppressWarnings("unused") + protected void deactivate(ComponentContext componentContext) { + // nothing to do + } + + protected void setApplicationManager(ApplicationManager applicationManager) { + TenantMgtDataHolder.getInstance().setApplicationManager(applicationManager); + } + + protected void unsetApplicationManager(ApplicationManager applicationManager) { + TenantMgtDataHolder.getInstance().setApplicationManager(null); + } + + protected void setRealmService(RealmService realmService) { + TenantMgtDataHolder.getInstance().setRealmService(realmService); + } + + protected void unsetRealmService(RealmService realmService) { + TenantMgtDataHolder.getInstance().setRealmService(null); + } +} diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/listener/DeviceMgtTenantListener.java b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/listener/DeviceMgtTenantListener.java new file mode 100644 index 00000000000..43e31cf4e08 --- /dev/null +++ b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/listener/DeviceMgtTenantListener.java @@ -0,0 +1,74 @@ +package io.entgra.tenant.mgt.core.listener; + +import io.entgra.tenant.mgt.core.TenantManager; +import io.entgra.tenant.mgt.common.exception.TenantMgtException; +import io.entgra.tenant.mgt.core.internal.TenantMgtDataHolder; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.stratos.common.beans.TenantInfoBean; +import org.wso2.carbon.stratos.common.exception.StratosException; +import org.wso2.carbon.stratos.common.listeners.TenantMgtListener; + +public class DeviceMgtTenantListener implements TenantMgtListener { + + private static final Log log = LogFactory.getLog(DeviceMgtTenantListener.class); + public static final int LISTENER_EXECUTION_ORDER = 11; + + @Override + public void onTenantCreate(TenantInfoBean tenantInfoBean) { + // Any work to be performed after a tenant creation + TenantManager tenantManager = TenantMgtDataHolder.getInstance().getTenantManager(); + try { + tenantManager.addDefaultRoles(tenantInfoBean); + tenantManager.addDefaultAppCategories(tenantInfoBean); + } catch (TenantMgtException e) { + String msg = "Error occurred while executing tenant creation flow"; + log.error(msg, e); + } + } + + @Override + public void onTenantUpdate(TenantInfoBean tenantInfoBean) throws StratosException { + // Any work to be performed after a tenant information update happens + } + + @Override + public void onTenantDelete(int i) { + // Any work to be performed after a tenant deletion + } + + @Override + public void onTenantRename(int i, String s, String s1) throws StratosException { + // Any work to be performed after a tenant rename happens + } + + @Override + public void onTenantInitialActivation(int i) throws StratosException { + // Any work to be performed after a tenant's initial activation happens + } + + @Override + public void onTenantActivation(int i) throws StratosException { + // Any work to be performed after a tenant activation + } + + @Override + public void onTenantDeactivation(int i) throws StratosException { + // Any work to be performed after a tenant deactivation + } + + @Override + public void onSubscriptionPlanChange(int i, String s, String s1) throws StratosException { + // Any work to be performed after subscription plan change + } + + @Override + public int getListenerOrder() { + return LISTENER_EXECUTION_ORDER; + } + + @Override + public void onPreDelete(int i) throws StratosException { + // Any work to be performed before a tenant is deleted + } +} diff --git a/components/tenant-mgt/pom.xml b/components/tenant-mgt/pom.xml new file mode 100644 index 00000000000..58b3ebceb00 --- /dev/null +++ b/components/tenant-mgt/pom.xml @@ -0,0 +1,23 @@ + + + + carbon-devicemgt + org.wso2.carbon.devicemgt + 5.0.25-SNAPSHOT + ../../pom.xml + + + 4.0.0 + tenant-mgt + pom + Entgra IoT - Tenant Management Component + Entgra IoT - Tenant Management Component + + + io.entgra.tenant.mgt.core + io.entgra.tenant.mgt.common + + + \ No newline at end of file diff --git a/features/tenant-mgt/io.entgra.tenant.mgt.server.feature/pom.xml b/features/tenant-mgt/io.entgra.tenant.mgt.server.feature/pom.xml new file mode 100644 index 00000000000..04cf1bb3e55 --- /dev/null +++ b/features/tenant-mgt/io.entgra.tenant.mgt.server.feature/pom.xml @@ -0,0 +1,94 @@ + + + + tenant-mgt-feature + org.wso2.carbon.devicemgt + 5.0.25-SNAPSHOT + ../pom.xml + + + 4.0.0 + io.entgra.tenant.mgt.server.feature + Entgra IoT - Tenant Management Server Feature + Entgra IoT - Tenant Management Server Feature + pom + + + + org.wso2.carbon.devicemgt + io.entgra.tenant.mgt.core + + + org.wso2.carbon.devicemgt + io.entgra.tenant.mgt.common + + + + + + + maven-resources-plugin + 2.6 + + + copy-resources + generate-resources + + copy-resources + + + src/main/resources + + + resources + + build.properties + p2.inf + + + + + + + + + org.wso2.maven + carbon-p2-plugin + ${carbon.p2.plugin.version} + + + p2-feature-generation + package + + p2-feature-gen + + + io.entgra.tenant.mgt.server + ../../etc/feature.properties + + + org.wso2.carbon.p2.category.type:server + + org.eclipse.equinox.p2.type.group:true + + + + + + + org.wso2.carbon.devicemgt:io.entgra.tenant.mgt.core:${carbon.device.mgt.version} + + + org.wso2.carbon.devicemgt:io.entgra.tenant.mgt.common:${carbon.device.mgt.version} + + + + + + + + + + \ No newline at end of file diff --git a/features/tenant-mgt/io.entgra.tenant.mgt.server.feature/src/main/resources/build.properties b/features/tenant-mgt/io.entgra.tenant.mgt.server.feature/src/main/resources/build.properties new file mode 100644 index 00000000000..920f5778887 --- /dev/null +++ b/features/tenant-mgt/io.entgra.tenant.mgt.server.feature/src/main/resources/build.properties @@ -0,0 +1 @@ +custom=true \ No newline at end of file diff --git a/features/tenant-mgt/io.entgra.tenant.mgt.server.feature/src/main/resources/p2.inf b/features/tenant-mgt/io.entgra.tenant.mgt.server.feature/src/main/resources/p2.inf new file mode 100644 index 00000000000..7ab37b9d7d7 --- /dev/null +++ b/features/tenant-mgt/io.entgra.tenant.mgt.server.feature/src/main/resources/p2.inf @@ -0,0 +1 @@ +instructions.configure = \ \ No newline at end of file diff --git a/features/tenant-mgt/pom.xml b/features/tenant-mgt/pom.xml new file mode 100644 index 00000000000..d55378a8cbf --- /dev/null +++ b/features/tenant-mgt/pom.xml @@ -0,0 +1,19 @@ + + + + + carbon-devicemgt + org.wso2.carbon.devicemgt + 5.0.25-SNAPSHOT + ../../pom.xml + + + 4.0.0 + tenant-mgt-feature + pom + Entgra IoT - Tenant Management Feature + + + io.entgra.tenant.mgt.server.feature + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 2851e5865f0..7eee718846b 100644 --- a/pom.xml +++ b/pom.xml @@ -48,6 +48,7 @@ components/webapp-authenticator-framework components/logger components/task-mgt + components/tenant-mgt features/device-mgt features/apimgt-extensions features/application-mgt @@ -62,7 +63,7 @@ features/webapp-authenticator-framework features/logger features/task-mgt - + features/tenant-mgt @@ -370,6 +371,18 @@ + + + org.wso2.carbon.devicemgt + io.entgra.tenant.mgt.common + ${carbon.device.mgt.version} + + + org.wso2.carbon.devicemgt + io.entgra.tenant.mgt.core + ${carbon.device.mgt.version} + + org.wso2.carbon.devicemgt From c33f402fd13e5176c72c25875a9655229a845d57 Mon Sep 17 00:00:00 2001 From: rajitha Date: Tue, 18 Apr 2023 15:34:07 +0530 Subject: [PATCH 02/10] Fix bundling issues --- components/tenant-mgt/io.entgra.tenant.mgt.core/pom.xml | 4 ++++ .../tenant/mgt/core/internal/TenantMgtServiceComponent.java | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.core/pom.xml b/components/tenant-mgt/io.entgra.tenant.mgt.core/pom.xml index 76284fea49f..5ec9904eb3d 100644 --- a/components/tenant-mgt/io.entgra.tenant.mgt.core/pom.xml +++ b/components/tenant-mgt/io.entgra.tenant.mgt.core/pom.xml @@ -46,7 +46,11 @@ org.wso2.carbon.stratos.common.exception, org.wso2.carbon.stratos.common.listeners, org.wso2.carbon.device.mgt.common.metadata.mgt, + org.wso2.carbon.device.mgt.common.exceptions, + org.wso2.carbon.device.mgt.common.permission.mgt, + org.wso2.carbon.device.mgt.common.roles.config, org.wso2.carbon.device.mgt.core.metadata.mgt, + org.wso2.carbon.device.mgt.core.config, org.wso2.carbon.user.core.service, org.wso2.carbon.context diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtServiceComponent.java b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtServiceComponent.java index ac2b0be69bb..534c50c59d2 100644 --- a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtServiceComponent.java +++ b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtServiceComponent.java @@ -9,6 +9,7 @@ import org.apache.commons.logging.LogFactory; import org.osgi.service.component.ComponentContext; import org.wso2.carbon.device.mgt.common.metadata.mgt.WhiteLabelManagementService; import org.wso2.carbon.device.mgt.core.metadata.mgt.WhiteLabelManagementServiceImpl; +import org.wso2.carbon.stratos.common.listeners.TenantMgtListener; import org.wso2.carbon.user.core.service.RealmService; /** @@ -27,6 +28,7 @@ import org.wso2.carbon.user.core.service.RealmService; * unbind="unsetRealmService" */ +@SuppressWarnings("unused") public class TenantMgtServiceComponent { private static final Log log = LogFactory.getLog(TenantManagerService.class); @@ -43,7 +45,7 @@ public class TenantMgtServiceComponent { TenantMgtDataHolder.getInstance().setWhiteLabelManagementService(whiteLabelManagementService); DeviceMgtTenantListener deviceMgtTenantListener = new DeviceMgtTenantListener(); componentContext.getBundleContext(). - registerService(DeviceMgtTenantListener.class.getName(), deviceMgtTenantListener, null); + registerService(TenantMgtListener.class.getName(), deviceMgtTenantListener, null); log.info("Tenant management service activated"); } catch (Throwable t) { String msg = "Error occurred while activating tenant management service"; From 4c2a02fdf03a3cb352611af039dd645f0d726d93 Mon Sep 17 00:00:00 2001 From: rajitha Date: Tue, 18 Apr 2023 15:40:28 +0530 Subject: [PATCH 03/10] Add license --- .../io.entgra.tenant.mgt.common/pom.xml | 17 +++++++++++++++++ .../common/exception/TenantMgtException.java | 17 +++++++++++++++++ .../mgt/common/spi/TenantManagerService.java | 17 +++++++++++++++++ .../io.entgra.tenant.mgt.core/pom.xml | 17 +++++++++++++++++ .../entgra/tenant/mgt/core/TenantManager.java | 17 +++++++++++++++++ .../tenant/mgt/core/impl/TenantManagerImpl.java | 17 +++++++++++++++++ .../mgt/core/impl/TenantManagerServiceImpl.java | 17 +++++++++++++++++ .../mgt/core/internal/TenantMgtDataHolder.java | 17 +++++++++++++++++ .../internal/TenantMgtServiceComponent.java | 17 +++++++++++++++++ components/tenant-mgt/pom.xml | 17 +++++++++++++++++ .../io.entgra.tenant.mgt.server.feature/pom.xml | 17 +++++++++++++++++ features/tenant-mgt/pom.xml | 17 +++++++++++++++++ 12 files changed, 204 insertions(+) diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.common/pom.xml b/components/tenant-mgt/io.entgra.tenant.mgt.common/pom.xml index 2c81fb58c6c..b69c2bb112d 100644 --- a/components/tenant-mgt/io.entgra.tenant.mgt.common/pom.xml +++ b/components/tenant-mgt/io.entgra.tenant.mgt.common/pom.xml @@ -1,4 +1,21 @@ + diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.common/src/main/java/io/entgra/tenant/mgt/common/exception/TenantMgtException.java b/components/tenant-mgt/io.entgra.tenant.mgt.common/src/main/java/io/entgra/tenant/mgt/common/exception/TenantMgtException.java index c0e278bd2b3..f9b8c22e629 100644 --- a/components/tenant-mgt/io.entgra.tenant.mgt.common/src/main/java/io/entgra/tenant/mgt/common/exception/TenantMgtException.java +++ b/components/tenant-mgt/io.entgra.tenant.mgt.common/src/main/java/io/entgra/tenant/mgt/common/exception/TenantMgtException.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) 2023, Entgra Pvt Ltd. (http://www.wso2.org) 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.tenant.mgt.common.exception; public class TenantMgtException extends Exception { diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.common/src/main/java/io/entgra/tenant/mgt/common/spi/TenantManagerService.java b/components/tenant-mgt/io.entgra.tenant.mgt.common/src/main/java/io/entgra/tenant/mgt/common/spi/TenantManagerService.java index a721e030298..472b1b7cb18 100644 --- a/components/tenant-mgt/io.entgra.tenant.mgt.common/src/main/java/io/entgra/tenant/mgt/common/spi/TenantManagerService.java +++ b/components/tenant-mgt/io.entgra.tenant.mgt.common/src/main/java/io/entgra/tenant/mgt/common/spi/TenantManagerService.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) 2023, Entgra Pvt Ltd. (http://www.wso2.org) 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.tenant.mgt.common.spi; import io.entgra.tenant.mgt.common.exception.TenantMgtException; diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.core/pom.xml b/components/tenant-mgt/io.entgra.tenant.mgt.core/pom.xml index 5ec9904eb3d..a91e831ed5e 100644 --- a/components/tenant-mgt/io.entgra.tenant.mgt.core/pom.xml +++ b/components/tenant-mgt/io.entgra.tenant.mgt.core/pom.xml @@ -1,4 +1,21 @@ + diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/TenantManager.java b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/TenantManager.java index 2f9b63281b3..6919f520c4f 100644 --- a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/TenantManager.java +++ b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/TenantManager.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) 2023, Entgra Pvt Ltd. (http://www.wso2.org) 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.tenant.mgt.core; import io.entgra.tenant.mgt.common.exception.TenantMgtException; diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/impl/TenantManagerImpl.java b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/impl/TenantManagerImpl.java index 8782f7ca1ae..fe5b16f2f38 100644 --- a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/impl/TenantManagerImpl.java +++ b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/impl/TenantManagerImpl.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) 2023, Entgra Pvt Ltd. (http://www.wso2.org) 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.tenant.mgt.core.impl; import io.entgra.application.mgt.common.exception.ApplicationManagementException; diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/impl/TenantManagerServiceImpl.java b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/impl/TenantManagerServiceImpl.java index 760e49f4e85..b8a82be1da0 100644 --- a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/impl/TenantManagerServiceImpl.java +++ b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/impl/TenantManagerServiceImpl.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) 2023, Entgra Pvt Ltd. (http://www.wso2.org) 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.tenant.mgt.core.impl; import io.entgra.tenant.mgt.common.spi.TenantManagerService; diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtDataHolder.java b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtDataHolder.java index 6f9d603a3ff..d28862d4106 100644 --- a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtDataHolder.java +++ b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtDataHolder.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) 2023, Entgra Pvt Ltd. (http://www.wso2.org) 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.tenant.mgt.core.internal; import io.entgra.application.mgt.common.services.ApplicationManager; diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtServiceComponent.java b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtServiceComponent.java index 534c50c59d2..0f4480e1b90 100644 --- a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtServiceComponent.java +++ b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtServiceComponent.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) 2023, Entgra Pvt Ltd. (http://www.wso2.org) 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.tenant.mgt.core.internal; import io.entgra.application.mgt.common.services.ApplicationManager; diff --git a/components/tenant-mgt/pom.xml b/components/tenant-mgt/pom.xml index 58b3ebceb00..7d13f340c8b 100644 --- a/components/tenant-mgt/pom.xml +++ b/components/tenant-mgt/pom.xml @@ -1,4 +1,21 @@ + diff --git a/features/tenant-mgt/io.entgra.tenant.mgt.server.feature/pom.xml b/features/tenant-mgt/io.entgra.tenant.mgt.server.feature/pom.xml index 04cf1bb3e55..87e3214a433 100644 --- a/features/tenant-mgt/io.entgra.tenant.mgt.server.feature/pom.xml +++ b/features/tenant-mgt/io.entgra.tenant.mgt.server.feature/pom.xml @@ -1,4 +1,21 @@ + diff --git a/features/tenant-mgt/pom.xml b/features/tenant-mgt/pom.xml index d55378a8cbf..44befb42404 100644 --- a/features/tenant-mgt/pom.xml +++ b/features/tenant-mgt/pom.xml @@ -1,4 +1,21 @@ + From 9c9c391fd4d1268e9464a3647c91c57e2455b4d0 Mon Sep 17 00:00:00 2001 From: rajitha Date: Tue, 18 Apr 2023 15:51:02 +0530 Subject: [PATCH 04/10] Code refactor --- .../common/exception/TenantMgtException.java | 3 +++ .../internal/TenantMgtServiceComponent.java | 19 ++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.common/src/main/java/io/entgra/tenant/mgt/common/exception/TenantMgtException.java b/components/tenant-mgt/io.entgra.tenant.mgt.common/src/main/java/io/entgra/tenant/mgt/common/exception/TenantMgtException.java index f9b8c22e629..1470f07f63d 100644 --- a/components/tenant-mgt/io.entgra.tenant.mgt.common/src/main/java/io/entgra/tenant/mgt/common/exception/TenantMgtException.java +++ b/components/tenant-mgt/io.entgra.tenant.mgt.common/src/main/java/io/entgra/tenant/mgt/common/exception/TenantMgtException.java @@ -18,6 +18,9 @@ package io.entgra.tenant.mgt.common.exception; public class TenantMgtException extends Exception { + + private static final long serialVersionUID = 4304028531230841553L; + public TenantMgtException(String msg, Throwable ex) { super(msg, ex); } diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtServiceComponent.java b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtServiceComponent.java index 0f4480e1b90..fafdbbbea75 100644 --- a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtServiceComponent.java +++ b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtServiceComponent.java @@ -61,9 +61,14 @@ public class TenantMgtServiceComponent { whiteLabelManagementService, null); TenantMgtDataHolder.getInstance().setWhiteLabelManagementService(whiteLabelManagementService); DeviceMgtTenantListener deviceMgtTenantListener = new DeviceMgtTenantListener(); + if(log.isDebugEnabled()) { + log.info("Tenant management listener is registering"); + } componentContext.getBundleContext(). registerService(TenantMgtListener.class.getName(), deviceMgtTenantListener, null); - log.info("Tenant management service activated"); + if(log.isDebugEnabled()) { + log.info("Tenant management service activated"); + } } catch (Throwable t) { String msg = "Error occurred while activating tenant management service"; log.error(msg, t); @@ -76,18 +81,30 @@ public class TenantMgtServiceComponent { } protected void setApplicationManager(ApplicationManager applicationManager) { + if(log.isDebugEnabled()) { + log.info("Application manager service is binding"); + } TenantMgtDataHolder.getInstance().setApplicationManager(applicationManager); } protected void unsetApplicationManager(ApplicationManager applicationManager) { + if(log.isDebugEnabled()) { + log.info("Application manager service is unbinding"); + } TenantMgtDataHolder.getInstance().setApplicationManager(null); } protected void setRealmService(RealmService realmService) { + if(log.isDebugEnabled()) { + log.info("Realm Service service is binding"); + } TenantMgtDataHolder.getInstance().setRealmService(realmService); } protected void unsetRealmService(RealmService realmService) { + if(log.isDebugEnabled()) { + log.info("Realm Service service is unbinding"); + } TenantMgtDataHolder.getInstance().setRealmService(null); } } From a668d3e364a61f275e756b417ea23907d0cf61b6 Mon Sep 17 00:00:00 2001 From: Pahansith Gunathilake Date: Wed, 19 Apr 2023 06:46:09 +0000 Subject: [PATCH 05/10] Fix issue with Nginx not recognizing the SCEP client certificate (#105) Co-authored-by: Pahansith Reviewed-on: https://repository.entgra.net/community/device-mgt-core/pulls/105 Co-authored-by: Pahansith Gunathilake Co-committed-by: Pahansith Gunathilake --- .../mgt/core/impl/CertificateGenerator.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/impl/CertificateGenerator.java b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/impl/CertificateGenerator.java index 20b4833d562..d686ff51158 100755 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/impl/CertificateGenerator.java +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.core/src/main/java/org/wso2/carbon/certificate/mgt/core/impl/CertificateGenerator.java @@ -97,10 +97,7 @@ import java.security.cert.CertificateNotYetValidException; import java.security.cert.X509Certificate; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.List; +import java.util.*; import java.util.concurrent.TimeUnit; public class CertificateGenerator { @@ -798,8 +795,16 @@ public class CertificateGenerator { BigInteger serialNumber = BigInteger.valueOf(System.currentTimeMillis()); - X500Name issuerName = new X500Name(certCA.getSubjectDN().getName()); - + //Reversing the order of components of the subject DN due to Nginx not verifying the client certificate + //generated by Java using this subject DN. + //Ref: https://stackoverflow.com/questions/33769978 & engineering mail SCEP implementation for Android + String[] dnParts = certCA.getSubjectDN().getName().split(","); + StringJoiner joiner = new StringJoiner(","); + for (int i = (dnParts.length - 1); i >= 0; i--) { + joiner.add(dnParts[i]); + } + String subjectDn = joiner.toString(); + X500Name issuerName = new X500Name(subjectDn); String commonName = certificationRequest.getSubject().getRDNs(BCStyle.CN)[0].getFirst() .getValue().toString(); X500Name subjectName = new X500Name("O=" + commonName + "O=AndroidDevice,CN=" + From e383f3b456474b25ece6bf248c42ae78f6e43056 Mon Sep 17 00:00:00 2001 From: rajitha Date: Wed, 19 Apr 2023 14:14:44 +0530 Subject: [PATCH 06/10] Refactor code --- .../DeviceManagementServiceComponent.java | 5 - .../core/util/DeviceMgtTenantMgtListener.java | 155 ------------------ .../entgra/tenant/mgt/core/TenantManager.java | 12 ++ .../mgt/core/impl/TenantManagerImpl.java | 5 - .../core/impl/TenantManagerServiceImpl.java | 12 +- .../internal/TenantMgtServiceComponent.java | 4 + .../listener/DeviceMgtTenantListener.java | 19 ++- 7 files changed, 36 insertions(+), 176 deletions(-) delete mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceMgtTenantMgtListener.java diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementServiceComponent.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementServiceComponent.java index 180730dd6cb..0d24f1125c3 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementServiceComponent.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/internal/DeviceManagementServiceComponent.java @@ -86,11 +86,9 @@ import org.wso2.carbon.device.mgt.core.traccar.api.service.DeviceAPIClientServic import org.wso2.carbon.device.mgt.core.traccar.api.service.impl.DeviceAPIClientServiceImpl; import org.wso2.carbon.device.mgt.core.util.DeviceManagementSchemaInitializer; import org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil; -import org.wso2.carbon.device.mgt.core.util.DeviceMgtTenantMgtListener; import org.wso2.carbon.email.sender.core.service.EmailSenderService; import org.wso2.carbon.ndatasource.core.DataSourceService; import org.wso2.carbon.registry.core.service.RegistryService; -import org.wso2.carbon.stratos.common.listeners.TenantMgtListener; import org.wso2.carbon.user.core.service.RealmService; import org.wso2.carbon.utils.Axis2ConfigurationContextObserver; import org.wso2.carbon.utils.ConfigurationContextService; @@ -271,9 +269,6 @@ public class DeviceManagementServiceComponent { componentContext.getBundleContext().registerService(PrivacyComplianceProvider.class.getName(), privacyComplianceProvider, null); -// componentContext.getBundleContext() -// .registerService(TenantMgtListener.class.getName(), new DeviceMgtTenantMgtListener(), null); - if (log.isDebugEnabled()) { log.debug("Device management core bundle has been successfully initialized"); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceMgtTenantMgtListener.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceMgtTenantMgtListener.java deleted file mode 100644 index 79f58e82a17..00000000000 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/util/DeviceMgtTenantMgtListener.java +++ /dev/null @@ -1,155 +0,0 @@ -/* Copyright (c) 2020, 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.util; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.context.PrivilegedCarbonContext; -import org.wso2.carbon.device.mgt.common.exceptions.MetadataManagementException; -import org.wso2.carbon.device.mgt.common.permission.mgt.PermissionManagementException; -import org.wso2.carbon.device.mgt.common.roles.config.Role; -import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager; -import org.wso2.carbon.device.mgt.core.config.DeviceManagementConfig; -import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder; -import org.wso2.carbon.device.mgt.core.permission.mgt.PermissionUtils; -import org.wso2.carbon.registry.core.exceptions.RegistryException; -import org.wso2.carbon.stratos.common.beans.TenantInfoBean; -import org.wso2.carbon.stratos.common.listeners.TenantMgtListener; -import org.wso2.carbon.user.api.Permission; -import org.wso2.carbon.user.api.UserStoreException; -import org.wso2.carbon.user.api.UserStoreManager; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class DeviceMgtTenantMgtListener implements TenantMgtListener { - private static final Log log = LogFactory.getLog(DeviceMgtTenantMgtListener.class); - private static final int EXEC_ORDER = 10; - private static final String PERMISSION_ACTION = "ui.execute"; - - @Override - public void onTenantCreate(TenantInfoBean tenantInfoBean) { - DeviceManagementConfig config = DeviceConfigurationManager.getInstance().getDeviceManagementConfig(); - if (config.getDefaultRoles().isEnabled()) { - Map> roleMap = getValidRoleMap(config); - try { - PrivilegedCarbonContext.startTenantFlow(); - PrivilegedCarbonContext.getThreadLocalCarbonContext() - .setTenantDomain(tenantInfoBean.getTenantDomain(), true); - UserStoreManager userStoreManager = DeviceManagementDataHolder.getInstance().getRealmService() - .getTenantUserRealm(tenantInfoBean.getTenantId()).getUserStoreManager(); - - roleMap.forEach((key, value) -> { - try { - userStoreManager.addRole(key, null, value.toArray(new Permission[0])); - } catch (UserStoreException e) { - log.error("Error occurred while adding default roles into user store.", e); - } - }); - } catch (UserStoreException e) { - log.error("Error occurred while getting user store manager.", e); - } finally { - PrivilegedCarbonContext.endTenantFlow(); - } - } - try { - DeviceManagementDataHolder.getInstance().getWhiteLabelManagementService(). - addDefaultWhiteLabelThemeIfNotExist(tenantInfoBean.getTenantId()); - } catch (MetadataManagementException e) { - log.error("Error occurred while adding default white label theme to created tenant.", e); - } - } - - @Override - public void onTenantUpdate(TenantInfoBean tenantInfoBean) { - // doing nothing - } - - @Override - public void onTenantDelete(int i) { - // doing nothing - } - - @Override - public void onTenantRename(int i, String s, String s1) { - // doing nothing - } - - @Override - public void onTenantInitialActivation(int i) { - // doing nothing - } - - @Override - public void onTenantActivation(int i) { - // doing nothing - } - - @Override - public void onTenantDeactivation(int i) { - // doing nothing - } - - @Override - public void onSubscriptionPlanChange(int i, String s, String s1) { - // doing nothing - } - - @Override - public int getListenerOrder() { - return EXEC_ORDER; - } - - @Override - public void onPreDelete(int i) { - // doing nothing - } - - /** - * Use the default roles defined in the cdm-config and evaluate the defined permissions. If permissions does not - * exist then exclude them and return role map which contains defined roles in the cdm-config and existing - * permission list as a roleMap - * @param config cdm-config - * @return {@link Map} key is role name and value is list of permissions which needs to be assigned to the role - * defined in the key. - */ - private Map> getValidRoleMap(DeviceManagementConfig config) { - Map> roleMap = new HashMap<>(); - try { - for (Role role : config.getDefaultRoles().getRoles()) { - List permissionList = new ArrayList<>(); - for (String permissionPath : role.getPermissions()) { - if (PermissionUtils.checkResourceExists(permissionPath)) { - Permission permission = new Permission(permissionPath, PERMISSION_ACTION); - - permissionList.add(permission); - } else { - log.warn("Permission " + permissionPath + " does not exist. Hence it will not add to role " - + role.getName()); - } - } - roleMap.put(role.getName(), permissionList); - } - } catch (PermissionManagementException | RegistryException e) { - log.error("Error occurred while checking permission existence.", e); - } - return roleMap; - } -} diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/TenantManager.java b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/TenantManager.java index 6919f520c4f..ab9b8b22900 100644 --- a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/TenantManager.java +++ b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/TenantManager.java @@ -21,7 +21,19 @@ import io.entgra.tenant.mgt.common.exception.TenantMgtException; import org.wso2.carbon.stratos.common.beans.TenantInfoBean; public interface TenantManager { + + /** + * Add default roles to a tenant described by the tenant info bean + * @param tenantInfoBean The info bean that provides tenant info + * @throws TenantMgtException Throws when error occurred while adding + * a role into user store or adding default white label theme to created tenant + */ void addDefaultRoles(TenantInfoBean tenantInfoBean) throws TenantMgtException; + /** + * Add default application categories to a tenant described by the tenant info bean + * @param tenantInfoBean The info bean that provides tenant info + * @throws TenantMgtException Throws when error occurred while adding default application categories + */ void addDefaultAppCategories(TenantInfoBean tenantInfoBean) throws TenantMgtException; } diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/impl/TenantManagerImpl.java b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/impl/TenantManagerImpl.java index fe5b16f2f38..4089b4bffaf 100644 --- a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/impl/TenantManagerImpl.java +++ b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/impl/TenantManagerImpl.java @@ -18,7 +18,6 @@ package io.entgra.tenant.mgt.core.impl; import io.entgra.application.mgt.common.exception.ApplicationManagementException; -import io.entgra.application.mgt.common.exception.InvalidConfigurationException; import io.entgra.application.mgt.core.config.ConfigurationManager; import io.entgra.application.mgt.common.services.ApplicationManager; import io.entgra.tenant.mgt.core.TenantManager; @@ -90,9 +89,6 @@ public class TenantManagerImpl implements TenantManager { ApplicationManager applicationManager = TenantMgtDataHolder.getInstance().getApplicationManager(); applicationManager .addApplicationCategories(ConfigurationManager.getInstance().getConfiguration().getAppCategories()); - } catch (InvalidConfigurationException e) { - String msg = "Error occurred while getting application manager"; - throw new TenantMgtException(msg, e); } catch (ApplicationManagementException e) { String msg = "Error occurred while getting default application categories"; log.error(msg, e); @@ -100,7 +96,6 @@ public class TenantManagerImpl implements TenantManager { } finally { endTenantFlow(); } - } private void initTenantFlow(TenantInfoBean tenantInfoBean) { diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/impl/TenantManagerServiceImpl.java b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/impl/TenantManagerServiceImpl.java index b8a82be1da0..e15d105fbf4 100644 --- a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/impl/TenantManagerServiceImpl.java +++ b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/impl/TenantManagerServiceImpl.java @@ -18,27 +18,19 @@ package io.entgra.tenant.mgt.core.impl; import io.entgra.tenant.mgt.common.spi.TenantManagerService; -import io.entgra.tenant.mgt.core.TenantManager; import io.entgra.tenant.mgt.common.exception.TenantMgtException; import io.entgra.tenant.mgt.core.internal.TenantMgtDataHolder; import org.wso2.carbon.stratos.common.beans.TenantInfoBean; public class TenantManagerServiceImpl implements TenantManagerService { - private final TenantManager tenantManager; - - public TenantManagerServiceImpl() { - tenantManager = new TenantManagerImpl(); - TenantMgtDataHolder.getInstance().setTenantManager(tenantManager); - } - @Override public void addDefaultRoles(TenantInfoBean tenantInfoBean) throws TenantMgtException { - tenantManager.addDefaultRoles(tenantInfoBean); + TenantMgtDataHolder.getInstance().getTenantManager().addDefaultRoles(tenantInfoBean); } @Override public void addDefaultAppCategories(TenantInfoBean tenantInfoBean) throws TenantMgtException { - tenantManager.addDefaultAppCategories(tenantInfoBean); + TenantMgtDataHolder.getInstance().getTenantManager().addDefaultAppCategories(tenantInfoBean); } } diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtServiceComponent.java b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtServiceComponent.java index fafdbbbea75..cab03921c06 100644 --- a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtServiceComponent.java +++ b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/internal/TenantMgtServiceComponent.java @@ -19,6 +19,8 @@ package io.entgra.tenant.mgt.core.internal; import io.entgra.application.mgt.common.services.ApplicationManager; import io.entgra.tenant.mgt.common.spi.TenantManagerService; +import io.entgra.tenant.mgt.core.TenantManager; +import io.entgra.tenant.mgt.core.impl.TenantManagerImpl; import io.entgra.tenant.mgt.core.impl.TenantManagerServiceImpl; import io.entgra.tenant.mgt.core.listener.DeviceMgtTenantListener; import org.apache.commons.logging.Log; @@ -56,6 +58,8 @@ public class TenantMgtServiceComponent { TenantManagerService tenantManagerService = new TenantManagerServiceImpl(); componentContext.getBundleContext(). registerService(TenantManagerServiceImpl.class.getName(), tenantManagerService, null); + TenantManager tenantManager = new TenantManagerImpl(); + TenantMgtDataHolder.getInstance().setTenantManager(tenantManager); WhiteLabelManagementService whiteLabelManagementService = new WhiteLabelManagementServiceImpl(); componentContext.getBundleContext().registerService(WhiteLabelManagementServiceImpl.class.getName(), whiteLabelManagementService, null); diff --git a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/listener/DeviceMgtTenantListener.java b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/listener/DeviceMgtTenantListener.java index 43e31cf4e08..a272585bf72 100644 --- a/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/listener/DeviceMgtTenantListener.java +++ b/components/tenant-mgt/io.entgra.tenant.mgt.core/src/main/java/io/entgra/tenant/mgt/core/listener/DeviceMgtTenantListener.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) 2023, Entgra Pvt Ltd. (http://www.wso2.org) 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.tenant.mgt.core.listener; import io.entgra.tenant.mgt.core.TenantManager; @@ -12,7 +29,7 @@ import org.wso2.carbon.stratos.common.listeners.TenantMgtListener; public class DeviceMgtTenantListener implements TenantMgtListener { private static final Log log = LogFactory.getLog(DeviceMgtTenantListener.class); - public static final int LISTENER_EXECUTION_ORDER = 11; + public static final int LISTENER_EXECUTION_ORDER = 10; @Override public void onTenantCreate(TenantInfoBean tenantInfoBean) { From 3b7544770d352b38977fa42726b90490a653203e Mon Sep 17 00:00:00 2001 From: Amalka Subasinghe Date: Fri, 21 Apr 2023 22:31:45 +0530 Subject: [PATCH 07/10] avoid replacing _ in device types --- .../mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java index 46a37b9f59c..cd657fb5749 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java @@ -826,8 +826,7 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { deviceConfig.setClientId(dcrResponse.getClientId()); deviceConfig.setClientSecret(dcrResponse.getClientSecret()); - StringBuilder scopes = new StringBuilder("device_" + type.replace(" ", "") - .replace("_", "") + "_" + id); + StringBuilder scopes = new StringBuilder("device_" + type.replace(" ", "") + "_" + id); for (String topic : mqttEventTopicStructure) { if (topic.contains("${deviceId}")) { topic = topic.replace("${deviceId}", id); From 290dcf61aec4681a8d47298af1cf3f9a21f95361 Mon Sep 17 00:00:00 2001 From: Amalka Subasinghe Date: Fri, 21 Apr 2023 22:36:45 +0530 Subject: [PATCH 08/10] change format of device scope --- .../mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java index cd657fb5749..f90c45e1066 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceManagementServiceImpl.java @@ -826,7 +826,7 @@ public class DeviceManagementServiceImpl implements DeviceManagementService { deviceConfig.setClientId(dcrResponse.getClientId()); deviceConfig.setClientSecret(dcrResponse.getClientSecret()); - StringBuilder scopes = new StringBuilder("device_" + type.replace(" ", "") + "_" + id); + StringBuilder scopes = new StringBuilder("device:" + type.replace(" ", "") + ":" + id); for (String topic : mqttEventTopicStructure) { if (topic.contains("${deviceId}")) { topic = topic.replace("${deviceId}", id); From 27cceecd33a2f28f726f3d8e39a88e5cc078ef34 Mon Sep 17 00:00:00 2001 From: Kavin Prathaban Date: Tue, 25 Apr 2023 07:50:37 +0000 Subject: [PATCH 09/10] Fix device enrolment using MSSQL as database (#72) ## Purpose * Fixes https://roadmap.entgra.net/issues/9859 ## Description * Fix device enrolment using MSSQL as database * Fix test case failures of database engine getting a null value Co-authored-by: prathabanKavin Co-authored-by: Pahansith Gunathilake Reviewed-on: https://repository.entgra.net/community/device-mgt-core/pulls/72 Co-authored-by: Kavin Prathaban Co-committed-by: Kavin Prathaban --- .../core/dao/DeviceManagementDAOFactory.java | 18 +- ...pl.java => AbstractEnrollmentDAOImpl.java} | 2 +- .../enrolment/GenericEnrollmentDAOImpl.java | 555 ++++++++++++++++++ .../enrolment/SQLServerEnrollmentDAOImpl.java | 554 +++++++++++++++++ .../dao/DeviceStatusPersistenceTests.java | 14 +- .../core/dao/EnrolmentPersistenceTests.java | 15 +- .../main/resources/dbscripts/cdm/mssql.sql | 16 + 7 files changed, 1157 insertions(+), 17 deletions(-) rename components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/{EnrollmentDAOImpl.java => AbstractEnrollmentDAOImpl.java} (99%) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/enrolment/GenericEnrollmentDAOImpl.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/enrolment/SQLServerEnrollmentDAOImpl.java diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceManagementDAOFactory.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceManagementDAOFactory.java index cbd7c697f4a..b6aadb113f6 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceManagementDAOFactory.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/DeviceManagementDAOFactory.java @@ -31,6 +31,8 @@ import org.wso2.carbon.device.mgt.core.dao.impl.device.GenericDeviceDAOImpl; import org.wso2.carbon.device.mgt.core.dao.impl.device.OracleDeviceDAOImpl; import org.wso2.carbon.device.mgt.core.dao.impl.device.PostgreSQLDeviceDAOImpl; import org.wso2.carbon.device.mgt.core.dao.impl.device.SQLServerDeviceDAOImpl; +import org.wso2.carbon.device.mgt.core.dao.impl.enrolment.GenericEnrollmentDAOImpl; +import org.wso2.carbon.device.mgt.core.dao.impl.enrolment.SQLServerEnrollmentDAOImpl; import org.wso2.carbon.device.mgt.core.dao.impl.tracker.TrackerDAOImpl; import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil; import org.wso2.carbon.device.mgt.core.device.details.mgt.dao.DeviceDetailsDAO; @@ -41,7 +43,6 @@ import org.wso2.carbon.device.mgt.core.privacy.dao.impl.PrivacyComplianceDAOImpl import javax.sql.DataSource; import java.sql.Connection; import java.sql.SQLException; -import java.sql.Timestamp; import java.util.Hashtable; import java.util.List; @@ -122,7 +123,20 @@ public class DeviceManagementDAOFactory { } public static EnrollmentDAO getEnrollmentDAO() { - return new EnrollmentDAOImpl(); + if (databaseEngine != null) { + switch (databaseEngine) { + case DeviceManagementConstants.DataBaseTypes.DB_TYPE_MSSQL: + return new SQLServerEnrollmentDAOImpl(); + case DeviceManagementConstants.DataBaseTypes.DB_TYPE_POSTGRESQL: + case DeviceManagementConstants.DataBaseTypes.DB_TYPE_ORACLE: + case DeviceManagementConstants.DataBaseTypes.DB_TYPE_H2: + case DeviceManagementConstants.DataBaseTypes.DB_TYPE_MYSQL: + return new GenericEnrollmentDAOImpl(); + default: + throw new UnsupportedDatabaseEngineException("Unsupported database engine : " + databaseEngine); + } + } + throw new IllegalStateException("Database engine has not initialized properly."); } public static TrackerDAO getTrackerDAO() { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/EnrollmentDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractEnrollmentDAOImpl.java similarity index 99% rename from components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/EnrollmentDAOImpl.java rename to components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractEnrollmentDAOImpl.java index 7b3e08cd509..a3757bc523d 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/EnrollmentDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractEnrollmentDAOImpl.java @@ -37,7 +37,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; -public class EnrollmentDAOImpl implements EnrollmentDAO { +public abstract class AbstractEnrollmentDAOImpl implements EnrollmentDAO { @Override public EnrolmentInfo addEnrollment(int deviceId, EnrolmentInfo enrolmentInfo, diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/enrolment/GenericEnrollmentDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/enrolment/GenericEnrollmentDAOImpl.java new file mode 100644 index 00000000000..041efbf285d --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/enrolment/GenericEnrollmentDAOImpl.java @@ -0,0 +1,555 @@ +/* + * Copyright (c) 2023, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.wso2.carbon.device.mgt.core.dao.impl.enrolment; + +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.DeviceManagementConstants; +import org.wso2.carbon.device.mgt.common.EnrolmentInfo; +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.AbstractEnrollmentDAOImpl; +import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil; + +import java.sql.*; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +public class GenericEnrollmentDAOImpl extends AbstractEnrollmentDAOImpl { + + @Override + public EnrolmentInfo addEnrollment(int deviceId, EnrolmentInfo enrolmentInfo, + int tenantId) throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + try { + conn = this.getConnection(); + String sql = "INSERT INTO DM_ENROLMENT(DEVICE_ID, OWNER, OWNERSHIP, STATUS, " + + "DATE_OF_ENROLMENT, DATE_OF_LAST_UPDATE, TENANT_ID) VALUES(?, ?, ?, ?, ?, ?, ?)"; + stmt = conn.prepareStatement(sql, new String[] {"id"}); + Timestamp enrollmentTime = new Timestamp(new Date().getTime()); + stmt.setInt(1, deviceId); + stmt.setString(2, enrolmentInfo.getOwner()); + stmt.setString(3, enrolmentInfo.getOwnership().toString()); + stmt.setString(4, enrolmentInfo.getStatus().toString()); + stmt.setTimestamp(5, enrollmentTime); + stmt.setTimestamp(6, enrollmentTime); + stmt.setInt(7, tenantId); + stmt.execute(); + + rs = stmt.getGeneratedKeys(); + if (rs.next()) { + int enrolmentId = rs.getInt(1); + enrolmentInfo.setId(enrolmentId); + enrolmentInfo.setDateOfEnrolment(enrollmentTime.getTime()); + enrolmentInfo.setDateOfLastUpdate(enrollmentTime.getTime()); + addDeviceStatus(enrolmentId, enrolmentInfo.getStatus()); + return enrolmentInfo; + } + return null; + } catch (SQLException e) { + e.printStackTrace(); + throw new DeviceManagementDAOException("Error occurred while adding enrolment configuration", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + } + + @Override + public int updateEnrollment(EnrolmentInfo enrolmentInfo, int tenantId) throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + try { + conn = this.getConnection(); + String sql = "UPDATE DM_ENROLMENT SET OWNERSHIP = ?, STATUS = ?, DATE_OF_LAST_UPDATE = ? " + + "WHERE ID = ? AND TENANT_ID = ?"; + stmt = conn.prepareStatement(sql); + stmt.setString(1, enrolmentInfo.getOwnership().toString()); + stmt.setString(2, enrolmentInfo.getStatus().toString()); + stmt.setTimestamp(3, new Timestamp(new Date().getTime())); + stmt.setInt(4, enrolmentInfo.getId()); + stmt.setInt(5, tenantId); + int updatedCount = stmt.executeUpdate(); + if (updatedCount == 1){ + addDeviceStatus(enrolmentInfo.getId(), enrolmentInfo.getStatus()); + } + return updatedCount; + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while updating enrolment configuration", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + } + + @Override + public boolean updateEnrollmentStatus(List enrolmentInfos) throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + boolean status = false; + int updateStatus = -1; + try { + conn = this.getConnection(); + String sql = "UPDATE DM_ENROLMENT SET STATUS = ? WHERE ID = ?"; + stmt = conn.prepareStatement(sql); + if (conn.getMetaData().supportsBatchUpdates()) { + for (EnrolmentInfo enrolmentInfo : enrolmentInfos) { + stmt.setString(1, enrolmentInfo.getStatus().toString()); + stmt.setInt(2, enrolmentInfo.getId()); + stmt.addBatch(); + } + updateStatus = stmt.executeBatch().length; + } else { + for (EnrolmentInfo enrolmentInfo : enrolmentInfos) { + stmt.setString(1, enrolmentInfo.getStatus().toString()); + stmt.setInt(2, enrolmentInfo.getId()); + updateStatus = stmt.executeUpdate(); + } + } + if (updateStatus > 0) { + status = true; + for (EnrolmentInfo enrolmentInfo : enrolmentInfos) { + addDeviceStatus(enrolmentInfo); + } + } + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while updating enrolment status of given device-list.", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + return status; + } + + @Override + public int removeEnrollment(int deviceId, String currentOwner, + int tenantId) throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + int status = -1; + try { + conn = this.getConnection(); + String sql = "DELETE FROM DM_ENROLMENT WHERE DEVICE_ID = ? AND OWNER = ? AND TENANT_ID = ?"; + stmt = conn.prepareStatement(sql, new String[] {"id"}); + stmt.setInt(1, deviceId); + stmt.setString(2, currentOwner); + stmt.setInt(3, tenantId); + stmt.executeUpdate(); + + rs = stmt.getGeneratedKeys(); + if (rs.next()) { + status = 1; + } + return status; + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while removing device enrolment", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + } + + private int getCountOfDevicesOfOwner(String owner, int tenantID) throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + int count = 0; + try { + conn = this.getConnection(); + String checkQuery = "SELECT COUNT(ID) AS COUNT FROM DM_ENROLMENT WHERE OWNER = ? AND TENANT_ID = ?"; + stmt = conn.prepareStatement(checkQuery); + stmt.setString(1, owner); + stmt.setInt(2, tenantID); + rs = stmt.executeQuery(); + if(rs.next()){ + count = rs.getInt("COUNT"); + } + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while trying to get device " + + "count of Owner : "+owner, e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + return count; + } + + @Override + public boolean setStatus(String currentOwner, EnrolmentInfo.Status status, + int tenantId) throws DeviceManagementDAOException { + return setStatusAllDevices(currentOwner, status, tenantId); + } + + @Override + public boolean setStatusAllDevices(String currentOwner, EnrolmentInfo.Status status, int tenantId) + throws DeviceManagementDAOException{ + Connection conn; + PreparedStatement stmt = null; + Timestamp updateTime = new Timestamp(new Date().getTime()); + if(getCountOfDevicesOfOwner(currentOwner, tenantId) > 0){ + try { + conn = this.getConnection(); + String sql = "UPDATE DM_ENROLMENT SET STATUS = ?, DATE_OF_LAST_UPDATE = ? WHERE OWNER = ? AND TENANT_ID = ?"; + stmt = conn.prepareStatement(sql); + stmt.setString(1, status.toString()); + stmt.setTimestamp(2, updateTime); + stmt.setString(3, currentOwner); + stmt.setInt(4, tenantId); + stmt.executeUpdate(); + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while setting the status of device enrolment", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, null); + } + return addDeviceStatus(currentOwner, status, tenantId); + } else { + return false; + } + } + + @Override + public boolean setStatus(int enrolmentID, EnrolmentInfo.Status status, int tenantId) throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + Timestamp updateTime = new Timestamp(new Date().getTime()); + try { + conn = this.getConnection(); + String sql = "UPDATE DM_ENROLMENT SET STATUS = ?, DATE_OF_LAST_UPDATE = ? WHERE ID = ? AND TENANT_ID = ?"; + stmt = conn.prepareStatement(sql); + stmt.setString(1, status.toString()); + stmt.setTimestamp(2, updateTime); + stmt.setInt(3, enrolmentID); + stmt.setInt(4, tenantId); + int updatedRowCount = stmt.executeUpdate(); + if (updatedRowCount != 1){ + throw new DeviceManagementDAOException("Error occurred while setting the status of device enrolment: "+ + updatedRowCount + " rows were updated instead of one row!!!"); + } + // save the device status history + addDeviceStatus(enrolmentID, status); + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while setting the status of device enrolment", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, null); + } + return true; + } + + private boolean addDeviceStatus(EnrolmentInfo config) throws DeviceManagementDAOException { + return addDeviceStatus(config.getId(), config.getStatus()); + } + + private boolean addDeviceStatus(String currentOwner, EnrolmentInfo.Status status, int tenantId) throws DeviceManagementDAOException { + Connection conn; + String changedBy = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + if (changedBy == null){ + changedBy = DeviceManagementConstants.MaintenanceProperties.MAINTENANCE_USER; + } + PreparedStatement stmt = null; + ResultSet rs = null; + List enrolmentInfoList = new ArrayList<>(); + try { + conn = this.getConnection(); + String sql = "SELECT ID, DEVICE_ID, OWNER, OWNERSHIP, STATUS, IS_TRANSFERRED, DATE_OF_ENROLMENT, " + + "DATE_OF_LAST_UPDATE, TENANT_ID FROM DM_ENROLMENT WHERE OWNER = ? AND TENANT_ID = ?"; + stmt = conn.prepareStatement(sql); + stmt.setString(1, currentOwner); + stmt.setInt(2, tenantId); + rs = stmt.executeQuery(); + while (rs.next()) { + int enrolmentId = rs.getInt("ID"); + int deviceId = rs.getInt("DEVICE_ID"); + enrolmentInfoList.add(new int[]{enrolmentId, deviceId}); + } + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + Timestamp updateTime = new Timestamp(new Date().getTime()); + sql = "INSERT INTO DM_DEVICE_STATUS (ENROLMENT_ID, DEVICE_ID, STATUS, UPDATE_TIME, CHANGED_BY) VALUES(?, ?, ?, ?, ?)"; + try (PreparedStatement ps = conn.prepareStatement(sql)) { + if (conn.getMetaData().supportsBatchUpdates()) { + for(int[] info: enrolmentInfoList){ + ps.setInt(1, info[0]); + ps.setInt(2, info[1]); + ps.setString(3, status.toString()); + ps.setTimestamp(4, updateTime); + ps.setString(5, changedBy); + ps.addBatch(); + } + int[] batchResult = ps.executeBatch(); + for (int i : batchResult) { + if (i == 0 || i == Statement.SUCCESS_NO_INFO || i == Statement.EXECUTE_FAILED) { + return false; + } + } + } else { + for(int[] info: enrolmentInfoList){ + ps.setInt(1, info[0]); + ps.setInt(2, info[1]); + ps.setString(3, status.toString()); + ps.setTimestamp(4, updateTime); + ps.setString(5, changedBy); + ps.execute(); + } + + } + } + + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the enrolments " + + "information of owner '" + currentOwner + "'", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + return true; + } + + private boolean addDeviceStatus(int enrolmentId, EnrolmentInfo.Status status) throws DeviceManagementDAOException { + Connection conn; + String changedBy = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + if (changedBy == null){ + changedBy = DeviceManagementConstants.MaintenanceProperties.MAINTENANCE_USER; + } + PreparedStatement stmt = null; + try { + conn = this.getConnection(); + // get the device id and last udpated status from the device status table + String sql = "SELECT DEVICE_ID, STATUS FROM DM_DEVICE_STATUS WHERE ENROLMENT_ID = ? ORDER BY UPDATE_TIME DESC LIMIT 1"; + stmt = conn.prepareStatement(sql); + stmt.setInt(1, enrolmentId); + ResultSet rs = stmt.executeQuery(); + int deviceId = -1; + EnrolmentInfo.Status previousStatus = null; + if (rs.next()) { + // if there is a record corresponding to the enrolment we save the status and the device id + previousStatus = EnrolmentInfo.Status.valueOf(rs.getString("STATUS")); + deviceId = rs.getInt("DEVICE_ID"); + } + DeviceManagementDAOUtil.cleanupResources(stmt, null); + // if there was no record for the enrolment or the previous status is not the same as the current status + // we'll add a record + if (previousStatus == null || previousStatus != status){ + if (deviceId == -1) { + // we need the device id in order to add a new record, therefore we get it from the enrolment table + sql = "SELECT DEVICE_ID FROM DM_ENROLMENT WHERE ID = ?"; + stmt = conn.prepareStatement(sql); + stmt.setInt(1, enrolmentId); + rs = stmt.executeQuery(); + if (rs.next()) { + deviceId = rs.getInt("DEVICE_ID"); + } else { + // if there were no records corresponding to the enrolment id this is a problem. i.e. enrolment + // id is invalid + throw new DeviceManagementDAOException("Error occurred while setting the status of device enrolment: no record for enrolment id " + enrolmentId); + } + DeviceManagementDAOUtil.cleanupResources(stmt, null); + } + + sql = "INSERT INTO DM_DEVICE_STATUS (ENROLMENT_ID, DEVICE_ID, STATUS, UPDATE_TIME, CHANGED_BY) VALUES(?, ?, ?, ?, ?)"; + stmt = conn.prepareStatement(sql); + Timestamp updateTime = new Timestamp(new Date().getTime()); + stmt.setInt(1, enrolmentId); + stmt.setInt(2, deviceId); + stmt.setString(3, status.toString()); + stmt.setTimestamp(4, updateTime); + stmt.setString(5, changedBy); + stmt.execute(); + } else { + // no need to update status since the last recorded status is the same as the current status + } + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while setting the status of device", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, null); + } + return true; + } + @Override + public EnrolmentInfo.Status getStatus(int deviceId, String currentOwner, + int tenantId) throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + EnrolmentInfo.Status status = null; + try { + conn = this.getConnection(); + String sql = "SELECT STATUS FROM DM_ENROLMENT WHERE DEVICE_ID = ? AND OWNER = ? AND TENANT_ID = ?"; + stmt = conn.prepareStatement(sql); + stmt.setInt(1, deviceId); + stmt.setString(2, currentOwner); + stmt.setInt(3, tenantId); + rs = stmt.executeQuery(); + if (rs.next()) { + status = EnrolmentInfo.Status.valueOf(rs.getString("STATUS")); + } + return status; + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while setting the status of device enrolment", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + } + + @Override + public EnrolmentInfo getEnrollment(int deviceId, String currentOwner, + int tenantId) throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + EnrolmentInfo enrolmentInfo = null; + try { + conn = this.getConnection(); + String sql = "SELECT ID, DEVICE_ID, OWNER, OWNERSHIP, STATUS, IS_TRANSFERRED, DATE_OF_ENROLMENT, " + + "DATE_OF_LAST_UPDATE, TENANT_ID FROM DM_ENROLMENT WHERE DEVICE_ID = ? AND OWNER = ? AND TENANT_ID = ?"; + stmt = conn.prepareStatement(sql); + stmt.setInt(1, deviceId); + stmt.setString(2, currentOwner); + stmt.setInt(3, tenantId); + rs = stmt.executeQuery(); + if (rs.next()) { + enrolmentInfo = this.loadEnrolment(rs); + } + return enrolmentInfo; + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the enrolment " + + "information of user '" + currentOwner + "' upon device '" + deviceId + "'", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + } + + @Override + public EnrolmentInfo getEnrollment(int deviceId, int tenantId) throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + EnrolmentInfo enrolmentInfo = null; + try { + conn = this.getConnection(); + String sql = "SELECT ID, DEVICE_ID, OWNER, OWNERSHIP, STATUS, IS_TRANSFERRED, DATE_OF_ENROLMENT, " + + "DATE_OF_LAST_UPDATE, TENANT_ID FROM DM_ENROLMENT WHERE DEVICE_ID = ? AND TENANT_ID = ? " + + "ORDER BY DATE_OF_LAST_UPDATE DESC"; + stmt = conn.prepareStatement(sql); + stmt.setInt(1, deviceId); + stmt.setInt(2, tenantId); + rs = stmt.executeQuery(); + if (rs.next()) { + enrolmentInfo = this.loadEnrolment(rs); + } + return enrolmentInfo; + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the enrolment " + + "information of device '" + deviceId + "'", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + } + + @Override + public List getEnrollmentsOfUser(int deviceId, String user, int tenantId) + throws DeviceManagementDAOException { + List enrolmentInfos = new ArrayList<>(); + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + EnrolmentInfo enrolmentInfo = null; + try { + conn = this.getConnection(); + String sql = "SELECT ID, DEVICE_ID, OWNER, OWNERSHIP, STATUS, IS_TRANSFERRED, DATE_OF_ENROLMENT, " + + "DATE_OF_LAST_UPDATE, TENANT_ID FROM DM_ENROLMENT WHERE DEVICE_ID = ? AND OWNER = ? AND TENANT_ID = ?"; + stmt = conn.prepareStatement(sql); + stmt.setInt(1, deviceId); + stmt.setString(2, user); + stmt.setInt(3, tenantId); + rs = stmt.executeQuery(); + while (rs.next()) { + enrolmentInfo = this.loadEnrolment(rs); + enrolmentInfos.add(enrolmentInfo); + } + return enrolmentInfos; + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the enrolments " + + "information of user '" + user + "' upon device '" + deviceId + "'", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + } + + @Override + public boolean updateOwnerOfEnrollment(List devices, String owner, int tenantId) + throws DeviceManagementDAOException { + try { + Connection conn = this.getConnection(); + boolean updateStatus = true; + String sql = "UPDATE DM_ENROLMENT " + + "SET OWNER = ?, IS_TRANSFERRED = ?, DATE_OF_LAST_UPDATE = ? " + + "WHERE ID = ? AND TENANT_ID = ?"; + try (PreparedStatement ps = conn.prepareStatement(sql)) { + if (conn.getMetaData().supportsBatchUpdates()) { + for (Device device : devices) { + ps.setString(1, owner); + ps.setBoolean(2, device.getEnrolmentInfo().isTransferred()); + ps.setTimestamp(3, new Timestamp(new Date().getTime())); + ps.setInt(4, device.getEnrolmentInfo().getId()); + ps.setInt(5, tenantId); + ps.addBatch(); + } + int[] batchResult = ps.executeBatch(); + for (int i : batchResult) { + if (i == 0 || i == Statement.SUCCESS_NO_INFO || i == Statement.EXECUTE_FAILED) { + updateStatus = false; + break; + } + } + } else { + for (Device device : devices) { + ps.setString(1, owner); + ps.setBoolean(2, device.getEnrolmentInfo().isTransferred()); + ps.setInt(3, device.getId()); + ps.setInt(4, tenantId); + if (ps.executeUpdate() == 0) { + updateStatus = false; + break; + } + } + } + } + return updateStatus; + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while obtaining the DB connection to update the " + + "owner of the device enrollment.", e); + } + } + + private Connection getConnection() throws SQLException { + return DeviceManagementDAOFactory.getConnection(); + } + + private EnrolmentInfo loadEnrolment(ResultSet rs) throws SQLException { + EnrolmentInfo enrolmentInfo = new EnrolmentInfo(); + enrolmentInfo.setOwner(rs.getString("OWNER")); + enrolmentInfo.setOwnership(EnrolmentInfo.OwnerShip.valueOf(rs.getString("OWNERSHIP"))); + enrolmentInfo.setTransferred(rs.getBoolean("IS_TRANSFERRED")); + enrolmentInfo.setDateOfEnrolment(rs.getTimestamp("DATE_OF_ENROLMENT").getTime()); + enrolmentInfo.setDateOfLastUpdate(rs.getTimestamp("DATE_OF_LAST_UPDATE").getTime()); + enrolmentInfo.setStatus(EnrolmentInfo.Status.valueOf(rs.getString("STATUS"))); + enrolmentInfo.setId(rs.getInt("ID")); + return enrolmentInfo; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/enrolment/SQLServerEnrollmentDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/enrolment/SQLServerEnrollmentDAOImpl.java new file mode 100644 index 00000000000..8041d07a598 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/enrolment/SQLServerEnrollmentDAOImpl.java @@ -0,0 +1,554 @@ +/* + * Copyright (c) 2023, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.wso2.carbon.device.mgt.core.dao.impl.enrolment; + +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.DeviceManagementConstants; +import org.wso2.carbon.device.mgt.common.EnrolmentInfo; +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.AbstractEnrollmentDAOImpl; +import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil; +import java.sql.*; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +public class SQLServerEnrollmentDAOImpl extends AbstractEnrollmentDAOImpl { + + @Override + public EnrolmentInfo addEnrollment(int deviceId, EnrolmentInfo enrolmentInfo, + int tenantId) throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + try { + conn = this.getConnection(); + String sql = "INSERT INTO DM_ENROLMENT(DEVICE_ID, OWNER, OWNERSHIP, STATUS, " + + "DATE_OF_ENROLMENT, DATE_OF_LAST_UPDATE, TENANT_ID) VALUES(?, ?, ?, ?, ?, ?, ?)"; + stmt = conn.prepareStatement(sql, new String[] {"id"}); + Timestamp enrollmentTime = new Timestamp(new Date().getTime()); + stmt.setInt(1, deviceId); + stmt.setString(2, enrolmentInfo.getOwner()); + stmt.setString(3, enrolmentInfo.getOwnership().toString()); + stmt.setString(4, enrolmentInfo.getStatus().toString()); + stmt.setTimestamp(5, enrollmentTime); + stmt.setTimestamp(6, enrollmentTime); + stmt.setInt(7, tenantId); + stmt.execute(); + + rs = stmt.getGeneratedKeys(); + if (rs.next()) { + int enrolmentId = rs.getInt(1); + enrolmentInfo.setId(enrolmentId); + enrolmentInfo.setDateOfEnrolment(enrollmentTime.getTime()); + enrolmentInfo.setDateOfLastUpdate(enrollmentTime.getTime()); + addDeviceStatus(enrolmentId, enrolmentInfo.getStatus()); + return enrolmentInfo; + } + return null; + } catch (SQLException e) { + e.printStackTrace(); + throw new DeviceManagementDAOException("Error occurred while adding enrolment configuration", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + } + + @Override + public int updateEnrollment(EnrolmentInfo enrolmentInfo, int tenantId) throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + try { + conn = this.getConnection(); + String sql = "UPDATE DM_ENROLMENT SET OWNERSHIP = ?, STATUS = ?, DATE_OF_LAST_UPDATE = ? " + + "WHERE ID = ? AND TENANT_ID = ?"; + stmt = conn.prepareStatement(sql); + stmt.setString(1, enrolmentInfo.getOwnership().toString()); + stmt.setString(2, enrolmentInfo.getStatus().toString()); + stmt.setTimestamp(3, new Timestamp(new Date().getTime())); + stmt.setInt(4, enrolmentInfo.getId()); + stmt.setInt(5, tenantId); + int updatedCount = stmt.executeUpdate(); + if (updatedCount == 1){ + addDeviceStatus(enrolmentInfo.getId(), enrolmentInfo.getStatus()); + } + return updatedCount; + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while updating enrolment configuration", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + } + + @Override + public boolean updateEnrollmentStatus(List enrolmentInfos) throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + boolean status = false; + int updateStatus = -1; + try { + conn = this.getConnection(); + String sql = "UPDATE DM_ENROLMENT SET STATUS = ? WHERE ID = ?"; + stmt = conn.prepareStatement(sql); + if (conn.getMetaData().supportsBatchUpdates()) { + for (EnrolmentInfo enrolmentInfo : enrolmentInfos) { + stmt.setString(1, enrolmentInfo.getStatus().toString()); + stmt.setInt(2, enrolmentInfo.getId()); + stmt.addBatch(); + } + updateStatus = stmt.executeBatch().length; + } else { + for (EnrolmentInfo enrolmentInfo : enrolmentInfos) { + stmt.setString(1, enrolmentInfo.getStatus().toString()); + stmt.setInt(2, enrolmentInfo.getId()); + updateStatus = stmt.executeUpdate(); + } + } + if (updateStatus > 0) { + status = true; + for (EnrolmentInfo enrolmentInfo : enrolmentInfos) { + addDeviceStatus(enrolmentInfo); + } + } + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while updating enrolment status of given device-list.", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + return status; + } + + @Override + public int removeEnrollment(int deviceId, String currentOwner, + int tenantId) throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + int status = -1; + try { + conn = this.getConnection(); + String sql = "DELETE FROM DM_ENROLMENT WHERE DEVICE_ID = ? AND OWNER = ? AND TENANT_ID = ?"; + stmt = conn.prepareStatement(sql, new String[] {"id"}); + stmt.setInt(1, deviceId); + stmt.setString(2, currentOwner); + stmt.setInt(3, tenantId); + stmt.executeUpdate(); + + rs = stmt.getGeneratedKeys(); + if (rs.next()) { + status = 1; + } + return status; + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while removing device enrolment", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + } + + private int getCountOfDevicesOfOwner(String owner, int tenantID) throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + int count = 0; + try { + conn = this.getConnection(); + String checkQuery = "SELECT COUNT(ID) AS COUNT FROM DM_ENROLMENT WHERE OWNER = ? AND TENANT_ID = ?"; + stmt = conn.prepareStatement(checkQuery); + stmt.setString(1, owner); + stmt.setInt(2, tenantID); + rs = stmt.executeQuery(); + if(rs.next()){ + count = rs.getInt("COUNT"); + } + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while trying to get device " + + "count of Owner : "+owner, e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + return count; + } + + @Override + public boolean setStatus(String currentOwner, EnrolmentInfo.Status status, + int tenantId) throws DeviceManagementDAOException { + return setStatusAllDevices(currentOwner, status, tenantId); + } + + @Override + public boolean setStatusAllDevices(String currentOwner, EnrolmentInfo.Status status, int tenantId) + throws DeviceManagementDAOException{ + Connection conn; + PreparedStatement stmt = null; + Timestamp updateTime = new Timestamp(new Date().getTime()); + if(getCountOfDevicesOfOwner(currentOwner, tenantId) > 0){ + try { + conn = this.getConnection(); + String sql = "UPDATE DM_ENROLMENT SET STATUS = ?, DATE_OF_LAST_UPDATE = ? WHERE OWNER = ? AND TENANT_ID = ?"; + stmt = conn.prepareStatement(sql); + stmt.setString(1, status.toString()); + stmt.setTimestamp(2, updateTime); + stmt.setString(3, currentOwner); + stmt.setInt(4, tenantId); + stmt.executeUpdate(); + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while setting the status of device enrolment", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, null); + } + return addDeviceStatus(currentOwner, status, tenantId); + } else { + return false; + } + } + + @Override + public boolean setStatus(int enrolmentID, EnrolmentInfo.Status status, int tenantId) throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + Timestamp updateTime = new Timestamp(new Date().getTime()); + try { + conn = this.getConnection(); + String sql = "UPDATE DM_ENROLMENT SET STATUS = ?, DATE_OF_LAST_UPDATE = ? WHERE ID = ? AND TENANT_ID = ?"; + stmt = conn.prepareStatement(sql); + stmt.setString(1, status.toString()); + stmt.setTimestamp(2, updateTime); + stmt.setInt(3, enrolmentID); + stmt.setInt(4, tenantId); + int updatedRowCount = stmt.executeUpdate(); + if (updatedRowCount != 1){ + throw new DeviceManagementDAOException("Error occurred while setting the status of device enrolment: "+ + updatedRowCount + " rows were updated instead of one row!!!"); + } + // save the device status history + addDeviceStatus(enrolmentID, status); + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while setting the status of device enrolment", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, null); + } + return true; + } + + private boolean addDeviceStatus(EnrolmentInfo config) throws DeviceManagementDAOException { + return addDeviceStatus(config.getId(), config.getStatus()); + } + + private boolean addDeviceStatus(String currentOwner, EnrolmentInfo.Status status, int tenantId) throws DeviceManagementDAOException { + Connection conn; + String changedBy = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + if (changedBy == null){ + changedBy = DeviceManagementConstants.MaintenanceProperties.MAINTENANCE_USER; + } + PreparedStatement stmt = null; + ResultSet rs = null; + List enrolmentInfoList = new ArrayList<>(); + try { + conn = this.getConnection(); + String sql = "SELECT ID, DEVICE_ID, OWNER, OWNERSHIP, STATUS, IS_TRANSFERRED, DATE_OF_ENROLMENT, " + + "DATE_OF_LAST_UPDATE, TENANT_ID FROM DM_ENROLMENT WHERE OWNER = ? AND TENANT_ID = ?"; + stmt = conn.prepareStatement(sql); + stmt.setString(1, currentOwner); + stmt.setInt(2, tenantId); + rs = stmt.executeQuery(); + while (rs.next()) { + int enrolmentId = rs.getInt("ID"); + int deviceId = rs.getInt("DEVICE_ID"); + enrolmentInfoList.add(new int[]{enrolmentId, deviceId}); + } + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + Timestamp updateTime = new Timestamp(new Date().getTime()); + sql = "INSERT INTO DM_DEVICE_STATUS (ENROLMENT_ID, DEVICE_ID, STATUS, UPDATE_TIME, CHANGED_BY) VALUES(?, ?, ?, ?, ?)"; + try (PreparedStatement ps = conn.prepareStatement(sql)) { + if (conn.getMetaData().supportsBatchUpdates()) { + for(int[] info: enrolmentInfoList){ + ps.setInt(1, info[0]); + ps.setInt(2, info[1]); + ps.setString(3, status.toString()); + ps.setTimestamp(4, updateTime); + ps.setString(5, changedBy); + ps.addBatch(); + } + int[] batchResult = ps.executeBatch(); + for (int i : batchResult) { + if (i == 0 || i == Statement.SUCCESS_NO_INFO || i == Statement.EXECUTE_FAILED) { + return false; + } + } + } else { + for(int[] info: enrolmentInfoList){ + ps.setInt(1, info[0]); + ps.setInt(2, info[1]); + ps.setString(3, status.toString()); + ps.setTimestamp(4, updateTime); + ps.setString(5, changedBy); + ps.execute(); + } + + } + } + + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the enrolments " + + "information of owner '" + currentOwner + "'", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + return true; + } + + private boolean addDeviceStatus(int enrolmentId, EnrolmentInfo.Status status) throws DeviceManagementDAOException { + Connection conn; + String changedBy = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername(); + if (changedBy == null){ + changedBy = DeviceManagementConstants.MaintenanceProperties.MAINTENANCE_USER; + } + PreparedStatement stmt = null; + try { + conn = this.getConnection(); + // get the device id and last udpated status from the device status table + String sql = "SELECT TOP 1 DEVICE_ID, STATUS FROM DM_DEVICE_STATUS WHERE ENROLMENT_ID = ? ORDER BY UPDATE_TIME DESC"; + stmt = conn.prepareStatement(sql); + stmt.setInt(1, enrolmentId); + ResultSet rs = stmt.executeQuery(); + int deviceId = -1; + EnrolmentInfo.Status previousStatus = null; + if (rs.next()) { + // if there is a record corresponding to the enrolment we save the status and the device id + previousStatus = EnrolmentInfo.Status.valueOf(rs.getString("STATUS")); + deviceId = rs.getInt("DEVICE_ID"); + } + DeviceManagementDAOUtil.cleanupResources(stmt, null); + // if there was no record for the enrolment or the previous status is not the same as the current status + // we'll add a record + if (previousStatus == null || previousStatus != status){ + if (deviceId == -1) { + // we need the device id in order to add a new record, therefore we get it from the enrolment table + sql = "SELECT DEVICE_ID FROM DM_ENROLMENT WHERE ID = ?"; + stmt = conn.prepareStatement(sql); + stmt.setInt(1, enrolmentId); + rs = stmt.executeQuery(); + if (rs.next()) { + deviceId = rs.getInt("DEVICE_ID"); + } else { + // if there were no records corresponding to the enrolment id this is a problem. i.e. enrolment + // id is invalid + throw new DeviceManagementDAOException("Error occurred while setting the status of device enrolment: no record for enrolment id " + enrolmentId); + } + DeviceManagementDAOUtil.cleanupResources(stmt, null); + } + + sql = "INSERT INTO DM_DEVICE_STATUS (ENROLMENT_ID, DEVICE_ID, STATUS, UPDATE_TIME, CHANGED_BY) VALUES(?, ?, ?, ?, ?)"; + stmt = conn.prepareStatement(sql); + Timestamp updateTime = new Timestamp(new Date().getTime()); + stmt.setInt(1, enrolmentId); + stmt.setInt(2, deviceId); + stmt.setString(3, status.toString()); + stmt.setTimestamp(4, updateTime); + stmt.setString(5, changedBy); + stmt.execute(); + } else { + // no need to update status since the last recorded status is the same as the current status + } + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while setting the status of device", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, null); + } + return true; + } + @Override + public EnrolmentInfo.Status getStatus(int deviceId, String currentOwner, + int tenantId) throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + EnrolmentInfo.Status status = null; + try { + conn = this.getConnection(); + String sql = "SELECT STATUS FROM DM_ENROLMENT WHERE DEVICE_ID = ? AND OWNER = ? AND TENANT_ID = ?"; + stmt = conn.prepareStatement(sql); + stmt.setInt(1, deviceId); + stmt.setString(2, currentOwner); + stmt.setInt(3, tenantId); + rs = stmt.executeQuery(); + if (rs.next()) { + status = EnrolmentInfo.Status.valueOf(rs.getString("STATUS")); + } + return status; + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while setting the status of device enrolment", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + } + + @Override + public EnrolmentInfo getEnrollment(int deviceId, String currentOwner, + int tenantId) throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + EnrolmentInfo enrolmentInfo = null; + try { + conn = this.getConnection(); + String sql = "SELECT ID, DEVICE_ID, OWNER, OWNERSHIP, STATUS, IS_TRANSFERRED, DATE_OF_ENROLMENT, " + + "DATE_OF_LAST_UPDATE, TENANT_ID FROM DM_ENROLMENT WHERE DEVICE_ID = ? AND OWNER = ? AND TENANT_ID = ?"; + stmt = conn.prepareStatement(sql); + stmt.setInt(1, deviceId); + stmt.setString(2, currentOwner); + stmt.setInt(3, tenantId); + rs = stmt.executeQuery(); + if (rs.next()) { + enrolmentInfo = this.loadEnrolment(rs); + } + return enrolmentInfo; + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the enrolment " + + "information of user '" + currentOwner + "' upon device '" + deviceId + "'", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + } + + @Override + public EnrolmentInfo getEnrollment(int deviceId, int tenantId) throws DeviceManagementDAOException { + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + EnrolmentInfo enrolmentInfo = null; + try { + conn = this.getConnection(); + String sql = "SELECT ID, DEVICE_ID, OWNER, OWNERSHIP, STATUS, IS_TRANSFERRED, DATE_OF_ENROLMENT, " + + "DATE_OF_LAST_UPDATE, TENANT_ID FROM DM_ENROLMENT WHERE DEVICE_ID = ? AND TENANT_ID = ? " + + "ORDER BY DATE_OF_LAST_UPDATE DESC"; + stmt = conn.prepareStatement(sql); + stmt.setInt(1, deviceId); + stmt.setInt(2, tenantId); + rs = stmt.executeQuery(); + if (rs.next()) { + enrolmentInfo = this.loadEnrolment(rs); + } + return enrolmentInfo; + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the enrolment " + + "information of device '" + deviceId + "'", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + } + + @Override + public List getEnrollmentsOfUser(int deviceId, String user, int tenantId) + throws DeviceManagementDAOException { + List enrolmentInfos = new ArrayList<>(); + Connection conn; + PreparedStatement stmt = null; + ResultSet rs = null; + EnrolmentInfo enrolmentInfo = null; + try { + conn = this.getConnection(); + String sql = "SELECT ID, DEVICE_ID, OWNER, OWNERSHIP, STATUS, IS_TRANSFERRED, DATE_OF_ENROLMENT, " + + "DATE_OF_LAST_UPDATE, TENANT_ID FROM DM_ENROLMENT WHERE DEVICE_ID = ? AND OWNER = ? AND TENANT_ID = ?"; + stmt = conn.prepareStatement(sql); + stmt.setInt(1, deviceId); + stmt.setString(2, user); + stmt.setInt(3, tenantId); + rs = stmt.executeQuery(); + while (rs.next()) { + enrolmentInfo = this.loadEnrolment(rs); + enrolmentInfos.add(enrolmentInfo); + } + return enrolmentInfos; + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while retrieving the enrolments " + + "information of user '" + user + "' upon device '" + deviceId + "'", e); + } finally { + DeviceManagementDAOUtil.cleanupResources(stmt, rs); + } + } + + @Override + public boolean updateOwnerOfEnrollment(List devices, String owner, int tenantId) + throws DeviceManagementDAOException { + try { + Connection conn = this.getConnection(); + boolean updateStatus = true; + String sql = "UPDATE DM_ENROLMENT " + + "SET OWNER = ?, IS_TRANSFERRED = ?, DATE_OF_LAST_UPDATE = ? " + + "WHERE ID = ? AND TENANT_ID = ?"; + try (PreparedStatement ps = conn.prepareStatement(sql)) { + if (conn.getMetaData().supportsBatchUpdates()) { + for (Device device : devices) { + ps.setString(1, owner); + ps.setBoolean(2, device.getEnrolmentInfo().isTransferred()); + ps.setTimestamp(3, new Timestamp(new Date().getTime())); + ps.setInt(4, device.getEnrolmentInfo().getId()); + ps.setInt(5, tenantId); + ps.addBatch(); + } + int[] batchResult = ps.executeBatch(); + for (int i : batchResult) { + if (i == 0 || i == Statement.SUCCESS_NO_INFO || i == Statement.EXECUTE_FAILED) { + updateStatus = false; + break; + } + } + } else { + for (Device device : devices) { + ps.setString(1, owner); + ps.setBoolean(2, device.getEnrolmentInfo().isTransferred()); + ps.setInt(3, device.getId()); + ps.setInt(4, tenantId); + if (ps.executeUpdate() == 0) { + updateStatus = false; + break; + } + } + } + } + return updateStatus; + } catch (SQLException e) { + throw new DeviceManagementDAOException("Error occurred while obtaining the DB connection to update the " + + "owner of the device enrollment.", e); + } + } + + private Connection getConnection() throws SQLException { + return DeviceManagementDAOFactory.getConnection(); + } + + private EnrolmentInfo loadEnrolment(ResultSet rs) throws SQLException { + EnrolmentInfo enrolmentInfo = new EnrolmentInfo(); + enrolmentInfo.setOwner(rs.getString("OWNER")); + enrolmentInfo.setOwnership(EnrolmentInfo.OwnerShip.valueOf(rs.getString("OWNERSHIP"))); + enrolmentInfo.setTransferred(rs.getBoolean("IS_TRANSFERRED")); + enrolmentInfo.setDateOfEnrolment(rs.getTimestamp("DATE_OF_ENROLMENT").getTime()); + enrolmentInfo.setDateOfLastUpdate(rs.getTimestamp("DATE_OF_LAST_UPDATE").getTime()); + enrolmentInfo.setStatus(EnrolmentInfo.Status.valueOf(rs.getString("STATUS"))); + enrolmentInfo.setId(rs.getInt("ID")); + return enrolmentInfo; + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/dao/DeviceStatusPersistenceTests.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/dao/DeviceStatusPersistenceTests.java index 65c22e11613..b2a8903c7fb 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/dao/DeviceStatusPersistenceTests.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/dao/DeviceStatusPersistenceTests.java @@ -39,9 +39,15 @@ import static org.wso2.carbon.device.mgt.common.EnrolmentInfo.Status.*; public class DeviceStatusPersistenceTests extends BaseDeviceManagementTest { private static final Log log = LogFactory.getLog(DeviceStatusPersistenceTests.class); - private EnrollmentDAO enrollmentDAO = DeviceManagementDAOFactory.getEnrollmentDAO(); + EnrollmentDAO enrollmentDAO; private DeviceStatusDAO deviceStatusDAO = DeviceManagementDAOFactory.getDeviceStatusDAO(); + @BeforeClass + @Override + public void init() throws Exception { + enrollmentDAO = DeviceManagementDAOFactory.getEnrollmentDAO(); + } + /** * Validate that the list of statuses received match the statuses * @param device @@ -245,10 +251,4 @@ public class DeviceStatusPersistenceTests extends BaseDeviceManagementTest { } return false; } - - @BeforeClass - @Override - public void init() throws Exception { - - } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/dao/EnrolmentPersistenceTests.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/dao/EnrolmentPersistenceTests.java index 9497324798e..10bf0a1b641 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/dao/EnrolmentPersistenceTests.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/test/java/org/wso2/carbon/device/mgt/core/dao/EnrolmentPersistenceTests.java @@ -33,7 +33,14 @@ import java.sql.SQLException; public class EnrolmentPersistenceTests extends BaseDeviceManagementTest { private static final Log log = LogFactory.getLog(EnrolmentPersistenceTests.class); - private EnrollmentDAO enrollmentDAO = DeviceManagementDAOFactory.getEnrollmentDAO(); + EnrollmentDAO enrollmentDAO; + + @BeforeClass + @Override + public void init() throws Exception { + this.initDataSource(); + enrollmentDAO = DeviceManagementDAOFactory.getEnrollmentDAO(); + } @Test public void testAddEnrolment() { @@ -86,10 +93,4 @@ public class EnrolmentPersistenceTests extends BaseDeviceManagementTest { } return enrolmentInfo; } - - @BeforeClass - @Override - public void init() throws Exception { - this.initDataSource(); - } } diff --git a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql index d43294bd34e..c8b809ae48b 100644 --- a/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql +++ b/features/device-mgt/org.wso2.carbon.device.mgt.basics.feature/src/main/resources/dbscripts/cdm/mssql.sql @@ -10,6 +10,13 @@ CREATE TABLE DM_DEVICE_TYPE ( CONSTRAINT DEVICE_TYPE_NAME UNIQUE(NAME, PROVIDER_TENANT_ID) ); +IF NOT EXISTS (SELECT * FROM SYS.INDEXES WHERE NAME = 'IDX_DEVICE_TYPE' AND OBJECT_ID = OBJECT_ID('DM_DEVICE_TYPE')) +CREATE INDEX IDX_DEVICE_TYPE ON DM_DEVICE_TYPE (NAME, PROVIDER_TENANT_ID); +IF NOT EXISTS (SELECT * FROM SYS.INDEXES WHERE NAME = 'IDX_DEVICE_NAME' AND OBJECT_ID = OBJECT_ID('DM_DEVICE_TYPE')) +CREATE INDEX IDX_DEVICE_NAME ON DM_DEVICE_TYPE (NAME); +IF NOT EXISTS (SELECT * FROM SYS.INDEXES WHERE NAME = 'IDX_DEVICE_TYPE_DEVICE_NAME' AND OBJECT_ID = OBJECT_ID('DM_DEVICE_TYPE')) +CREATE INDEX IDX_DEVICE_TYPE_DEVICE_NAME ON DM_DEVICE_TYPE (ID, NAME); + IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[DM_DEVICE_CERTIFICATE]') AND TYPE IN (N'U')) CREATE TABLE DM_DEVICE_CERTIFICATE ( ID INTEGER IDENTITY(1,1) NOT NULL, @@ -165,6 +172,13 @@ CREATE TABLE DM_ENROLMENT_OP_MAPPING ( PUSH_NOTIFICATION_STATUS VARCHAR(50) NULL, CREATED_TIMESTAMP BIGINT NOT NULL, UPDATED_TIMESTAMP BIGINT NOT NULL, + OPERATION_CODE VARCHAR(50) NOT NULL, + INITIATED_BY VARCHAR(100) NULL, + TYPE VARCHAR(20) NOT NULL, + DEVICE_ID INTEGER DEFAULT NULL, + DEVICE_TYPE VARCHAR(300) NOT NULL, + DEVICE_IDENTIFICATION VARCHAR(300) DEFAULT NULL, + TENANT_ID INTEGER DEFAULT 0, PRIMARY KEY (ID), CONSTRAINT FK_DM_DEVICE_OPERATION_MAPPING_DEVICE FOREIGN KEY (ENROLMENT_ID) REFERENCES DM_ENROLMENT (ID) ON DELETE NO ACTION ON UPDATE NO ACTION, @@ -178,6 +192,8 @@ IF NOT EXISTS (SELECT * FROM SYS.INDEXES WHERE NAME = 'IDX_EN_OP_MAPPING_EN_ID' CREATE INDEX IDX_EN_OP_MAPPING_EN_ID ON DM_ENROLMENT_OP_MAPPING(ENROLMENT_ID); IF NOT EXISTS (SELECT * FROM SYS.INDEXES WHERE NAME = 'IDX_EN_OP_MAPPING_OP_ID' AND OBJECT_ID = OBJECT_ID('DM_ENROLMENT_OP_MAPPING')) CREATE INDEX IDX_EN_OP_MAPPING_OP_ID ON DM_ENROLMENT_OP_MAPPING(OPERATION_ID); +IF NOT EXISTS (SELECT * FROM SYS.INDEXES WHERE NAME = 'IDX_EN_OP_MAPPING_EN_ID_STATUS' AND OBJECT_ID = OBJECT_ID('DM_ENROLMENT_OP_MAPPING')) +CREATE INDEX IDX_EN_OP_MAPPING_EN_ID_STATUS ON DM_ENROLMENT_OP_MAPPING(ENROLMENT_ID, STATUS); IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[DM_DEVICE_OPERATION_RESPONSE]') AND TYPE IN (N'U')) CREATE TABLE DM_DEVICE_OPERATION_RESPONSE ( From 36bae5e3c197fb929ab427f968c7f78e6119bc50 Mon Sep 17 00:00:00 2001 From: Kavin Prathaban Date: Tue, 25 Apr 2023 07:54:05 +0000 Subject: [PATCH 10/10] Fix geofences not loading with MSSQL db (#75) ## Purpose * Fixes https://roadmap.entgra.net/issues/9987 ## Description * Fix geofences page not loading when starting the pack with MSSQL databases. Co-authored-by: prathabanKavin Co-authored-by: Pahansith Gunathilake Reviewed-on: https://repository.entgra.net/community/device-mgt-core/pulls/75 Co-authored-by: Kavin Prathaban Co-committed-by: Kavin Prathaban --- .../core/dao/EventManagementDAOFactory.java | 17 +- ...Impl.java => AbstractGeofenceDAOImpl.java} | 5 +- .../impl/geofence/GenericGeofenceDAOImpl.java | 637 ++++++++++++++++++ .../geofence/SQLServerGeofenceDAOImpl.java | 109 +++ 4 files changed, 764 insertions(+), 4 deletions(-) rename components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/{GeofenceDAOImpl.java => AbstractGeofenceDAOImpl.java} (99%) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/geofence/GenericGeofenceDAOImpl.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/geofence/SQLServerGeofenceDAOImpl.java diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/EventManagementDAOFactory.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/EventManagementDAOFactory.java index 754b5190041..09e5353fa61 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/EventManagementDAOFactory.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/EventManagementDAOFactory.java @@ -29,6 +29,8 @@ import org.wso2.carbon.device.mgt.core.config.datasource.JNDILookupDefinition; import org.wso2.carbon.device.mgt.core.dao.impl.*; import org.wso2.carbon.device.mgt.core.dao.impl.event.GenericEventConfigDAOImpl; import org.wso2.carbon.device.mgt.core.dao.impl.event.H2EventConfigDAOImpl; +import org.wso2.carbon.device.mgt.core.dao.impl.geofence.GenericGeofenceDAOImpl; +import org.wso2.carbon.device.mgt.core.dao.impl.geofence.SQLServerGeofenceDAOImpl; import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil; import javax.sql.DataSource; @@ -45,7 +47,20 @@ public class EventManagementDAOFactory { public static GeofenceDAO getGeofenceDAO() { - return new GeofenceDAOImpl(); + if (databaseEngine != null) { + switch (databaseEngine) { + case DeviceManagementConstants.DataBaseTypes.DB_TYPE_MSSQL: + return new SQLServerGeofenceDAOImpl(); + case DeviceManagementConstants.DataBaseTypes.DB_TYPE_POSTGRESQL: + case DeviceManagementConstants.DataBaseTypes.DB_TYPE_ORACLE: + case DeviceManagementConstants.DataBaseTypes.DB_TYPE_MYSQL: + case DeviceManagementConstants.DataBaseTypes.DB_TYPE_H2: + return new GenericGeofenceDAOImpl(); + default: + throw new UnsupportedDatabaseEngineException("Unsupported database engine : " + databaseEngine); + } + } + throw new IllegalStateException("Database engine has not initialized properly."); } public static EventConfigDAO getEventConfigDAO() { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/GeofenceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractGeofenceDAOImpl.java similarity index 99% rename from components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/GeofenceDAOImpl.java rename to components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractGeofenceDAOImpl.java index e845a43da92..4c8cd12e7e5 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/GeofenceDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/AbstractGeofenceDAOImpl.java @@ -25,7 +25,6 @@ import org.wso2.carbon.device.mgt.common.PaginationRequest; import org.wso2.carbon.device.mgt.common.event.config.EventConfig; import org.wso2.carbon.device.mgt.common.geo.service.GeofenceData; 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.EventManagementDAOFactory; import org.wso2.carbon.device.mgt.core.dao.GeofenceDAO; import org.wso2.carbon.device.mgt.core.dto.event.config.GeoFenceGroupMap; @@ -45,8 +44,8 @@ import java.util.List; import java.util.Map; import java.util.Set; -public class GeofenceDAOImpl implements GeofenceDAO { - private static final Log log = LogFactory.getLog(GeofenceDAOImpl.class); +public abstract class AbstractGeofenceDAOImpl implements GeofenceDAO { + private static final Log log = LogFactory.getLog(AbstractGeofenceDAOImpl.class); @Override public GeofenceData saveGeofence(GeofenceData geofenceData) throws DeviceManagementDAOException { try { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/geofence/GenericGeofenceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/geofence/GenericGeofenceDAOImpl.java new file mode 100644 index 00000000000..b7784a34800 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/geofence/GenericGeofenceDAOImpl.java @@ -0,0 +1,637 @@ +/* + * Copyright (c) 2020, 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.dao.impl.geofence; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.common.DeviceManagementConstants; +import org.wso2.carbon.device.mgt.common.PaginationRequest; +import org.wso2.carbon.device.mgt.common.event.config.EventConfig; +import org.wso2.carbon.device.mgt.common.geo.service.GeofenceData; +import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException; +import org.wso2.carbon.device.mgt.core.dao.EventManagementDAOFactory; +import org.wso2.carbon.device.mgt.core.dao.GeofenceDAO; +import org.wso2.carbon.device.mgt.core.dao.impl.AbstractGeofenceDAOImpl; +import org.wso2.carbon.device.mgt.core.dto.event.config.GeoFenceGroupMap; + +import java.sql.*; +import java.util.Date; +import java.util.*; + +public class GenericGeofenceDAOImpl extends AbstractGeofenceDAOImpl { + private static final Log log = LogFactory.getLog(GenericGeofenceDAOImpl.class); + @Override + public GeofenceData saveGeofence(GeofenceData geofenceData) throws DeviceManagementDAOException { + try { + Connection conn = this.getConnection(); + String sql = "INSERT INTO DM_GEOFENCE(" + + "FENCE_NAME, " + + "DESCRIPTION, " + + "LATITUDE, " + + "LONGITUDE, " + + "RADIUS, " + + "GEO_JSON, " + + "FENCE_SHAPE, " + + "CREATED_TIMESTAMP, " + + "OWNER, " + + "TENANT_ID) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + try (PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { + stmt.setString(1, geofenceData.getFenceName()); + stmt.setString(2, geofenceData.getDescription()); + stmt.setDouble(3, geofenceData.getLatitude()); + stmt.setDouble(4, geofenceData.getLongitude()); + stmt.setFloat(5, geofenceData.getRadius()); + stmt.setString(6, geofenceData.getGeoJson()); + stmt.setString(7, geofenceData.getFenceShape()); + stmt.setTimestamp(8, new Timestamp(new Date().getTime())); + stmt.setString(9, geofenceData.getOwner()); + stmt.setInt(10, geofenceData.getTenantId()); + if (stmt.executeUpdate() > 0) { + ResultSet generatedKeys = stmt.getGeneratedKeys(); + if (generatedKeys.next()) { + geofenceData.setId(generatedKeys.getInt(1)); + } + } + return geofenceData; + } + } catch (SQLException e) { + String msg = "Error occurred while creating Geofence for the tenant id "+geofenceData.getTenantId(); + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + @Override + public GeofenceData getGeofence(int fenceId) throws DeviceManagementDAOException { + try { + Connection conn = this.getConnection(); + GeofenceData geofenceData = null; + String sql = "SELECT " + + "ID, " + + "FENCE_NAME, " + + "DESCRIPTION, " + + "LATITUDE, " + + "LONGITUDE, " + + "RADIUS, " + + "GEO_JSON, " + + "FENCE_SHAPE, " + + "OWNER, " + + "TENANT_ID " + + "FROM DM_GEOFENCE " + + "WHERE ID = ?"; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, fenceId); + try (ResultSet rst = stmt.executeQuery()) { + List geofenceDataList = extractGeofenceData(rst); + if (!geofenceDataList.isEmpty()) { + geofenceData = geofenceDataList.get(0); + } + } + } + return geofenceData; + } catch (SQLException e) { + String msg = "Error occurred while retrieving Geofence with id "+fenceId; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + @Override + public List getGeoFencesOfTenant(PaginationRequest request, int tenantId) + throws DeviceManagementDAOException { + try { + Connection conn = this.getConnection(); + boolean isNameProvided = false; + List geofenceData; + String sql = "SELECT " + + "ID, " + + "FENCE_NAME, " + + "DESCRIPTION, " + + "LATITUDE, " + + "LONGITUDE, " + + "RADIUS, " + + "GEO_JSON, " + + "FENCE_SHAPE, " + + "OWNER, " + + "TENANT_ID " + + "FROM DM_GEOFENCE " + + "WHERE TENANT_ID = ? "; + + if (request.getProperty(DeviceManagementConstants.GeoServices.FENCE_NAME) != null) { + sql += "AND FENCE_NAME LIKE ?"; + isNameProvided = true; + } + sql += "LIMIT ? OFFSET ?"; + int index = 1; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(index++, tenantId); + if (isNameProvided) { + stmt.setString(index++, request.getProperty(DeviceManagementConstants.GeoServices.FENCE_NAME).toString() + "%"); + } + stmt.setInt(index++, request.getRowCount()); + stmt.setInt(index, request.getStartIndex()); + try (ResultSet rst = stmt.executeQuery()) { + geofenceData = extractGeofenceData(rst); + } + } + return geofenceData; + } catch (SQLException e) { + String msg = "Error occurred while retrieving Geofence of the tenant " + tenantId; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + @Override + public List getGeoFencesOfTenant(String fenceName, int tenantId) + throws DeviceManagementDAOException { + try { + Connection conn = this.getConnection(); + List geofenceData; + String sql = "SELECT " + + "ID, " + + "FENCE_NAME, " + + "DESCRIPTION, " + + "LATITUDE, " + + "LONGITUDE, " + + "RADIUS, " + + "GEO_JSON, " + + "FENCE_SHAPE, " + + "OWNER, " + + "TENANT_ID " + + "FROM DM_GEOFENCE " + + "WHERE FENCE_NAME LIKE ?" + + "AND TENANT_ID = ? "; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, fenceName + "%"); + stmt.setInt(2, tenantId); + try (ResultSet rst = stmt.executeQuery()) { + geofenceData = extractGeofenceData(rst); + } + } + return geofenceData; + } catch (SQLException e) { + String msg = "Error occurred while retrieving Geofence of the tenant " + tenantId; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + @Override + public List getGeoFencesOfTenant(int tenantId) + throws DeviceManagementDAOException { + try { + Connection conn = this.getConnection(); + List geofenceData; + String sql = "SELECT " + + "ID, " + + "FENCE_NAME, " + + "DESCRIPTION, " + + "LATITUDE, " + + "LONGITUDE, " + + "RADIUS, " + + "GEO_JSON, " + + "FENCE_SHAPE, " + + "OWNER, " + + "TENANT_ID " + + "FROM DM_GEOFENCE " + + "WHERE TENANT_ID = ? "; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, tenantId); + try (ResultSet rst = stmt.executeQuery()) { + geofenceData = extractGeofenceData(rst); + } + } + return geofenceData; + } catch (SQLException e) { + String msg = "Error occurred while retrieving Geofence of the tenant " + tenantId; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + @Override + public int deleteGeofenceById(int fenceId) throws DeviceManagementDAOException { + try { + Connection conn = this.getConnection(); + String sql = "DELETE FROM DM_GEOFENCE WHERE ID = ?"; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, fenceId); + return stmt.executeUpdate(); + } + } catch (SQLException e) { + String msg = "Error occurred while deleting Geofence with ID " + fenceId; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + @Override + public int updateGeofence(GeofenceData geofenceData, int fenceId) throws DeviceManagementDAOException { + try { + Connection conn = this.getConnection(); + String sql = "UPDATE DM_GEOFENCE SET " + + "FENCE_NAME = ?, " + + "DESCRIPTION = ?, " + + "LATITUDE = ?, " + + "LONGITUDE = ?, " + + "RADIUS = ?, " + + "GEO_JSON = ?, " + + "FENCE_SHAPE = ? " + + "WHERE ID = ?"; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, geofenceData.getFenceName()); + stmt.setString(2, geofenceData.getDescription()); + stmt.setDouble(3, geofenceData.getLatitude()); + stmt.setDouble(4, geofenceData.getLongitude()); + stmt.setFloat(5, geofenceData.getRadius()); + stmt.setString(6, geofenceData.getGeoJson()); + stmt.setString(7, geofenceData.getFenceShape()); + stmt.setInt(8, fenceId); + return stmt.executeUpdate(); + } + } catch (SQLException e) { + String msg = "Error occurred while updating Geofence record with id " + fenceId; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + @Override + public boolean createGeofenceGroupMapping(GeofenceData geofenceData, List groupIds) throws DeviceManagementDAOException { + try { + Connection conn = this.getConnection(); + String sql = "INSERT INTO DM_GEOFENCE_GROUP_MAPPING(" + + "FENCE_ID, " + + "GROUP_ID) " + + "VALUES (?, ?)"; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + for (Integer groupId : groupIds) { + stmt.setInt(1, geofenceData.getId()); + stmt.setInt(2, groupId); + stmt.addBatch(); + } + return stmt.executeBatch().length > 0; + } + } catch (SQLException e) { + String msg = "Error occurred while creating geofence group mapping records"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + private Connection getConnection() throws SQLException { + return EventManagementDAOFactory.getConnection(); + } + + private List extractGeofenceData(ResultSet rst) throws SQLException { + List geofenceDataList = new ArrayList<>(); + while (rst.next()) { + GeofenceData geofenceData = new GeofenceData(); + geofenceData.setId(rst.getInt("ID")); + geofenceData.setFenceName(rst.getString("FENCE_NAME")); + geofenceData.setDescription(rst.getString("DESCRIPTION")); + geofenceData.setLatitude(rst.getDouble("LATITUDE")); + geofenceData.setLongitude(rst.getDouble("LONGITUDE")); + geofenceData.setRadius(rst.getFloat("RADIUS")); + geofenceData.setGeoJson(rst.getString("GEO_JSON")); + geofenceData.setFenceShape(rst.getString("FENCE_SHAPE")); + geofenceData.setOwner(rst.getString("OWNER")); + geofenceData.setTenantId(rst.getInt("TENANT_ID")); + geofenceDataList.add(geofenceData); + } + return geofenceDataList; + } + + @Override + public List getGroupIdsOfGeoFence(int fenceId) throws DeviceManagementDAOException { + try { + Connection conn = this.getConnection(); + String sql = "SELECT " + + "GROUP_ID " + + "FROM DM_GEOFENCE_GROUP_MAPPING " + + "WHERE FENCE_ID = ? "; + List groupIds = new ArrayList<>(); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, fenceId); + try (ResultSet rst = stmt.executeQuery()) { + while (rst.next()) { + groupIds.add(rst.getInt(1)); + } + } + } + return groupIds; + } catch (SQLException e) { + String msg = "Error occurred while fetching group IDs of the fence " + fenceId; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + @Override + public void deleteGeofenceGroupMapping(List groupIdsToDelete, int fenceId) throws DeviceManagementDAOException { + try { + Connection conn = this.getConnection(); + String sql = "DELETE FROM DM_GEOFENCE_GROUP_MAPPING WHERE GROUP_ID = ? AND FENCE_ID = ?"; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + for (Integer groupId : groupIdsToDelete) { + stmt.setInt(1, groupId); + stmt.setInt(2, fenceId); + stmt.addBatch(); + } + stmt.executeBatch(); + } + } catch (SQLException e) { + String msg = "Error occurred while deleting Geofence group mapping records"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + @Override + public void createGeofenceEventMapping(int fenceId, List eventIds) throws DeviceManagementDAOException { + try { + Connection conn = this.getConnection(); + String sql = "INSERT INTO DM_GEOFENCE_EVENT_MAPPING(" + + "FENCE_ID, "+ + "EVENT_ID) " + + "VALUES (?, ?)"; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + for (Integer createdEventId : eventIds) { + stmt.setInt(1, fenceId); + stmt.setInt(2, createdEventId); + stmt.addBatch(); + } + stmt.executeBatch(); + } + } catch (SQLException e) { + String msg = "Error occurred while creating geofence event group mapping records"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + @Override + public void deleteGeofenceEventMapping(List removedEventIdList) throws DeviceManagementDAOException { + try { + Connection conn = this.getConnection(); + String sql = "DELETE FROM DM_GEOFENCE_EVENT_MAPPING WHERE EVENT_ID = ?"; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + for (Integer eventId : removedEventIdList) { + stmt.setInt(1, eventId); + stmt.addBatch(); + } + stmt.executeBatch(); + } + } catch (SQLException e) { + String msg = "Error occurred while deleting Geofence event mapping records"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + @Override + public Map> getEventsOfGeoFences(List geofenceIds) throws DeviceManagementDAOException { + try { + Map> geoFenceEventMap = new HashMap<>(); + if (geofenceIds.isEmpty()) { + return geoFenceEventMap; + } + Connection conn = this.getConnection(); + String sql = "SELECT " + + "E.ID AS EVENT_ID, " + + "M.FENCE_ID AS FENCE_ID, " + + "EVENT_SOURCE, " + + "EVENT_LOGIC, " + + "ACTIONS " + + "FROM DM_DEVICE_EVENT E, DM_GEOFENCE_EVENT_MAPPING M " + + "WHERE E.ID = M.EVENT_ID " + + "AND M.FENCE_ID IN (%s)"; + String inClause = String.join(", ", Collections.nCopies(geofenceIds.size(), "?")); + sql = String.format(sql, inClause); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + int index = 1; + for (Integer geofenceId : geofenceIds) { + stmt.setInt(index++, geofenceId); + } + ResultSet resultSet = stmt.executeQuery(); + while (resultSet.next()) { + int fenceId = resultSet.getInt("FENCE_ID"); + List eventConfigList = geoFenceEventMap.get(fenceId); + if (eventConfigList == null) { + eventConfigList = new ArrayList<>(); + } + EventConfig event = new EventConfig(); + event.setEventId(resultSet.getInt("EVENT_ID")); + event.setEventSource(resultSet.getString("EVENT_SOURCE")); + event.setEventLogic(resultSet.getString("EVENT_LOGIC")); + event.setActions(resultSet.getString("ACTIONS")); + eventConfigList.add(event); + geoFenceEventMap.put(fenceId, eventConfigList); + } + return geoFenceEventMap; + } + } catch (SQLException e) { + String msg = "Error occurred while updating Geofence record with id "; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + @Override + public List getEventsOfGeoFence(int geofenceId) throws DeviceManagementDAOException { + try { + List eventList = new ArrayList<>(); + Connection conn = this.getConnection(); + String sql = "SELECT " + + "E.ID AS EVENT_ID, " + + "EVENT_SOURCE, " + + "EVENT_LOGIC, " + + "ACTIONS " + + "FROM DM_DEVICE_EVENT E, DM_GEOFENCE_EVENT_MAPPING G " + + "WHERE E.ID = G.EVENT_ID " + + "AND G.FENCE_ID = ?"; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, geofenceId); + return getEventConfigs(stmt); + } + } catch (SQLException e) { + String msg = "Error occurred while updating Geofence record with id "; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + @Override + public Set getGroupIdsOfGeoFences(List fenceIds) throws DeviceManagementDAOException { + try { + Set geoFenceGroupSet = new HashSet<>(); + if (fenceIds.isEmpty()) { + return geoFenceGroupSet; + } + Connection conn = this.getConnection(); + String sql = "SELECT " + + "FENCE_ID, " + + "M.GROUP_ID, " + + "G.GROUP_NAME " + + "FROM DM_GEOFENCE_GROUP_MAPPING M, DM_GROUP G " + + "WHERE M.GROUP_ID = G.ID " + + "AND FENCE_ID IN (%s)"; + String inClause = String.join(", ", Collections.nCopies(fenceIds.size(), "?")); + sql = String.format(sql, inClause); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + int index = 1; + for (Integer fenceId : fenceIds) { + stmt.setInt(index++, fenceId); + } + ResultSet rst = stmt.executeQuery(); + while (rst.next()) { + GeoFenceGroupMap geoFenceGroupMap = new GeoFenceGroupMap(); + geoFenceGroupMap.setFenceId(rst.getInt("FENCE_ID")); + geoFenceGroupMap.setGroupId(rst.getInt("GROUP_ID")); + geoFenceGroupMap.setGroupName(rst.getString("GROUP_NAME")); + geoFenceGroupSet.add(geoFenceGroupMap); + } + } + return geoFenceGroupSet; + } catch (SQLException e) { + String msg = "Error occurred while fetching group IDs of the fences"; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + /** + * Retrieve the geofence event extracted from the DB + * @param stmt prepared statement to retrieve data from the DB + * @return Retrieved Event list from the DB + * @throws SQLException for the errors occur while accessing the DB + */ + private List getEventConfigs(PreparedStatement stmt) throws SQLException { + List eventList = new ArrayList<>(); + ResultSet resultSet = stmt.executeQuery(); + EventConfig event; + while (resultSet.next()) { + event = new EventConfig(); + event.setEventId(resultSet.getInt("EVENT_ID")); + event.setEventSource(resultSet.getString("EVENT_SOURCE")); + event.setEventLogic(resultSet.getString("EVENT_LOGIC")); + event.setActions(resultSet.getString("ACTIONS")); + eventList.add(event); + } + return eventList; + } + + @Override + public List getGeoFences(int groupId, int tenantId) throws DeviceManagementDAOException { + try { + Connection conn = this.getConnection(); + String sql = "SELECT " + + "G.ID AS FENCE_ID, " + + "FENCE_NAME, " + + "DESCRIPTION, " + + "LATITUDE," + + "LONGITUDE, " + + "RADIUS, " + + "GEO_JSON, " + + "FENCE_SHAPE " + + "FROM DM_GEOFENCE G, DM_GEOFENCE_GROUP_MAPPING M " + + "WHERE M.GROUP_ID = ? AND TENANT_ID = ? " + + "GROUP BY G.ID"; + + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, groupId); + stmt.setInt(2, tenantId); + ResultSet rst = stmt.executeQuery(); + List geofenceDataList = new ArrayList<>(); + while (rst.next()) { + GeofenceData geofenceData = new GeofenceData(); + geofenceData.setId(rst.getInt("FENCE_ID")); + geofenceData.setFenceName(rst.getString("FENCE_NAME")); + geofenceData.setDescription(rst.getString("DESCRIPTION")); + geofenceData.setLatitude(rst.getDouble("LATITUDE")); + geofenceData.setLongitude(rst.getDouble("LONGITUDE")); + geofenceData.setRadius(rst.getFloat("RADIUS")); + geofenceData.setGeoJson(rst.getString("GEO_JSON")); + geofenceData.setFenceShape(rst.getString("FENCE_SHAPE")); + geofenceDataList.add(geofenceData); + } + return geofenceDataList; + } + } catch (SQLException e) { + String msg = "Error occurred while retrieving Geo fences of group " + groupId + + " and tenant " + tenantId; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + @Override + public GeofenceData getGeofence(int fenceId, boolean requireGroupData) throws DeviceManagementDAOException { + if (!requireGroupData) { + return getGeofence(fenceId); + } + + try { + Connection con = this.getConnection(); + String sql = "SELECT " + + "G.ID AS FENCE_ID, " + + "FENCE_NAME, " + + "G.DESCRIPTION, " + + "LATITUDE, " + + "LONGITUDE, " + + "RADIUS, " + + "GEO_JSON, " + + "FENCE_SHAPE, " + + "M.GROUP_ID AS GROUP_ID, " + + "GR.GROUP_NAME " + + "FROM DM_GEOFENCE G, DM_GEOFENCE_GROUP_MAPPING M, DM_GROUP GR " + + "WHERE G.ID = M.FENCE_ID " + + "AND M.GROUP_ID = GR.ID " + + "AND G.ID = ?"; + try (PreparedStatement stmt = con.prepareStatement(sql)){ + stmt.setInt(1, fenceId); + ResultSet rst = stmt.executeQuery(); + Map groupMap = new HashMap<>(); + GeofenceData geofenceData = null; + while (rst.next()) { + groupMap.put(rst.getInt("GROUP_ID"), rst.getString("GROUP_NAME")); + if (rst.isLast()) { + geofenceData = new GeofenceData(); + geofenceData.setId(rst.getInt("FENCE_ID")); + geofenceData.setFenceName(rst.getString("FENCE_NAME")); + geofenceData.setDescription(rst.getString("DESCRIPTION")); + geofenceData.setLatitude(rst.getDouble("LATITUDE")); + geofenceData.setLongitude(rst.getDouble("LONGITUDE")); + geofenceData.setRadius(rst.getFloat("RADIUS")); + geofenceData.setGeoJson(rst.getString("GEO_JSON")); + geofenceData.setFenceShape(rst.getString("FENCE_SHAPE")); + geofenceData.setGroupData(groupMap); + } + } + return geofenceData; + } + } catch (SQLException e) { + String msg = "Error occurred while retrieving Geo fence data " + fenceId; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/geofence/SQLServerGeofenceDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/geofence/SQLServerGeofenceDAOImpl.java new file mode 100644 index 00000000000..7fe050a477f --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/dao/impl/geofence/SQLServerGeofenceDAOImpl.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2023, 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.dao.impl.geofence; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.common.DeviceManagementConstants; +import org.wso2.carbon.device.mgt.common.PaginationRequest; +import org.wso2.carbon.device.mgt.common.event.config.EventConfig; +import org.wso2.carbon.device.mgt.common.geo.service.GeofenceData; +import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException; +import org.wso2.carbon.device.mgt.core.dao.EventManagementDAOFactory; +import org.wso2.carbon.device.mgt.core.dao.GeofenceDAO; +import org.wso2.carbon.device.mgt.core.dao.impl.AbstractGeofenceDAOImpl; +import org.wso2.carbon.device.mgt.core.dto.event.config.GeoFenceGroupMap; + +import java.sql.*; +import java.util.Date; +import java.util.*; + +public class SQLServerGeofenceDAOImpl extends AbstractGeofenceDAOImpl { + private static final Log log = LogFactory.getLog(SQLServerGeofenceDAOImpl.class); + + @Override + public List getGeoFencesOfTenant(PaginationRequest request, int tenantId) + throws DeviceManagementDAOException { + try { + Connection conn = this.getConnection(); + boolean isNameProvided = false; + List geofenceData; + String sql = "SELECT " + + "ID, " + + "FENCE_NAME, " + + "DESCRIPTION, " + + "LATITUDE, " + + "LONGITUDE, " + + "RADIUS, " + + "GEO_JSON, " + + "FENCE_SHAPE, " + + "OWNER, " + + "TENANT_ID " + + "FROM DM_GEOFENCE " + + "WHERE TENANT_ID = ? "; + + if (request.getProperty(DeviceManagementConstants.GeoServices.FENCE_NAME) != null) { + sql += "AND FENCE_NAME LIKE ?"; + isNameProvided = true; + } + sql += "ORDER BY FENCE_NAME "; + sql += "OFFSET ? ROWS FETCH NEXT ? ROWS ONLY"; + int index = 1; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(index++, tenantId); + if (isNameProvided) { + stmt.setString(index++, request.getProperty(DeviceManagementConstants.GeoServices.FENCE_NAME).toString() + "%"); + } + stmt.setInt(index++, request.getStartIndex()); + stmt.setInt(index, request.getRowCount()); + try (ResultSet rst = stmt.executeQuery()) { + geofenceData = extractGeofenceData(rst); + } + } + return geofenceData; + } catch (SQLException e) { + String msg = "Error occurred while retrieving Geofence of the tenant " + tenantId; + log.error(msg, e); + throw new DeviceManagementDAOException(msg, e); + } + } + + private Connection getConnection() throws SQLException { + return EventManagementDAOFactory.getConnection(); + } + + private List extractGeofenceData(ResultSet rst) throws SQLException { + List geofenceDataList = new ArrayList<>(); + while (rst.next()) { + GeofenceData geofenceData = new GeofenceData(); + geofenceData.setId(rst.getInt("ID")); + geofenceData.setFenceName(rst.getString("FENCE_NAME")); + geofenceData.setDescription(rst.getString("DESCRIPTION")); + geofenceData.setLatitude(rst.getDouble("LATITUDE")); + geofenceData.setLongitude(rst.getDouble("LONGITUDE")); + geofenceData.setRadius(rst.getFloat("RADIUS")); + geofenceData.setGeoJson(rst.getString("GEO_JSON")); + geofenceData.setFenceShape(rst.getString("FENCE_SHAPE")); + geofenceData.setOwner(rst.getString("OWNER")); + geofenceData.setTenantId(rst.getInt("TENANT_ID")); + geofenceDataList.add(geofenceData); + } + return geofenceDataList; + } +}