diff --git a/components/operation-template-mgt/io.entgra.device.mgt.operation.template/pom.xml b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/pom.xml
new file mode 100644
index 0000000000..496462c287
--- /dev/null
+++ b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/pom.xml
@@ -0,0 +1,362 @@
+
+
+
+
+
+
+ org.wso2.carbon.devicemgt
+ operation-template-mgt
+ 5.0.20-SNAPSHOT
+ ../pom.xml
+
+
+ 4.0.0
+ io.entgra.device.mgt.operation.template
+ bundle
+ Entgra IoT - Operation Template Core
+ Entgra IoT - Operation Template Core
+ http://entgra.io
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ org.apache.felix
+ maven-scr-plugin
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+
+
+ ${project.artifactId}
+ ${project.artifactId}
+ ${carbon.device.mgt.version}
+ IOT Operation Template Bundle
+ io.entgra.device.mgt.operation.template.internal
+
+ org.osgi.framework.*;version="${imp.package.version.osgi.framework}",
+ org.osgi.service.*;version="${imp.package.version.osgi.service}",
+ org.apache.commons.logging,
+ org.apache.commons.lang,
+ javax.xml,
+ javax.xml.stream,
+ javax.xml.bind.*;version="${javax.xml.bind.imp.pkg.version}",
+ javax.sql,
+ javax.xml.parsers; version=0.0.0,
+ org.w3c.dom,
+ com.google.gson.*,
+ javax.naming,
+ org.wso2.carbon.context,
+ org.wso2.carbon.base,
+ org.wso2.carbon.utils.*,
+ org.wso2.carbon.device.mgt.common.*,
+ org.wso2.carbon.device.mgt.core.*,
+ org.wso2.carbon.ndatasource.core,
+ org.wso2.carbon.registry.core,
+ org.wso2.carbon.registry.core.session,
+ org.wso2.carbon.registry.core.service,
+ org.wso2.carbon.registry.api,
+ org.wso2.carbon.device.mgt.extensions.license.mgt.registry,
+ javax.net.ssl,
+ org.wso2.carbon.core.util,
+ okhttp3
+
+
+ !io.entgra.device.mgt.operation.template.internal,
+ io.entgra.device.mgt.operation.template.*
+
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+
+ ${basedir}/target/coverage-reports/jacoco-unit.exec
+
+
+
+ jacoco-initialize
+
+ prepare-agent
+
+
+
+ jacoco-site
+ test
+
+ report
+
+
+ ${basedir}/target/coverage-reports/jacoco-unit.exec
+ ${basedir}/target/coverage-reports/site
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ file:src/test/resources/carbon-home/repository/conf/log4j.properties
+
+
+
+ src/test/resources/testng.xml
+
+
+
+
+
+
+
+ org.wso2.carbon.devicemgt
+ org.wso2.carbon.device.mgt.common
+ provided
+
+
+ org.wso2.carbon.identity.inbound.auth.oauth2
+ org.wso2.carbon.identity.oauth.stub
+
+
+ org.apache.axis2.wso2
+ axis2-client
+
+
+ org.apache.geronimo.specs.wso2
+ geronimo-stax-api_1.0_spec
+
+
+ org.apache.ws.commons.axiom.wso2
+ axiom
+
+
+ org.codehaus.woodstox
+ woodstox-core-asl
+
+
+ org.codehaus.woodstox
+ wstx-asl
+
+
+ org.wso2.carbon.devicemgt
+ org.wso2.carbon.device.mgt.analytics.data.publisher
+
+
+ org.wso2.carbon.analytics
+ org.wso2.carbon.analytics.api
+
+
+
+
+ org.powermock
+ powermock-module-testng
+ test
+
+
+ org.testng
+ testng
+ test
+
+
+ org.wso2.carbon.devicemgt
+ org.wso2.carbon.device.mgt.extensions
+ provided
+
+
+ org.codehaus.woodstox
+ stax2-api
+
+
+ org.codehaus.woodstox
+ woodstox-core-asl
+
+
+ org.wso2.carbon
+ org.wso2.carbon.securevault
+
+
+ org.apache.ws.commons.axiom.wso2
+ axiom
+
+
+
+
+ org.wso2.carbon
+ org.wso2.carbon.ndatasource.core
+ provided
+
+
+ org.wso2.securevault
+ org.wso2.securevault
+
+
+
+
+ org.wso2.carbon
+ org.wso2.carbon.base
+ provided
+
+
+ org.wso2.securevault
+ org.wso2.securevault
+
+
+ org.apache.ws.commons.axiom.wso2
+ axiom
+
+
+ org.mockito
+ mockito-core
+
+
+
+
+ org.eclipse.osgi
+ org.eclipse.osgi
+ provided
+
+
+ com.h2database.wso2
+ h2-database-engine
+ test
+
+
+ org.eclipse.osgi
+ org.eclipse.osgi.services
+ provided
+
+
+ org.wso2.carbon
+ org.wso2.carbon.core
+ provided
+
+
+ org.wso2.carbon
+ org.wso2.carbon.logging
+ provided
+
+
+ org.wso2.carbon
+ org.wso2.carbon.utils
+ provided
+
+
+ org.wso2.carbon.devicemgt
+ org.wso2.carbon.device.mgt.core
+ provided
+
+
+ org.wso2.carbon
+ org.wso2.carbon.registry.api
+ provided
+
+
+ org.wso2.carbon
+ org.wso2.carbon.registry.core
+ provided
+
+
+ org.apache.tomcat.wso2
+ jdbc-pool
+ provided
+
+
+ com.google.code.gson
+ gson
+ provided
+
+
+ io.github.openfeign
+ feign-core
+ provided
+
+
+ io.github.openfeign
+ feign-jackson
+ provided
+
+
+ com.google.guava
+ guava
+
+
+ io.github.openfeign
+ feign-jaxrs
+ provided
+
+
+ io.github.openfeign
+ feign-gson
+ provided
+
+
+ io.github.openfeign
+ feign-okhttp
+ provided
+
+
+ io.github.openfeign
+ feign-slf4j
+ provided
+
+
+ org.wso2.carbon.devicemgt
+ org.wso2.carbon.identity.jwt.client.extension
+ provided
+
+
+ commons-validator
+ commons-validator
+ provided
+
+
+ org.apache.cxf
+ cxf-rt-frontend-jaxws
+ provided
+
+
+ org.apache.cxf
+ cxf-rt-frontend-jaxrs
+ provided
+
+
+ org.apache.cxf
+ cxf-rt-transports-http
+ provided
+
+
+ commons-lang.wso2
+ commons-lang
+ provided
+
+
+ javax.xml.bind
+ jaxb-api
+ test
+
+
+
diff --git a/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/cache/OperationTemplateCacheLoader.java b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/cache/OperationTemplateCacheLoader.java
new file mode 100644
index 0000000000..792d540004
--- /dev/null
+++ b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/cache/OperationTemplateCacheLoader.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2018 - 2023 Entgra (Pvt) Ltd, Inc - All Rights Reserved.
+ *
+ * Unauthorised copying/redistribution of this file, via any medium is strictly prohibited.
+ *
+ * Licensed under the Entgra Commercial License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://entgra.io/licenses/entgra-commercial/1.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.device.mgt.operation.template.cache;
+
+import com.google.common.cache.CacheLoader;
+import io.entgra.device.mgt.operation.template.dao.OperationTemplateDAO;
+import io.entgra.device.mgt.operation.template.dao.OperationTemplateDAOFactory;
+import io.entgra.device.mgt.operation.template.dao.impl.util.OperationTemplateManagementUtil;
+import io.entgra.device.mgt.operation.template.dto.OperationTemplate;
+import io.entgra.device.mgt.operation.template.dto.OperationTemplateCacheKey;
+import io.entgra.device.mgt.operation.template.exception.DBConnectionException;
+import io.entgra.device.mgt.operation.template.exception.OperationTemplateManagementDAOException;
+import io.entgra.device.mgt.operation.template.exception.OperationTemplateMgtPluginException;
+import io.entgra.device.mgt.operation.template.util.ConnectionManagerUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Class for the Operation Template cache.
+ */
+public class OperationTemplateCacheLoader extends CacheLoader {
+
+ private static final Log log = LogFactory.getLog(OperationTemplateCacheLoader.class);
+
+ private final OperationTemplateDAO operationTemplateDAO;
+
+ public OperationTemplateCacheLoader() {
+ this.operationTemplateDAO = OperationTemplateDAOFactory.getOperationTemplateDAO();
+ }
+
+ /**
+ *
+ * @param key the non-null key whose value should be loaded
+ * @return
+ * @throws OperationTemplateMgtPluginException
+ */
+ @Override
+ public OperationTemplate load(String key) throws OperationTemplateMgtPluginException {
+ OperationTemplateCacheKey operationTemplateCacheKey = OperationTemplateManagementUtil.getOperationTemplateCacheKey(
+ key);
+ int subTypeId = operationTemplateCacheKey.getSubTypeId();
+ String operationCode = operationTemplateCacheKey.getOperationCode();
+ String deviceType = operationTemplateCacheKey.getDeviceType();
+
+ if (log.isTraceEnabled()) {
+ log.trace(
+ "Loading operation template for subtype Id : " + subTypeId + " & deviceType : " + deviceType + " operation code : "
+ + operationCode);
+ }
+ try {
+ ConnectionManagerUtils.openDBConnection();
+ return operationTemplateDAO.getOperationTemplate(subTypeId, deviceType, operationCode);
+ } catch (DBConnectionException e) {
+ String msg =
+ "Error occurred while obtaining the database connection to retrieve operation template for "
+ +
+ "subtype Id : " + subTypeId + " & operation code : " + operationCode;
+ log.error(msg);
+ throw new OperationTemplateMgtPluginException(msg, e);
+ } catch (InvalidCacheLoadException e) {
+ String msg =
+ "CacheLoader returned null for operation template for subtype Id : " + subTypeId
+ + " & operation code : " + operationCode;
+ log.error(msg, e);
+ return null;
+ } catch (OperationTemplateManagementDAOException e) {
+ String msg =
+ "Error occurred in the database level while retrieving operation template for subtype Id : "
+ + subTypeId + " & operation code : " + operationCode;
+ log.error(msg);
+ throw new OperationTemplateMgtPluginException(msg, e);
+ } finally {
+ ConnectionManagerUtils.closeDBConnection();
+ }
+ }
+
+}
diff --git a/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/OperationTemplateDAO.java b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/OperationTemplateDAO.java
new file mode 100644
index 0000000000..d395c4d54c
--- /dev/null
+++ b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/OperationTemplateDAO.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2018 - 2023 Entgra (Pvt) Ltd, Inc - All Rights Reserved.
+ *
+ * Unauthorised copying/redistribution of this file, via any medium is strictly prohibited.
+ *
+ * Licensed under the Entgra Commercial License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://entgra.io/licenses/entgra-commercial/1.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.device.mgt.operation.template.dao;
+
+import io.entgra.device.mgt.operation.template.dto.OperationTemplate;
+import io.entgra.device.mgt.operation.template.exception.OperationTemplateManagementDAOException;
+
+/**
+ * This class represents the key operations associated with persisting mobile-device related
+ * information.
+ */
+public interface OperationTemplateDAO {
+ void addOperationTemplate(OperationTemplate operationTemplate) throws OperationTemplateManagementDAOException;
+
+ OperationTemplate updateOperationTemplate(OperationTemplate operationTemplate)
+ throws OperationTemplateManagementDAOException;
+
+ OperationTemplate getOperationTemplate(int subTypeId, String deviceType, String operationCode) throws OperationTemplateManagementDAOException;
+
+ void deleteOperationTemplate(int subTypeId, String deviceCode, String operationCode) throws OperationTemplateManagementDAOException;
+
+ boolean isExistsOperationTemplateBySubtypeIdAndOperationCode(int subTypeId, String deviceType, String operationCode) throws OperationTemplateManagementDAOException;
+}
diff --git a/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/OperationTemplateDAOFactory.java b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/OperationTemplateDAOFactory.java
new file mode 100644
index 0000000000..b62ed24635
--- /dev/null
+++ b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/OperationTemplateDAOFactory.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2018 - 2023 Entgra (Pvt) Ltd, Inc - All Rights Reserved.
+ *
+ * Unauthorised copying/redistribution of this file, via any medium is strictly prohibited.
+ *
+ * Licensed under the Entgra Commercial License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://entgra.io/licenses/entgra-commercial/1.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.device.mgt.operation.template.dao;
+
+import io.entgra.device.mgt.operation.template.dao.impl.OperationTemplateDAOImpl;
+import io.entgra.device.mgt.operation.template.dao.impl.OperationTemplateMySQLDAOImpl;
+import io.entgra.device.mgt.operation.template.dao.impl.config.datasource.DataSourceConfig;
+import io.entgra.device.mgt.operation.template.util.ConnectionManagerUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.wso2.carbon.device.mgt.common.DeviceManagementConstants;
+
+
+public class OperationTemplateDAOFactory {
+
+ private static final Log log = LogFactory.getLog(OperationTemplateDAOFactory.class);
+ private static String databaseEngine;
+
+ /**
+ *
+ * @param config
+ */
+ public static void init(DataSourceConfig config) {
+ if (log.isDebugEnabled()) {
+ log.debug("Initializing Operation Template Mgt Data Source");
+ }
+ ConnectionManagerUtils.resolveDataSource(config);
+ databaseEngine = ConnectionManagerUtils.getDatabaseType();
+ }
+
+ /**
+ *
+ * @return
+ */
+ public static OperationTemplateDAO getOperationTemplateDAO() {
+ if (databaseEngine == null) {
+ throw new IllegalStateException("Database engine has not initialized properly.");
+ }
+ //noinspection SwitchStatementWithTooFewBranches
+ switch (databaseEngine) {
+ case DeviceManagementConstants.DataBaseTypes.DB_TYPE_MYSQL:
+ return new OperationTemplateMySQLDAOImpl();
+ default:
+ return new OperationTemplateDAOImpl();
+ }
+ }
+
+}
diff --git a/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/impl/OperationTemplateDAOImpl.java b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/impl/OperationTemplateDAOImpl.java
new file mode 100644
index 0000000000..f32246ec0c
--- /dev/null
+++ b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/impl/OperationTemplateDAOImpl.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2018 - 2023 Entgra (Pvt) Ltd, Inc - All Rights Reserved.
+ *
+ * Unauthorised copying/redistribution of this file, via any medium is strictly prohibited.
+ *
+ * Licensed under the Entgra Commercial License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://entgra.io/licenses/entgra-commercial/1.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.device.mgt.operation.template.dao.impl;
+
+import com.google.gson.Gson;
+import io.entgra.device.mgt.operation.template.dao.OperationTemplateDAO;
+import io.entgra.device.mgt.operation.template.dto.OperationTemplate;
+import io.entgra.device.mgt.operation.template.exception.DBConnectionException;
+import io.entgra.device.mgt.operation.template.exception.OperationTemplateManagementDAOException;
+import io.entgra.device.mgt.operation.template.util.ConnectionManagerUtils;
+import io.entgra.device.mgt.operation.template.util.DAOUtil;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Implementation for generic DB engines.
+ */
+public class OperationTemplateDAOImpl implements OperationTemplateDAO {
+
+ private static final Log log = LogFactory.getLog(OperationTemplateDAOImpl.class);
+
+ /**
+ *
+ * @param operationTemplate
+ * @throws OperationTemplateManagementDAOException
+ */
+ @Override
+ public void addOperationTemplate(OperationTemplate operationTemplate)
+ throws OperationTemplateManagementDAOException {
+
+ try {
+ String sql =
+ "INSERT INTO SUB_OPERATION_TEMPLATE (" + "OPERATION_DEFINITION, " + "OPERATION_CODE, "
+ + "SUB_TYPE_ID, " + "DEVICE_TYPE, " + "CREATE_TIMESTAMP, " + "UPDATE_TIMESTAMP) "
+ + "VALUES (?, ?, ?, ?, ?, ?)";
+ Connection conn = ConnectionManagerUtils.getDBConnection();
+
+ try (PreparedStatement stmt = conn.prepareStatement(sql)) {
+
+ int index = 1;
+ stmt.setObject(index++, new Gson().toJson(operationTemplate.getOperationDefinition()));
+ stmt.setString(index++, operationTemplate.getCode());
+ stmt.setInt(index++, operationTemplate.getSubTypeId());
+ stmt.setString(index++, operationTemplate.getDeviceType());
+ stmt.setTimestamp(index++, new Timestamp(System.currentTimeMillis()));
+ stmt.setTimestamp(index++, null);
+ stmt.executeUpdate();
+ } catch (SQLException e) {
+ String msg = "Error occurred while processing insert operation template.";
+ log.error(msg);
+ throw new OperationTemplateManagementDAOException(msg, e);
+ }
+ } catch (DBConnectionException e) {
+ String msg = "Error occurred while obtaining DB connection to insert operation template.";
+ log.error(msg);
+ throw new OperationTemplateManagementDAOException(msg, e);
+ }
+ }
+
+ /**
+ *
+ * @param operationTemplate
+ * @return
+ * @throws OperationTemplateManagementDAOException
+ */
+ @Override
+ public OperationTemplate updateOperationTemplate(OperationTemplate operationTemplate)
+ throws OperationTemplateManagementDAOException {
+
+ try {
+ String sql =
+ "UPDATE SUB_OPERATION_TEMPLATE SET OPERATION_DEFINITION = ? WHERE SUB_TYPE_ID = ? AND DEVICE_TYPE = ? "
+ + "AND OPERATION_CODE = ?";
+
+ Connection conn = ConnectionManagerUtils.getDBConnection();
+ try (PreparedStatement stmt = conn.prepareStatement(sql)) {
+ stmt.setString(1, operationTemplate.getOperationDefinition());
+ stmt.setInt(2, operationTemplate.getSubTypeId());
+ stmt.setString(3, operationTemplate.getDeviceType());
+ stmt.setString(4, operationTemplate.getCode());
+ stmt.executeUpdate();
+
+ return getOperationTemplate(operationTemplate.getSubTypeId(), operationTemplate.getDeviceType(), operationTemplate.getCode());
+ } catch (SQLException e) {
+ String msg = "Error occurred while processing update operation template.";
+ log.error(msg);
+ throw new OperationTemplateManagementDAOException(msg, e);
+ }
+ } catch (DBConnectionException e) {
+ String msg = "Error occurred while obtaining DB connection to update operation template.";
+ throw new OperationTemplateManagementDAOException(msg, e);
+ }
+ }
+
+ /**
+ *
+ * @param subTypeId
+ * @param deviceType
+ * @param operationCode
+ * @return
+ * @throws OperationTemplateManagementDAOException
+ */
+ @Override
+ public OperationTemplate getOperationTemplate(int subTypeId, String deviceType, String operationCode)
+ throws OperationTemplateManagementDAOException {
+ try {
+ String sql = "SELECT * FROM SUB_OPERATION_TEMPLATE WHERE SUB_TYPE_ID = ? AND DEVICE_TYPE = ? AND OPERATION_CODE = ?";
+ Connection conn = ConnectionManagerUtils.getDBConnection();
+ try (PreparedStatement stmt = conn.prepareStatement(sql)) {
+ stmt.setInt(1, subTypeId);
+ stmt.setString(2, deviceType);
+ stmt.setString(3, operationCode);
+
+ try (ResultSet rs = stmt.executeQuery()) {
+ if (rs.next()) {
+ return DAOUtil.loadOperationTemplate(rs);
+ }
+ return null;
+ }
+ } catch (SQLException e) {
+ String msg = "Error occurred while loading operation template.";
+ log.error(e.getMessage());
+ throw new OperationTemplateManagementDAOException(msg, e);
+ }
+ } catch (DBConnectionException e) {
+ String msg = "Error occurred while obtaining DB connection to loading operation template.";
+ log.error(msg);
+ throw new OperationTemplateManagementDAOException(msg, e);
+ }
+ }
+
+ /**
+ *
+ * @param subTypeId
+ * @param deviceType
+ * @param operationCode
+ * @throws OperationTemplateManagementDAOException
+ */
+ @Override
+ public void deleteOperationTemplate(int subTypeId, String deviceType, String operationCode)
+ throws OperationTemplateManagementDAOException {
+ String sql = "DELETE FROM SUB_OPERATION_TEMPLATE WHERE SUB_TYPE_ID = ? AND DEVICE_TYPE = ? AND OPERATION_CODE = ?";
+ try {
+ Connection conn = ConnectionManagerUtils.getDBConnection();
+ try (PreparedStatement stmt = conn.prepareStatement(sql)) {
+ stmt.setInt(1, subTypeId);
+ stmt.setString(2, deviceType);
+ stmt.setString(3, operationCode);
+ stmt.executeUpdate();
+ } catch (SQLException e) {
+ String msg = "Error occurred while deleting operation template for sub type id : " + subTypeId
+ + " and operation code : " + operationCode;
+ log.error(msg, e);
+ throw new OperationTemplateManagementDAOException(msg, e);
+ }
+ } catch (DBConnectionException e) {
+ String msg = "Error occurred while obtaining DB connection to delete operation template.";
+ log.error(msg);
+ throw new OperationTemplateManagementDAOException(msg, e);
+ }
+ }
+
+ /**
+ *
+ * @param subTypeId
+ * @param deviceType
+ * @param operationCode
+ * @return
+ * @throws OperationTemplateManagementDAOException
+ */
+ @Override
+ public boolean isExistsOperationTemplateBySubtypeIdAndOperationCode(int subTypeId, String deviceType,
+ String operationCode) throws OperationTemplateManagementDAOException {
+ try {
+ String sql = "SELECT * FROM SUB_OPERATION_TEMPLATE WHERE SUB_TYPE_ID = ? AND DEVICE_TYPE = ? AND OPERATION_CODE = ?";
+
+ Connection conn = ConnectionManagerUtils.getDBConnection();
+ try (PreparedStatement stmt = conn.prepareStatement(sql)) {
+ stmt.setInt(1, subTypeId);
+ stmt.setString(2, deviceType);
+ stmt.setString(3, operationCode);
+
+ try (ResultSet rs = stmt.executeQuery()) {
+ if (rs.next()) {
+ return true;
+ }
+ return false;
+ }
+ } catch (SQLException e) {
+ String msg = "Error occurred while loading operation template.";
+ log.error(e.getMessage());
+ throw new OperationTemplateManagementDAOException(msg, e);
+ }
+ } catch (DBConnectionException e) {
+ String msg = "Error occurred while obtaining DB connection to loading operation template.";
+ log.error(msg);
+ throw new OperationTemplateManagementDAOException(msg, e);
+ }
+ }
+}
diff --git a/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/impl/OperationTemplateMySQLDAOImpl.java b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/impl/OperationTemplateMySQLDAOImpl.java
new file mode 100644
index 0000000000..26fedaa4e5
--- /dev/null
+++ b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/impl/OperationTemplateMySQLDAOImpl.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2018 - 2023 Entgra (Pvt) Ltd, Inc - All Rights Reserved.
+ *
+ * Unauthorised copying/redistribution of this file, via any medium is strictly prohibited.
+ *
+ * Licensed under the Entgra Commercial License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://entgra.io/licenses/entgra-commercial/1.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.device.mgt.operation.template.dao.impl;
+
+
+/**
+ * Implementation for MySQL
+ */
+public class OperationTemplateMySQLDAOImpl extends OperationTemplateDAOImpl {
+
+
+}
diff --git a/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/impl/config/DeviceConfigurationManager.java b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/impl/config/DeviceConfigurationManager.java
new file mode 100644
index 0000000000..80915cd1bf
--- /dev/null
+++ b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/impl/config/DeviceConfigurationManager.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2018 - 2023 Entgra (Pvt) Ltd, Inc - All Rights Reserved.
+ *
+ * Unauthorised copying/redistribution of this file, via any medium is strictly prohibited.
+ *
+ * Licensed under the Entgra Commercial License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://entgra.io/licenses/entgra-commercial/1.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.device.mgt.operation.template.dao.impl.config;
+
+import io.entgra.device.mgt.operation.template.dao.impl.util.OperationTemplateManagementUtil;
+import org.w3c.dom.Document;
+import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
+import org.wso2.carbon.utils.CarbonUtils;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
+import java.io.File;
+
+/**
+ * Class responsible for the mobile device manager configuration initialization.
+ */
+public class DeviceConfigurationManager {
+
+ public static final String DEVICE_CONFIG_XML_NAME = "cdm-config.xml";
+ private DeviceManagementConfig deviceManagementConfig;
+ private static DeviceConfigurationManager deviceConfigurationManager;
+ private final String operationTemplateMgtConfigXMLPath = CarbonUtils.getCarbonConfigDirPath() + File.separator +
+ DEVICE_CONFIG_XML_NAME;
+
+ /**
+ *
+ * @return
+ */
+ public static DeviceConfigurationManager getInstance() {
+ if (deviceConfigurationManager == null) {
+ synchronized (DeviceConfigurationManager.class) {
+ if (deviceConfigurationManager == null) {
+ deviceConfigurationManager = new DeviceConfigurationManager();
+ }
+ }
+ }
+ return deviceConfigurationManager;
+ }
+
+ /**
+ *
+ * @throws DeviceManagementException
+ */
+ public synchronized void initConfig() throws DeviceManagementException {
+ try {
+ File deviceMgtConfig = new File(operationTemplateMgtConfigXMLPath);
+ Document doc = OperationTemplateManagementUtil.convertToDocument(deviceMgtConfig);
+ JAXBContext mobileDeviceMgmtContext =
+ JAXBContext.newInstance(DeviceManagementConfig.class);
+ Unmarshaller unmarshaller = mobileDeviceMgmtContext.createUnmarshaller();
+ this.deviceManagementConfig =
+ (DeviceManagementConfig) unmarshaller.unmarshal(doc);
+ } catch (Exception e) {
+ throw new DeviceManagementException(
+ "Error occurred while initializing Mobile Device Management config", e);
+ }
+ }
+
+ /**
+ *
+ * @return
+ */
+ public DeviceManagementConfig getDeviceManagementConfig() {
+ return deviceManagementConfig;
+ }
+
+}
diff --git a/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/impl/config/DeviceManagementConfig.java b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/impl/config/DeviceManagementConfig.java
new file mode 100644
index 0000000000..7a817d67ea
--- /dev/null
+++ b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/impl/config/DeviceManagementConfig.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2018 - 2023 Entgra (Pvt) Ltd, Inc - All Rights Reserved.
+ *
+ * Unauthorised copying/redistribution of this file, via any medium is strictly prohibited.
+ *
+ * Licensed under the Entgra Commercial License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://entgra.io/licenses/entgra-commercial/1.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.device.mgt.operation.template.dao.impl.config;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * Represents Mobile Device Mgt configuration.
+ */
+@XmlRootElement(name = "DeviceMgtConfiguration")
+public final class DeviceManagementConfig {
+
+ private DeviceManagementRepository deviceManagementRepository;
+
+ @XmlElement(name = "ManagementRepository", required = true)
+ public DeviceManagementRepository getDeviceManagementRepository() {
+ return deviceManagementRepository;
+ }
+
+ public void setDeviceManagementRepository(
+ DeviceManagementRepository deviceManagementRepository) {
+ this.deviceManagementRepository = deviceManagementRepository;
+ }
+
+}
diff --git a/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/impl/config/DeviceManagementRepository.java b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/impl/config/DeviceManagementRepository.java
new file mode 100644
index 0000000000..315c1a8f3b
--- /dev/null
+++ b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/impl/config/DeviceManagementRepository.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2018 - 2023 Entgra (Pvt) Ltd, Inc - All Rights Reserved.
+ *
+ * Unauthorised copying/redistribution of this file, via any medium is strictly prohibited.
+ *
+ * Licensed under the Entgra Commercial License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://entgra.io/licenses/entgra-commercial/1.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.device.mgt.operation.template.dao.impl.config;
+
+import io.entgra.device.mgt.operation.template.dao.impl.config.datasource.DataSourceConfig;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * Class for holding management repository data.
+ */
+@XmlRootElement(name = "ManagementRepository")
+public class DeviceManagementRepository {
+
+ private DataSourceConfig dataSourceConfig;
+
+ @XmlElement(name = "DataSourceConfiguration", required = true)
+ public DataSourceConfig getDataSourceConfig() {
+ return dataSourceConfig;
+ }
+
+ public void setDataSourceConfig(
+ DataSourceConfig dataSourceConfig) {
+ this.dataSourceConfig = dataSourceConfig;
+ }
+}
diff --git a/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/impl/config/datasource/DataSourceConfig.java b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/impl/config/datasource/DataSourceConfig.java
new file mode 100644
index 0000000000..519fa3c92b
--- /dev/null
+++ b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/impl/config/datasource/DataSourceConfig.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2018 - 2023 Entgra (Pvt) Ltd, Inc - All Rights Reserved.
+ *
+ * Unauthorised copying/redistribution of this file, via any medium is strictly prohibited.
+ *
+ * Licensed under the Entgra Commercial License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://entgra.io/licenses/entgra-commercial/1.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.device.mgt.operation.template.dao.impl.config.datasource;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * Class for holding data source configuration at parsing with JAXB.
+ */
+@XmlRootElement(name = "DataSourceConfiguration")
+public class DataSourceConfig {
+
+ private JNDILookupDefinition jndiLookupDefinition;
+
+ @XmlElement(name = "JndiLookupDefinition", required = true)
+ public JNDILookupDefinition getJndiLookupDefinition() {
+ return jndiLookupDefinition;
+ }
+
+ public void setJndiLookupDefinition(JNDILookupDefinition jndiLookupDefinition) {
+ this.jndiLookupDefinition = jndiLookupDefinition;
+ }
+
+}
diff --git a/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/impl/config/datasource/JNDILookupDefinition.java b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/impl/config/datasource/JNDILookupDefinition.java
new file mode 100644
index 0000000000..6ecfcda805
--- /dev/null
+++ b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/impl/config/datasource/JNDILookupDefinition.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2018 - 2023 Entgra (Pvt) Ltd, Inc - All Rights Reserved.
+ *
+ * Unauthorised copying/redistribution of this file, via any medium is strictly prohibited.
+ *
+ * Licensed under the Entgra Commercial License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://entgra.io/licenses/entgra-commercial/1.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.device.mgt.operation.template.dao.impl.config.datasource;
+
+import javax.xml.bind.annotation.*;
+import java.util.List;
+
+/**
+ * Class for hold JndiLookupDefinition at parsing with JAXB.
+ */
+@XmlRootElement(name = "JndiLookupDefinition")
+public class JNDILookupDefinition {
+
+ private String jndiName;
+ private List jndiProperties;
+
+ @XmlElement(name = "Name", required = false)
+ public String getJndiName() {
+ return jndiName;
+ }
+
+ public void setJndiName(String jndiName) {
+ this.jndiName = jndiName;
+ }
+
+ @XmlElementWrapper(name = "Environment", nillable = false)
+ @XmlElement(name = "Property", nillable = false)
+ public List getJndiProperties() {
+ return jndiProperties;
+ }
+
+ public void setJndiProperties(List jndiProperties) {
+ this.jndiProperties = jndiProperties;
+ }
+
+ @XmlRootElement(name = "Property")
+ public static class JNDIProperty {
+
+ private String name;
+
+ private String value;
+
+ @XmlAttribute(name = "Name")
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @XmlValue
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+ }
+
+}
+
diff --git a/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/impl/util/OperationTemplateManagementUtil.java b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/impl/util/OperationTemplateManagementUtil.java
new file mode 100644
index 0000000000..079fb65847
--- /dev/null
+++ b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dao/impl/util/OperationTemplateManagementUtil.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2018 - 2023 Entgra (Pvt) Ltd, Inc - All Rights Reserved.
+ *
+ * Unauthorised copying/redistribution of this file, via any medium is strictly prohibited.
+ *
+ * Licensed under the Entgra Commercial License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://entgra.io/licenses/entgra-commercial/1.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.device.mgt.operation.template.dao.impl.util;
+
+import io.entgra.device.mgt.operation.template.dto.OperationTemplateCacheKey;
+import org.w3c.dom.Document;
+import org.wso2.carbon.device.mgt.common.exceptions.DeviceManagementException;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import java.io.File;
+
+public class OperationTemplateManagementUtil {
+
+ private OperationTemplateManagementUtil() {
+ }
+
+ /**
+ *
+ * @param file
+ * @return
+ * @throws DeviceManagementException
+ */
+ public static Document convertToDocument(File file) throws DeviceManagementException {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setNamespaceAware(true);
+ try {
+ factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
+ factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+ DocumentBuilder docBuilder = factory.newDocumentBuilder();
+ return docBuilder.parse(file);
+ } catch (Exception e) {
+ throw new DeviceManagementException("Error occurred while parsing file, while converting " +
+ "to a org.w3c.dom.Document", e);
+ }
+ }
+
+ /**
+ *
+ * @param subTypeId
+ * @param deviceType
+ * @param operationCode
+ * @return
+ */
+ public static String setOperationTemplateCacheKey(int subTypeId, String deviceType, String operationCode) {
+ return subTypeId + "|" + deviceType + "|" + operationCode;
+ }
+
+ /**
+ *
+ * @param key
+ * @return
+ */
+ public static OperationTemplateCacheKey getOperationTemplateCacheKey(String key) {
+ String[] keys = key.split("\\|");
+ int subTypeId = Integer.parseInt(keys[0]);
+ String deviceType = keys[1];
+ String operationCode = keys[2];
+
+ OperationTemplateCacheKey operationTemplateCacheKey = new OperationTemplateCacheKey();
+ operationTemplateCacheKey.setSubTypeId(subTypeId);
+ operationTemplateCacheKey.setDeviceType(deviceType);
+ operationTemplateCacheKey.setOperationCode(operationCode);
+
+ return operationTemplateCacheKey;
+ }
+
+}
diff --git a/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dto/OperationTemplate.java b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dto/OperationTemplate.java
new file mode 100644
index 0000000000..0ecd0a1c47
--- /dev/null
+++ b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dto/OperationTemplate.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2018 - 2023 Entgra (Pvt) Ltd, Inc - All Rights Reserved.
+ *
+ * Unauthorised copying/redistribution of this file, via any medium is strictly prohibited.
+ *
+ * Licensed under the Entgra Commercial License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://entgra.io/licenses/entgra-commercial/1.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.device.mgt.operation.template.dto;
+
+public class OperationTemplate {
+ private int subTypeId;
+
+ private String deviceType;
+ private int operationTemplateId;
+ private String code;
+ private String operationDefinition;
+
+ public int getSubTypeId() {
+ return subTypeId;
+ }
+
+ public void setSubTypeId(int subTypeId) {
+ this.subTypeId = subTypeId;
+ }
+
+ public int getOperationTemplateId() {
+ return operationTemplateId;
+ }
+
+ public void setOperationTemplateId(int operationTemplateId) {
+ this.operationTemplateId = operationTemplateId;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public void setCode(String code) {
+ this.code = code;
+ }
+
+ public String getOperationDefinition() {
+ return operationDefinition;
+ }
+
+ public void setOperationDefinition(String operationDefinition) {
+ this.operationDefinition = operationDefinition;
+ }
+
+ public String getDeviceType() {
+ return deviceType;
+ }
+
+ public void setDeviceType(String deviceType) {
+ this.deviceType = deviceType;
+ }
+}
diff --git a/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dto/OperationTemplateCacheKey.java b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dto/OperationTemplateCacheKey.java
new file mode 100644
index 0000000000..2bbbf1a22d
--- /dev/null
+++ b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/dto/OperationTemplateCacheKey.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2018 - 2023 Entgra (Pvt) Ltd, Inc - All Rights Reserved.
+ *
+ * Unauthorised copying/redistribution of this file, via any medium is strictly prohibited.
+ *
+ * Licensed under the Entgra Commercial License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://entgra.io/licenses/entgra-commercial/1.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.device.mgt.operation.template.dto;
+
+public class OperationTemplateCacheKey {
+
+ int subTypeId;
+ String deviceType;
+ String operationCode;
+
+ public int getSubTypeId() {
+ return subTypeId;
+ }
+
+ public void setSubTypeId(int subTypeId) {
+ this.subTypeId = subTypeId;
+ }
+
+ public String getOperationCode() {
+ return operationCode;
+ }
+
+ public void setOperationCode(String operationCode) {
+ this.operationCode = operationCode;
+ }
+
+ public String getDeviceType() {
+ return deviceType;
+ }
+
+ public void setDeviceType(String deviceType) {
+ this.deviceType = deviceType;
+ }
+}
diff --git a/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/exception/DBConnectionException.java b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/exception/DBConnectionException.java
new file mode 100644
index 0000000000..05928673d8
--- /dev/null
+++ b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/exception/DBConnectionException.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2018 - 2023 Entgra (Pvt) Ltd, Inc - All Rights Reserved.
+ *
+ * Unauthorised copying/redistribution of this file, via any medium is strictly prohibited.
+ *
+ * Licensed under the Entgra Commercial License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://entgra.io/licenses/entgra-commercial/1.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.device.mgt.operation.template.exception;
+
+/**
+ * Exception thrown due to Database Connection issues.
+ */
+public class DBConnectionException extends Exception {
+
+ private static final long serialVersionUID = 8568807205814148601L;
+
+ public DBConnectionException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public DBConnectionException(String msg) {
+ super(msg);
+ }
+}
diff --git a/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/exception/OperationTemplateManagementDAOException.java b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/exception/OperationTemplateManagementDAOException.java
new file mode 100644
index 0000000000..da9aec9dd8
--- /dev/null
+++ b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/exception/OperationTemplateManagementDAOException.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2018 - 2023 Entgra (Pvt) Ltd, Inc - All Rights Reserved.
+ *
+ * Unauthorised copying/redistribution of this file, via any medium is strictly prohibited.
+ *
+ * Licensed under the Entgra Commercial License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://entgra.io/licenses/entgra-commercial/1.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.device.mgt.operation.template.exception;
+
+public class OperationTemplateManagementDAOException extends Exception {
+
+ private static final long serialVersionUID = -2880391246325221123L;
+
+ public OperationTemplateManagementDAOException(String message, Throwable throwable) {
+ super(message, throwable);
+ }
+
+ public OperationTemplateManagementDAOException(String message) {
+ super(message, new Exception());
+ }
+
+}
diff --git a/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/exception/OperationTemplateMgtPluginException.java b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/exception/OperationTemplateMgtPluginException.java
new file mode 100644
index 0000000000..d2f9deafde
--- /dev/null
+++ b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/exception/OperationTemplateMgtPluginException.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2018 - 2023 Entgra (Pvt) Ltd, Inc - All Rights Reserved.
+ *
+ * Unauthorised copying/redistribution of this file, via any medium is strictly prohibited.
+ *
+ * Licensed under the Entgra Commercial License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://entgra.io/licenses/entgra-commercial/1.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.device.mgt.operation.template.exception;
+
+public class OperationTemplateMgtPluginException extends Exception {
+
+ private static final long serialVersionUID = 1426658754211497795L;
+
+ private String errorMessage;
+
+ public OperationTemplateMgtPluginException() {
+ super();
+ }
+
+ public OperationTemplateMgtPluginException(Throwable cause) {
+ super(cause);
+ }
+
+ public OperationTemplateMgtPluginException(String msg, Exception nestedEx) {
+ super(msg, nestedEx);
+ setErrorMessage(msg);
+ }
+
+ public OperationTemplateMgtPluginException(String message, Throwable cause) {
+ super(message, cause);
+ setErrorMessage(message);
+ }
+
+ public OperationTemplateMgtPluginException(String msg) {
+ super(msg);
+ setErrorMessage(msg);
+ }
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ public void setErrorMessage(String errorMessage) {
+ this.errorMessage = errorMessage;
+ }
+}
diff --git a/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/impl/OperationTemplateServiceImpl.java b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/impl/OperationTemplateServiceImpl.java
new file mode 100644
index 0000000000..3094b04a53
--- /dev/null
+++ b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/impl/OperationTemplateServiceImpl.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2018 - 2023 Entgra (Pvt) Ltd, Inc - All Rights Reserved.
+ *
+ * Unauthorised copying/redistribution of this file, via any medium is strictly prohibited.
+ *
+ * Licensed under the Entgra Commercial License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://entgra.io/licenses/entgra-commercial/1.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.device.mgt.operation.template.impl;
+
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.LoadingCache;
+import io.entgra.device.mgt.operation.template.cache.OperationTemplateCacheLoader;
+import io.entgra.device.mgt.operation.template.dao.OperationTemplateDAO;
+import io.entgra.device.mgt.operation.template.dao.OperationTemplateDAOFactory;
+import io.entgra.device.mgt.operation.template.dao.impl.util.OperationTemplateManagementUtil;
+import io.entgra.device.mgt.operation.template.dto.OperationTemplate;
+import io.entgra.device.mgt.operation.template.exception.DBConnectionException;
+import io.entgra.device.mgt.operation.template.exception.OperationTemplateManagementDAOException;
+import io.entgra.device.mgt.operation.template.exception.OperationTemplateMgtPluginException;
+import io.entgra.device.mgt.operation.template.spi.OperationTemplateService;
+import io.entgra.device.mgt.operation.template.util.ConnectionManagerUtils;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Operation Template service impl class.
+ */
+public class OperationTemplateServiceImpl implements OperationTemplateService {
+
+ private static final Log log = LogFactory.getLog(OperationTemplateServiceImpl.class);
+ private static final LoadingCache operationTemplateCache = CacheBuilder.newBuilder()
+ .expireAfterWrite(15, TimeUnit.MINUTES).build(new OperationTemplateCacheLoader());
+ private final OperationTemplateDAO operationTemplateDAO;
+
+ public OperationTemplateServiceImpl() {
+ this.operationTemplateDAO = OperationTemplateDAOFactory.getOperationTemplateDAO();
+ }
+
+ /**
+ * @param operationTemplate
+ * @throws OperationTemplateMgtPluginException
+ */
+ @Override
+ public void addOperationTemplate(OperationTemplate operationTemplate)
+ throws OperationTemplateMgtPluginException {
+
+ try {
+ ConnectionManagerUtils.beginDBTransaction();
+ operationTemplateDAO.addOperationTemplate(operationTemplate);
+ ConnectionManagerUtils.commitDBTransaction();
+
+ String key = OperationTemplateManagementUtil.setOperationTemplateCacheKey(
+ operationTemplate.getSubTypeId(), operationTemplate.getDeviceType(), operationTemplate.getCode());
+ operationTemplateCache.put(key, operationTemplate);
+
+ if (log.isDebugEnabled()) {
+ String msg = "Operation Template added successfully,for subtype id "
+ + operationTemplate.getSubTypeId() + " and operation code "
+ + operationTemplate.getCode() + "";
+ log.debug(msg);
+ }
+ } catch (DBConnectionException | OperationTemplateManagementDAOException e) {
+ log.error(e.getMessage(), e);
+ throw new OperationTemplateMgtPluginException(e.getMessage(), e);
+ } finally {
+ ConnectionManagerUtils.closeDBConnection();
+ }
+ }
+
+ /**
+ * @param operationTemplate
+ * @return
+ * @throws OperationTemplateMgtPluginException
+ */
+ @Override
+ public OperationTemplate updateOperationTemplate(OperationTemplate operationTemplate)
+ throws OperationTemplateMgtPluginException {
+
+ OperationTemplate updatedOperationTemplate = null;
+ try {
+ ConnectionManagerUtils.beginDBTransaction();
+ updatedOperationTemplate = operationTemplateDAO.updateOperationTemplate(
+ operationTemplate);
+ ConnectionManagerUtils.commitDBTransaction();
+ if (log.isDebugEnabled()) {
+ String msg = "Operation Template updated successfully,for subtype id "
+ + operationTemplate.getSubTypeId() + " and operation code " + operationTemplate.getCode()
+ + "";
+ log.debug(msg);
+ }
+ return updatedOperationTemplate;
+ } catch (DBConnectionException | OperationTemplateManagementDAOException e) {
+ log.error(e.getMessage(), e);
+ throw new OperationTemplateMgtPluginException(e.getMessage(), e);
+ } finally {
+ ConnectionManagerUtils.closeDBConnection();
+
+ if (updatedOperationTemplate != null) {
+ String key = OperationTemplateManagementUtil.setOperationTemplateCacheKey(
+ operationTemplate.getSubTypeId(), operationTemplate.getDeviceType(), operationTemplate.getCode());
+ operationTemplateCache.refresh(key);
+ }
+ }
+ }
+
+ /**
+ * @param subTypeId
+ * @param deviceType
+ * @param operationCode
+ * @return
+ * @throws OperationTemplateMgtPluginException
+ */
+ @Override
+ public OperationTemplate getOperationTemplate(int subTypeId, String deviceType, String operationCode)
+ throws OperationTemplateMgtPluginException {
+ try {
+ String key = OperationTemplateManagementUtil.setOperationTemplateCacheKey(subTypeId, deviceType,
+ operationCode);
+ return operationTemplateCache.get(key);
+ } catch (ExecutionException e) {
+ log.error(e.getMessage());
+ throw new OperationTemplateMgtPluginException(e.getMessage(), e);
+ }
+ }
+
+ /**
+ * @param subTypeId
+ * @param deviceType
+ * @param operationCode
+ * @throws OperationTemplateMgtPluginException
+ */
+ @Override
+ public void deleteOperationTemplate(int subTypeId, String deviceType, String operationCode)
+ throws OperationTemplateMgtPluginException {
+
+ try {
+ ConnectionManagerUtils.beginDBTransaction();
+ operationTemplateDAO.deleteOperationTemplate(subTypeId, deviceType, operationCode);
+ ConnectionManagerUtils.commitDBTransaction();
+ if (log.isDebugEnabled()) {
+ String msg = "Operation Template deleted successfully,for subtype id "
+ + subTypeId + " and operation code "
+ + operationCode + "";
+ log.debug(msg);
+ }
+ String key = OperationTemplateManagementUtil.setOperationTemplateCacheKey(
+ subTypeId, deviceType, operationCode);
+ operationTemplateCache.invalidate(key);
+ } catch (DBConnectionException | OperationTemplateManagementDAOException e) {
+ log.error(e.getMessage());
+ throw new OperationTemplateMgtPluginException(e.getMessage(), e);
+ } finally {
+ ConnectionManagerUtils.closeDBConnection();
+
+ }
+ }
+
+ /**
+ * @param subTypeId
+ * @param operationCode
+ * @param deviceType
+ * @return
+ * @throws OperationTemplateMgtPluginException
+ */
+ @Override
+ public boolean isExistsOperationTemplateBySubtypeIdAndOperationCode(int subTypeId,
+ String operationCode, String deviceType) throws OperationTemplateMgtPluginException {
+ try {
+ ConnectionManagerUtils.openDBConnection();
+ return operationTemplateDAO.isExistsOperationTemplateBySubtypeIdAndOperationCode(subTypeId, deviceType,
+ operationCode);
+
+ } catch (DBConnectionException | OperationTemplateManagementDAOException e) {
+ log.error(e.getMessage());
+ throw new OperationTemplateMgtPluginException(e.getMessage(), e);
+ } finally {
+ ConnectionManagerUtils.closeDBConnection();
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/internal/OperationTemplateMgtDataHolder.java b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/internal/OperationTemplateMgtDataHolder.java
new file mode 100644
index 0000000000..2236d5cd90
--- /dev/null
+++ b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/internal/OperationTemplateMgtDataHolder.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2018 - 2023 Entgra (Pvt) Ltd, Inc - All Rights Reserved.
+ *
+ * Unauthorised copying/redistribution of this file, via any medium is strictly prohibited.
+ *
+ * Licensed under the Entgra Commercial License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://entgra.io/licenses/entgra-commercial/1.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.device.mgt.operation.template.internal;
+
+import io.entgra.device.mgt.operation.template.spi.OperationTemplateService;
+import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
+import org.wso2.carbon.registry.core.service.RegistryService;
+
+/**
+ * Operation Template data holder class
+ */
+public class OperationTemplateMgtDataHolder {
+
+ public static final OperationTemplateMgtDataHolder thisInstance = new OperationTemplateMgtDataHolder();
+
+ private OperationTemplateService operationTemplateService;
+ private DeviceManagementProviderService deviceManagementProviderService;
+ private RegistryService registryService;
+ private OperationTemplateMgtDataHolder() {
+ }
+ public static OperationTemplateMgtDataHolder getInstance() {
+ return thisInstance;
+ }
+
+ public OperationTemplateService getOperationTemplateService() {
+ return operationTemplateService;
+ }
+
+ public void setOperationTemplateService(OperationTemplateService operationTemplateService) {
+ this.operationTemplateService = operationTemplateService;
+ }
+
+ public DeviceManagementProviderService getDeviceManagementProviderService() {
+ return deviceManagementProviderService;
+ }
+
+ public void setDeviceManagementProviderService(DeviceManagementProviderService deviceManagementProviderService) {
+ this.deviceManagementProviderService = deviceManagementProviderService;
+ }
+
+ public RegistryService getRegistryService() {
+ return registryService;
+ }
+
+ public void setRegistryService(RegistryService registryService) {
+ this.registryService = registryService;
+ }
+}
diff --git a/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/internal/OperationTemplateMgtServiceComponent.java b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/internal/OperationTemplateMgtServiceComponent.java
new file mode 100644
index 0000000000..5233b37387
--- /dev/null
+++ b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/internal/OperationTemplateMgtServiceComponent.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2018 - 2023 Entgra (Pvt) Ltd, Inc - All Rights Reserved.
+ *
+ * Unauthorised copying/redistribution of this file, via any medium is strictly prohibited.
+ *
+ * Licensed under the Entgra Commercial License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://entgra.io/licenses/entgra-commercial/1.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.device.mgt.operation.template.internal;
+
+import io.entgra.device.mgt.operation.template.dao.OperationTemplateDAOFactory;
+import io.entgra.device.mgt.operation.template.dao.impl.config.DeviceConfigurationManager;
+import io.entgra.device.mgt.operation.template.dao.impl.config.DeviceManagementConfig;
+import io.entgra.device.mgt.operation.template.dao.impl.config.datasource.DataSourceConfig;
+import io.entgra.device.mgt.operation.template.impl.OperationTemplateServiceImpl;
+import io.entgra.device.mgt.operation.template.spi.OperationTemplateService;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.component.ComponentContext;
+import org.wso2.carbon.ndatasource.core.DataSourceService;
+
+/**
+ * @scr.component name="io.entgra.device.mgt.operation.template.internal.OperationTemplateMgtServiceComponent" immediate="true"
+ * immediate="true"
+ * @scr.reference name="org.wso2.carbon.ndatasource"
+ * interface="org.wso2.carbon.ndatasource.core.DataSourceService"
+ * cardinality="1..1"
+ * policy="dynamic"
+ * bind="setDataSourceService"
+ * unbind="unsetDataSourceService"
+ */
+public class OperationTemplateMgtServiceComponent {
+
+ private static final Log log = LogFactory.getLog(OperationTemplateMgtServiceComponent.class);
+
+ /**
+ *
+ * @param componentContext
+ */
+ protected void activate(ComponentContext componentContext) {
+
+ if (log.isDebugEnabled()) {
+ log.debug("Activating Operation Template Management Service Component");
+ }
+ try {
+ BundleContext bundleContext = componentContext.getBundleContext();
+
+ DeviceConfigurationManager.getInstance().initConfig();
+ DeviceManagementConfig config = DeviceConfigurationManager.getInstance().getDeviceManagementConfig();
+ DataSourceConfig dsConfig = config.getDeviceManagementRepository().getDataSourceConfig();
+ OperationTemplateDAOFactory.init(dsConfig);
+
+ OperationTemplateService operationTemplateService = new OperationTemplateServiceImpl();
+ OperationTemplateMgtDataHolder.getInstance().setOperationTemplateService(operationTemplateService);
+ bundleContext.registerService(OperationTemplateService.class, operationTemplateService, null);
+
+ if (log.isDebugEnabled()) {
+ log.debug("Operation Template Management Service Component has been successfully activated");
+ }
+ } catch (Throwable e) {
+ log.error("Error occurred while activating Operation Template Management Service Component", e);
+ }
+ }
+
+ /**
+ *
+ * @param componentContext
+ */
+ protected void deactivate(ComponentContext componentContext) {
+ if (log.isDebugEnabled()) {
+ log.debug("De-activating Operation Template Management Service Component");
+ }
+ try {
+ if (log.isDebugEnabled()) {
+ log.debug("Operation Template Management Service Component has been successfully de-activated");
+ }
+ } catch (Throwable e) {
+ log.error("Error occurred while de-activating Operation Template Management bundle", e);
+ }
+ }
+
+ /**
+ *
+ * @param dataSourceService
+ */
+ protected void setDataSourceService(DataSourceService dataSourceService) {
+ /* This is to avoid mobile device management component getting initialized before the underlying datasources
+ are registered */
+ if (log.isDebugEnabled()) {
+ log.debug("Data source service set to Operation Template Mgt component");
+ }
+ }
+
+ /**
+ *
+ * @param dataSourceService
+ */
+ protected void unsetDataSourceService(DataSourceService dataSourceService) {
+ //do nothing
+ if (log.isDebugEnabled()) {
+ log.debug("Removing Data Source service from Operation Template Mgt component");
+ }
+ }
+
+}
diff --git a/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/spi/OperationTemplateService.java b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/spi/OperationTemplateService.java
new file mode 100644
index 0000000000..b8c2eaefbd
--- /dev/null
+++ b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/spi/OperationTemplateService.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2018 - 2023 Entgra (Pvt) Ltd, Inc - All Rights Reserved.
+ *
+ * Unauthorised copying/redistribution of this file, via any medium is strictly prohibited.
+ *
+ * Licensed under the Entgra Commercial License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://entgra.io/licenses/entgra-commercial/1.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.device.mgt.operation.template.spi;
+
+import io.entgra.device.mgt.operation.template.dto.OperationTemplate;
+import io.entgra.device.mgt.operation.template.exception.OperationTemplateMgtPluginException;
+
+/**
+ * Operation Template service interface.
+ */
+public interface OperationTemplateService {
+
+ void addOperationTemplate(OperationTemplate operationTemplate) throws OperationTemplateMgtPluginException;
+ OperationTemplate updateOperationTemplate(OperationTemplate operationTemplate) throws OperationTemplateMgtPluginException;
+ OperationTemplate getOperationTemplate(int subTypeId, String deviceType, String operationCode) throws OperationTemplateMgtPluginException;
+ void deleteOperationTemplate(int subTypeId, String deviceType, String operationCode) throws OperationTemplateMgtPluginException;
+ boolean isExistsOperationTemplateBySubtypeIdAndOperationCode(int subTypeId, String deviceType, String operationCode) throws OperationTemplateMgtPluginException;
+
+}
diff --git a/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/util/ConnectionManagerUtils.java b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/util/ConnectionManagerUtils.java
new file mode 100644
index 0000000000..f20f34d50b
--- /dev/null
+++ b/components/operation-template-mgt/io.entgra.device.mgt.operation.template/src/main/java/io/entgra/device/mgt/operation/template/util/ConnectionManagerUtils.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2018 - 2023 Entgra (Pvt) Ltd, Inc - All Rights Reserved.
+ *
+ * Unauthorised copying/redistribution of this file, via any medium is strictly prohibited.
+ *
+ * Licensed under the Entgra Commercial License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://entgra.io/licenses/entgra-commercial/1.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.device.mgt.operation.template.util;
+
+import io.entgra.device.mgt.operation.template.dao.impl.config.datasource.DataSourceConfig;
+import io.entgra.device.mgt.operation.template.dao.impl.config.datasource.JNDILookupDefinition;
+import io.entgra.device.mgt.operation.template.exception.DBConnectionException;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Hashtable;
+import java.util.List;
+import javax.naming.InitialContext;
+import javax.sql.DataSource;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.wso2.carbon.device.mgt.common.exceptions.IllegalTransactionStateException;
+
+/**
+ * Connection Manager Utils class.
+ */
+public class ConnectionManagerUtils {
+
+ private static final Log log = LogFactory.getLog(ConnectionManagerUtils.class);
+ private static final ThreadLocal currentConnection = new ThreadLocal<>();
+ private static DataSource dataSource;
+
+ private ConnectionManagerUtils() {
+ }
+
+ /**
+ *
+ * @throws DBConnectionException
+ */
+ public static void openDBConnection() throws DBConnectionException {
+ Connection conn = currentConnection.get();
+ if (conn != null) {
+ throw new IllegalTransactionStateException("Database connection has already been obtained.");
+ }
+ try {
+ conn = dataSource.getConnection();
+ } catch (SQLException e) {
+ throw new DBConnectionException("Failed to get a database connection.", e);
+ }
+ currentConnection.set(conn);
+ }
+
+ /**
+ *
+ * @return
+ * @throws DBConnectionException
+ */
+ public static Connection getDBConnection() throws DBConnectionException {
+ Connection conn = currentConnection.get();
+ if (conn != null) {
+ return conn;
+ }
+ try {
+ conn = dataSource.getConnection();
+ currentConnection.set(conn);
+
+ } catch (SQLException e) {
+ throw new DBConnectionException("Failed to get database connection.", e);
+ }
+ return conn;
+
+ }
+
+ /**
+ *
+ * @throws DBConnectionException
+ */
+ public static void beginDBTransaction() throws DBConnectionException {
+ Connection conn = currentConnection.get();
+ if (conn == null) {
+ conn = getDBConnection();
+ } else if (inTransaction(conn)) {
+ throw new IllegalTransactionStateException("Transaction has already been started.");
+ }
+
+ try {
+ conn.setAutoCommit(false);
+ } catch (SQLException e) {
+ throw new DBConnectionException("Error occurred while starting a database transaction.", e);
+ }
+ }
+
+ /**
+ *
+ * @throws DBConnectionException
+ */
+ public static void enableAutoCommitDBTransaction() throws DBConnectionException {
+ Connection conn = currentConnection.get();
+ if (conn == null) {
+ throw new IllegalTransactionStateException("Database connection is not active.");
+ }
+
+ if (!inTransaction(conn)) {
+ throw new IllegalTransactionStateException("Transaction has not been started.");
+ }
+
+ try {
+ conn.setAutoCommit(Boolean.TRUE);
+ } catch (SQLException e) {
+ throw new DBConnectionException("Error occurred while ending database transaction.", e);
+ }
+ }
+
+
+ public static void commitDBTransaction() {
+ Connection conn = currentConnection.get();
+ if (conn == null) {
+ throw new IllegalTransactionStateException("Database connection is not active.");
+ }
+
+ if (!inTransaction(conn)) {
+ throw new IllegalTransactionStateException("Transaction has not been started.");
+ }
+
+ try {
+ conn.commit();
+ } catch (SQLException e) {
+ log.error("Error occurred while committing the transaction", e);
+ }
+ }
+
+
+ public static void rollbackDBTransaction() {
+ Connection conn = currentConnection.get();
+ if (conn == null) {
+ throw new IllegalTransactionStateException("Database connection is not active.");
+ }
+
+ if (!inTransaction(conn)) {
+ throw new IllegalTransactionStateException("Transaction has not been started.");
+ }
+
+ try {
+ conn.rollback();
+ } catch (SQLException e) {
+ log.warn("Error occurred while roll-backing the transaction", e);
+ }
+ }
+
+ public static void closeDBConnection() {
+ Connection conn = currentConnection.get();
+ if (conn == null) {
+ throw new IllegalTransactionStateException("Database connection is not active.");
+ }
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ log.error("Error occurred while closing the connection", e);
+ }
+ currentConnection.remove();
+ }
+
+ /**
+ *
+ * @param conn
+ * @return
+ */
+ private static boolean inTransaction(Connection conn) {
+ try {
+ if (conn.getAutoCommit()) {
+ return false;
+ }
+ } catch (SQLException e) {
+ throw new IllegalTransactionStateException("Failed to get transaction state.");
+ }
+ return true;
+ }
+
+ /**
+ *
+ * @return
+ * @throws DBConnectionException
+ */
+ public static boolean isTransactionStarted() throws DBConnectionException {
+ Connection connection = getDBConnection();
+ return inTransaction(connection);
+ }
+
+ /**
+ * Resolve data source from the data source definition.
+ *
+ * @param config Data source configuration
+ * @return data source resolved from the data source definition
+ */
+ public static DataSource resolveDataSource(DataSourceConfig config) {
+ if (config == null) {
+ throw new RuntimeException("Device Management Repository data source configuration "
+ + "is null and thus, is not initialized");
+ }
+ JNDILookupDefinition jndiConfig = config.getJndiLookupDefinition();
+ if (jndiConfig == null) {
+ return dataSource;
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("Initializing Device Management Repository data source using the JNDI "
+ + "Lookup Definition");
+ }
+ List jndiPropertyList = jndiConfig.getJndiProperties();
+ if (jndiPropertyList != null) {
+ Hashtable